From c1472dca69d08f1fe25bbe5a4c07066a70c80b3b Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 28 Oct 2024 10:17:00 +0100 Subject: [PATCH 01/93] feat: begin update voting process --- .ruby-version | 2 +- Gemfile | 12 +- Gemfile.lock | 969 ++- .../budget_list_item_cell_extensions.rb | 6 +- ...ns.rb => projectx_list_item_extensions.rb} | 0 .../decidim/budgets/budget_list_item/show.erb | 88 - .../budgets/budget_list_item/showx.erb | 134 + .../budgets_header/{show.erb => showx.erb} | 8 +- .../{card_list.erb => card_listx.erb} | 28 +- .../budgets_list/{show.erb => showx.erb} | 7 +- .../app/cells/decidim/budgets/project_cell.rb | 28 + .../cells/decidim/budgets/project_g/show.erb | 30 + .../cells/decidim/budgets/project_g_cell.rb | 65 + .../budgets/project_vote_button/show.erb | 4 +- ...s.rb => budgetsx_controller_extensions.rb} | 3 +- .../projects_controller_extensions.rb | 17 + .../projects_helper_extensions.rb | 18 + .../decidim_budgets_booth_voting.js | 6 +- .../{progressFixed.js => progressXFixed.js} | 0 .../budgets/{projects.js => projectsX.js} | 0 .../{exit_handler.js => exitX_handler.js} | 0 .../{progressFixed.js => progressFixedX.js} | 0 .../{projects.js => projectsX.js} | 0 .../decidim/budgets_booth/budgets_booth.scss | 147 +- .../{_form.html.erb => _formX.html.erb} | 0 .../{index.html.erb => indexX.html.erb} | 2 + .../budgets/line_items/update_budget.js.erb | 45 +- ...irm.html.erb => _budgetx_confirm.html.erb} | 0 ...cess.html.erb => _budgetx_excess.html.erb} | 2 +- ...ary.html.erb => _budgetx_summary.html.erb} | 0 .../budgets/projects/_project.html.erb | 4 +- .../budgets/projects/_projects.html.erb | 15 +- .../decidim/budgets/projects/index.html.erb | 71 +- .../decidim/budgets/projects/show.html.erb | 152 +- .../decidim/shared/_custom_filters.html.erb | 55 + .../budgets/_voting_application.html.erb | 23 +- .../decidim/budgets/_voting_menubar.html.erb | 22 + .../decidim/budgets/_voting_wrapper.html.erb | 14 +- .../decidim/shared/_layout_item.html.erb | 21 + decidim-budgets_booth/config/locales/en.yml | 10 + decidim-budgets_booth/config/locales/fr.yml | 10 + .../lib/decidim/budgets_booth/engine.rb | 12 +- .../lib/decidim/budgets_booth/version.rb | 4 +- .../packs/stylesheets/decidim/l10n/l10n.scss | 2 +- decidim-l10n/lib/decidim/l10n/engine.rb | 12 +- decidim-l10n/lib/decidim/l10n/version.rb | 4 +- .../decidim/debates/debate_m_cell_spec.rb | 3 +- .../decidim/meetings/meeting_m_cell_spec.rb | 3 +- .../lib/decidim/sms/twilio/version.rb | 4 +- .../stylesheets/decidim/smsauth/smsauth.scss | 10 +- .../lib/decidim/smsauth/version.rb | 4 +- lib/decidim/ptp/version.rb | 4 +- package-lock.json | 259 +- yarn.lock | 6058 +++++++++++++++++ 54 files changed, 7436 insertions(+), 961 deletions(-) rename decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/{project_list_item_extensions.rb => projectx_list_item_extensions.rb} (100%) delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb create mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb rename decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/{show.erb => showx.erb} (89%) rename decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/{card_list.erb => card_listx.erb} (54%) rename decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/{show.erb => showx.erb} (91%) create mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb create mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb create mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb rename decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/{budgets_controller_extensions.rb => budgetsx_controller_extensions.rb} (92%) rename decidim-budgets_booth/app/packs/src/decidim/budgets/{progressFixed.js => progressXFixed.js} (100%) rename decidim-budgets_booth/app/packs/src/decidim/budgets/{projects.js => projectsX.js} (100%) rename decidim-budgets_booth/app/packs/src/decidim/budgets_booth/{exit_handler.js => exitX_handler.js} (100%) rename decidim-budgets_booth/app/packs/src/decidim/budgets_booth/{progressFixed.js => progressFixedX.js} (100%) rename decidim-budgets_booth/app/packs/src/decidim/budgets_booth/{projects.js => projectsX.js} (100%) rename decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/{_form.html.erb => _formX.html.erb} (100%) rename decidim-budgets_booth/app/views/decidim/budgets/budgets/{index.html.erb => indexX.html.erb} (99%) rename decidim-budgets_booth/app/views/decidim/budgets/projects/{_budget_confirm.html.erb => _budgetx_confirm.html.erb} (100%) rename decidim-budgets_booth/app/views/decidim/budgets/projects/{_budget_excess.html.erb => _budgetx_excess.html.erb} (86%) rename decidim-budgets_booth/app/views/decidim/budgets/projects/{_budget_summary.html.erb => _budgetx_summary.html.erb} (100%) create mode 100644 decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb create mode 100644 decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb create mode 100644 decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb create mode 100644 yarn.lock diff --git a/.ruby-version b/.ruby-version index b0f2dcb3..be94e6f5 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.0.4 +3.2.2 diff --git a/Gemfile b/Gemfile index a8812407..bf9de6a3 100644 --- a/Gemfile +++ b/Gemfile @@ -17,9 +17,9 @@ gem "decidim-ptp", path: "." gem "bootsnap", "~> 1.4" -gem "puma", ">= 5.6.2" +gem "puma", ">= 6.3.1" -gem "faker", "~> 2.14" +gem "faker", "~> 3.2" group :development, :test do gem "byebug", "~> 11.0", platform: :mri @@ -27,19 +27,19 @@ group :development, :test do gem "decidim-dev", DECIDIM_VERSION gem "decidim-initiatives", DECIDIM_VERSION - gem "brakeman", "~> 5.2" + gem "brakeman", "~> 6.1" # Ruby 3.0 -> (Decidim 0.27.x ->) # gem "net-imap", "~> 0.2.3" # gem "net-pop", "~> 0.1.1" # gem "net-smtp", "~> 0.3.1" - gem "parallel_tests", "~> 3.7" + gem "parallel_tests", "~> 4.2" gem "rubocop-faker" end group :development do gem "letter_opener_web", "~> 2.0" gem "listen", "~> 3.1" - gem "spring", "~> 2.0" - gem "spring-watcher-listen", "~> 2.0" + gem "spring" + #gem "spring-watcher-listen", "~> 2.0" gem "web-console", "~> 4.2" end diff --git a/Gemfile.lock b/Gemfile.lock index 1edd5e73..7c4ad973 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,61 +1,68 @@ PATH remote: . specs: - decidim-budgets_booth (0.27.0) - decidim-budgets (~> 0.27.0) - decidim-core (~> 0.27.0) - decidim-l10n (0.27.0) - decidim-core (~> 0.27.0) - decidim-ptp (0.27.0) - decidim-budgets_booth (= 0.27.0) - decidim-core (~> 0.27.0) - decidim-l10n (= 0.27.0) - decidim-sms-twilio (= 0.27.0) - decidim-smsauth (= 0.27.0) - decidim-sms-twilio (0.27.0) - decidim-core (~> 0.27.0) + decidim-budgets_booth (0.29.0) + decidim-budgets (~> 0.29.0) + decidim-core (~> 0.29.0) + decidim-l10n (0.29.0) + decidim-core (~> 0.29.0) + decidim-ptp (0.29.0) + decidim-budgets_booth (= 0.29.0) + decidim-core (~> 0.29.0) + decidim-l10n (= 0.29.0) + decidim-sms-twilio (= 0.29.0) + decidim-smsauth (= 0.29.0) + decidim-sms-twilio (0.29.0) + decidim-core (~> 0.29.0) twilio-ruby (~> 5.72.0) - decidim-smsauth (0.27.0) + decidim-smsauth (0.29.0) countries (~> 5.1, >= 5.1.2) - decidim-core (~> 0.27.0) + decidim-core (~> 0.29.0) GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7) - actionpack (= 6.1.7) - activesupport (= 6.1.7) + actioncable (7.0.8.5) + actionpack (= 7.0.8.5) + activesupport (= 7.0.8.5) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7) - actionpack (= 6.1.7) - activejob (= 6.1.7) - activerecord (= 6.1.7) - activestorage (= 6.1.7) - activesupport (= 6.1.7) + actionmailbox (7.0.8.5) + actionpack (= 7.0.8.5) + activejob (= 7.0.8.5) + activerecord (= 7.0.8.5) + activestorage (= 7.0.8.5) + activesupport (= 7.0.8.5) mail (>= 2.7.1) - actionmailer (6.1.7) - actionpack (= 6.1.7) - actionview (= 6.1.7) - activejob (= 6.1.7) - activesupport (= 6.1.7) + net-imap + net-pop + net-smtp + actionmailer (7.0.8.5) + actionpack (= 7.0.8.5) + actionview (= 7.0.8.5) + activejob (= 7.0.8.5) + activesupport (= 7.0.8.5) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.7) - actionview (= 6.1.7) - activesupport (= 6.1.7) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.8.5) + actionview (= 7.0.8.5) + activesupport (= 7.0.8.5) + rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7) - actionpack (= 6.1.7) - activerecord (= 6.1.7) - activestorage (= 6.1.7) - activesupport (= 6.1.7) + actiontext (7.0.8.5) + actionpack (= 7.0.8.5) + activerecord (= 7.0.8.5) + activestorage (= 7.0.8.5) + activesupport (= 7.0.8.5) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.7) - activesupport (= 6.1.7) + actionview (7.0.8.5) + activesupport (= 7.0.8.5) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -63,77 +70,63 @@ GEM active_link_to (1.0.5) actionpack addressable - activejob (6.1.7) - activesupport (= 6.1.7) + activejob (7.0.8.5) + activesupport (= 7.0.8.5) globalid (>= 0.3.6) - activemodel (6.1.7) - activesupport (= 6.1.7) - activerecord (6.1.7) - activemodel (= 6.1.7) - activesupport (= 6.1.7) - activestorage (6.1.7) - actionpack (= 6.1.7) - activejob (= 6.1.7) - activerecord (= 6.1.7) - activesupport (= 6.1.7) + activemodel (7.0.8.5) + activesupport (= 7.0.8.5) + activerecord (7.0.8.5) + activemodel (= 7.0.8.5) + activesupport (= 7.0.8.5) + activestorage (7.0.8.5) + actionpack (= 7.0.8.5) + activejob (= 7.0.8.5) + activerecord (= 7.0.8.5) + activesupport (= 7.0.8.5) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7) + activesupport (7.0.8.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) - acts_as_list (0.9.19) - activerecord (>= 3.0) - addressable (2.8.1) - public_suffix (>= 2.0.2, < 6.0) + acts_as_list (1.2.3) + activerecord (>= 6.1) + activesupport (>= 6.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) - axe-core-api (4.5.1) - dumb_delegator - virtus - axe-core-rspec (4.1.0) - axe-core-api - dumb_delegator - virtus - axiom-types (0.1.1) - descendants_tracker (~> 0.0.4) - ice_nine (~> 0.11.0) - thread_safe (~> 0.3, >= 0.3.1) + base64 (0.2.0) batch-loader (1.5.0) - bcrypt (3.1.18) - better_html (1.0.16) - actionview (>= 4.0) - activesupport (>= 4.0) + bcrypt (3.1.20) + better_html (2.1.1) + actionview (>= 6.0) + activesupport (>= 6.0) ast (~> 2.0) erubi (~> 1.4) - html_tokenizer (~> 0.0.6) parser (>= 2.4) smart_properties + bigdecimal (3.1.8) bindex (0.8.1) - bootsnap (1.15.0) + bootsnap (1.18.4) msgpack (~> 1.2) - brakeman (5.4.0) + brakeman (6.2.1) + racc browser (2.7.1) - builder (3.2.4) + builder (3.3.0) + bullet (7.1.6) + activesupport (>= 3.0.0) + uniform_notifier (~> 1.11) byebug (11.1.3) - capybara (3.38.0) + capybara (3.40.0) addressable matrix mini_mime (>= 0.1.3) - nokogiri (~> 1.8) + nokogiri (~> 1.11) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - carrierwave (2.2.3) - activemodel (>= 5.0.0) - activesupport (>= 5.0.0) - addressable (~> 2.6) - image_processing (~> 1.1) - marcel (~> 1.0.0) - mini_mime (>= 0.1.3) - ssrf_filter (~> 1.0) cells (4.1.7) declarative-builder (< 0.2.0) declarative-option (< 0.2.0) @@ -145,271 +138,259 @@ GEM cells-rails (0.1.5) actionpack (>= 5.0) cells (>= 4.1.6, < 5.0.0) - charlock_holmes (0.7.7) - chef-utils (18.0.185) - concurrent-ruby - childprocess (4.1.0) - coercible (1.0.0) - descendants_tracker (~> 0.0.1) - coffee-rails (5.0.0) - coffee-script (>= 2.2.0) - railties (>= 5.2.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.12.2) - colorize (0.8.1) - commonmarker (0.23.6) - concurrent-ruby (1.1.10) - countries (5.2.0) + charlock_holmes (0.7.9) + childprocess (5.1.0) + logger (~> 1.5) + cmdparse (3.0.7) + commonmarker (0.23.10) + concurrent-ruby (1.3.4) + countries (5.7.2) unaccent (~> 0.3) - crack (0.4.5) + crack (1.0.0) + bigdecimal rexml crass (1.0.6) - css_parser (1.12.0) + css_parser (1.19.1) addressable - date (3.3.3) + csv (3.3.0) + dartsass (1.49.8) + date (3.3.4) date_validator (0.12.0) activemodel (>= 3) activesupport (>= 3) - db-query-matchers (0.10.0) - activesupport (>= 4.0, < 7) - rspec (~> 3.0) - decidim (0.27.1) - decidim-accountability (= 0.27.1) - decidim-admin (= 0.27.1) - decidim-api (= 0.27.1) - decidim-assemblies (= 0.27.1) - decidim-blogs (= 0.27.1) - decidim-budgets (= 0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-debates (= 0.27.1) - decidim-forms (= 0.27.1) - decidim-generators (= 0.27.1) - decidim-meetings (= 0.27.1) - decidim-pages (= 0.27.1) - decidim-participatory_processes (= 0.27.1) - decidim-proposals (= 0.27.1) - decidim-sortitions (= 0.27.1) - decidim-surveys (= 0.27.1) - decidim-system (= 0.27.1) - decidim-templates (= 0.27.1) - decidim-verifications (= 0.27.1) - decidim-accountability (0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-admin (0.27.1) + decidim (0.29.1) + decidim-accountability (= 0.29.1) + decidim-admin (= 0.29.1) + decidim-api (= 0.29.1) + decidim-assemblies (= 0.29.1) + decidim-blogs (= 0.29.1) + decidim-budgets (= 0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-debates (= 0.29.1) + decidim-forms (= 0.29.1) + decidim-generators (= 0.29.1) + decidim-meetings (= 0.29.1) + decidim-pages (= 0.29.1) + decidim-participatory_processes (= 0.29.1) + decidim-proposals (= 0.29.1) + decidim-sortitions (= 0.29.1) + decidim-surveys (= 0.29.1) + decidim-system (= 0.29.1) + decidim-verifications (= 0.29.1) + decidim-accountability (0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-admin (0.29.1) active_link_to (~> 1.0) - decidim-core (= 0.27.1) + decidim-core (= 0.29.1) devise (~> 4.7) devise-i18n (~> 1.2) - devise_invitable (~> 2.0) - decidim-api (0.27.1) - graphql (~> 1.12, < 1.13) - graphql-docs (~> 2.1.0) + devise_invitable (~> 2.0, >= 2.0.9) + decidim-api (0.29.1) + decidim-core (= 0.29.1) + graphql (~> 2.2.6) + graphql-docs (~> 4.0) rack-cors (~> 1.0) - decidim-assemblies (0.27.1) - decidim-core (= 0.27.1) - decidim-blogs (0.27.1) - decidim-admin (= 0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-budgets (0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-comments (0.27.1) - decidim-core (= 0.27.1) + decidim-assemblies (0.29.1) + decidim-core (= 0.29.1) + decidim-blogs (0.29.1) + decidim-admin (= 0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-budgets (0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-comments (0.29.1) + decidim-core (= 0.29.1) redcarpet (~> 3.5, >= 3.5.1) - decidim-core (0.27.1) + decidim-core (0.29.1) active_link_to (~> 1.0) - acts_as_list (~> 0.9) + acts_as_list (~> 1.0) batch-loader (~> 1.2) browser (~> 2.7) - carrierwave (~> 2.2.1) cells-erb (~> 0.1.0) cells-rails (~> 0.1.3) charlock_holmes (~> 0.7) date_validator (~> 0.12.0) - decidim-api (= 0.27.1) devise (~> 4.7) - devise-i18n (~> 1.2) + devise-i18n (~> 1.2, < 1.11.1) diffy (~> 3.3) - doorkeeper (~> 5.1) + doorkeeper (~> 5.6, >= 5.6.6) doorkeeper-i18n (~> 4.0) file_validators (~> 3.0) fog-local (~> 0.6) foundation_rails_helper (~> 4.0) geocoder (~> 1.8) hashdiff (>= 0.4.0, < 2.0.0) + image_processing (~> 1.2) invisible_captcha (~> 0.12) kaminari (~> 1.2, >= 1.2.1) - loofah (~> 2.3.1) + loofah (~> 2.19, >= 2.19.1) mime-types (>= 1.16, < 4.0) mini_magick (~> 4.9) - mustache (~> 1.1.0) + net-smtp (~> 0.3.1) + nokogiri (~> 1.16, >= 1.16.2) omniauth (~> 2.0) omniauth-facebook (~> 5.0) omniauth-google-oauth2 (~> 1.0) omniauth-rails_csrf_protection (~> 1.0) omniauth-twitter (~> 1.4) paper_trail (~> 12.0) - pg (~> 1.1.4, < 2) + pg (~> 1.4.0, < 2) pg_search (~> 2.2) premailer-rails (~> 1.10) - rack (~> 2.2, >= 2.2.3) + psych (~> 4.0) + rack (~> 2.2, >= 2.2.8.1) rack-attack (~> 6.0) - rails (~> 6.1.0) - rails-i18n (~> 6.0) - ransack (~> 2.4.1) + rails (~> 7.0.8) + rails-i18n (~> 7.0) + ransack (~> 3.2.1) redis (~> 4.1) request_store (~> 1.5.0) rubyXL (~> 3.4) rubyzip (~> 2.0) - seven_zip_ruby (~> 1.3) - social-share-button (~> 1.2, >= 1.2.1) - valid_email2 (~> 2.1) - webpacker (= 6.0.0.rc.5) - webpush (~> 1.1) + shakapacker (~> 7.1.0) + valid_email2 (~> 4.0) + web-push (~> 3.0) wisper (~> 2.0) - decidim-debates (0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-dev (0.27.1) - axe-core-rspec (~> 4.1.0) + decidim-debates (0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-dev (0.29.1) + bullet (~> 7.1.6) byebug (~> 11.0) - capybara (~> 3.24) - db-query-matchers (~> 0.10.0) - decidim (= 0.27.1) - erb_lint (~> 0.0.35) - factory_bot_rails (~> 4.8) - i18n-tasks (~> 0.9.18) - mdl (~> 0.5) - nokogiri (~> 1.13) - parallel_tests (~> 3.7) - puma (~> 5.0) + capybara (~> 3.39) + decidim (= 0.29.1) + erb_lint (~> 0.4.0) + factory_bot_rails (~> 6.2) + faker (~> 3.2) + i18n-tasks (~> 1.0) + nokogiri (~> 1.16, >= 1.16.2) + parallel_tests (~> 4.2) + puma (~> 6.2, >= 6.3.1) rails-controller-testing (~> 1.0) + rspec (~> 3.12) rspec-cells (~> 0.3.7) - rspec-html-matchers (~> 0.9.1) - rspec-rails (~> 4.0) + rspec-html-matchers (~> 0.10) + rspec-rails (~> 6.0) rspec-retry (~> 0.6.2) - rspec_junit_formatter (~> 0.3.0) - rubocop (~> 1.28.0) - rubocop-rails (~> 2.14) - rubocop-rspec (~> 2.10) - selenium-webdriver (~> 4.1.0) - simplecov (~> 0.21.0) + rspec_junit_formatter (~> 0.6.0) + rubocop (~> 1.65.0) + rubocop-capybara (~> 2.21) + rubocop-factory_bot (~> 2.26) + rubocop-faker (~> 1.1) + rubocop-performance (~> 1.21) + rubocop-rails (~> 2.25) + rubocop-rspec (~> 3.0) + rubocop-rspec_rails (~> 2.30) + rubocop-rubycw (~> 0.1) + selenium-webdriver (~> 4.9) + simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1.0) + spring (~> 4.0) + spring-watcher-listen (~> 2.0) w3c_rspec_validators (~> 0.3.0) - webmock (~> 3.6) + webmock (~> 3.18) wisper-rspec (~> 1.0) - decidim-forms (0.27.1) - decidim-core (= 0.27.1) + decidim-forms (0.29.1) + decidim-core (= 0.29.1) wicked_pdf (~> 2.1) - wkhtmltopdf-binary (~> 0.12) - decidim-generators (0.27.1) - decidim-core (= 0.27.1) - decidim-initiatives (0.27.1) - decidim-admin (= 0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-verifications (= 0.27.1) - origami (~> 2.1) - rexml (~> 3.2.5) - wicked (~> 1.3) + wkhtmltopdf-binary (= 0.12.6.6) + decidim-generators (0.29.1) + decidim-core (= 0.29.1) + decidim-initiatives (0.29.1) + decidim-admin (= 0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-verifications (= 0.29.1) + hexapdf (~> 0.32.0) wicked_pdf (~> 2.1) - wkhtmltopdf-binary (~> 0.12) - decidim-meetings (0.27.1) - decidim-core (= 0.27.1) - decidim-forms (= 0.27.1) + wkhtmltopdf-binary (= 0.12.6.6) + decidim-meetings (0.29.1) + decidim-core (= 0.29.1) + decidim-forms (= 0.29.1) icalendar (~> 2.5) - decidim-pages (0.27.1) - decidim-core (= 0.27.1) - decidim-participatory_processes (0.27.1) - decidim-core (= 0.27.1) - decidim-proposals (0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - doc2text (~> 0.4.5) + decidim-pages (0.29.1) + decidim-core (= 0.29.1) + decidim-participatory_processes (0.29.1) + decidim-core (= 0.29.1) + decidim-proposals (0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + doc2text (~> 0.4.7) redcarpet (~> 3.5, >= 3.5.1) - decidim-sortitions (0.27.1) - decidim-admin (= 0.27.1) - decidim-comments (= 0.27.1) - decidim-core (= 0.27.1) - decidim-proposals (= 0.27.1) - decidim-surveys (0.27.1) - decidim-core (= 0.27.1) - decidim-forms (= 0.27.1) - decidim-templates (= 0.27.1) - decidim-system (0.27.1) + decidim-sortitions (0.29.1) + decidim-admin (= 0.29.1) + decidim-comments (= 0.29.1) + decidim-core (= 0.29.1) + decidim-proposals (= 0.29.1) + decidim-surveys (0.29.1) + decidim-core (= 0.29.1) + decidim-forms (= 0.29.1) + decidim-system (0.29.1) active_link_to (~> 1.0) - decidim-core (= 0.27.1) + decidim-core (= 0.29.1) devise (~> 4.7) devise-i18n (~> 1.2) - devise_invitable (~> 2.0) - decidim-templates (0.27.1) - decidim-core (= 0.27.1) - decidim-forms (= 0.27.1) - decidim-verifications (0.27.1) - decidim-core (= 0.27.1) + devise_invitable (~> 2.0, >= 2.0.9) + decidim-verifications (0.29.1) + decidim-core (= 0.29.1) declarative-builder (0.1.0) declarative-option (< 0.2.0) declarative-option (0.1.0) - descendants_tracker (0.0.4) - thread_safe (~> 0.3, >= 0.3.1) - devise (4.8.1) + devise (4.9.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-i18n (1.10.2) - devise (>= 4.8.0) - devise_invitable (2.0.6) + devise-i18n (1.11.0) + devise (>= 4.9.0) + devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - diff-lcs (1.5.0) + diff-lcs (1.5.1) diffy (3.4.2) - doc2text (0.4.5) - nokogiri (>= 1.13.2, < 1.14.0) + doc2text (0.4.7) + nokogiri (>= 1.13.2, < 1.17.0) rubyzip (~> 2.3.0) - docile (1.4.0) - doorkeeper (5.6.2) + docile (1.4.1) + doorkeeper (5.7.1) railties (>= 5) doorkeeper-i18n (4.0.1) - dumb_delegator (1.0.0) - erb_lint (0.0.37) + erb_lint (0.4.0) activesupport - better_html (~> 1.0.7) - html_tokenizer + better_html (>= 2.0.1) parser (>= 2.7.1.4) rainbow rubocop smart_properties erbse (0.1.4) temple - erubi (1.11.0) + erubi (1.13.0) escape_utils (1.3.0) - excon (0.95.0) - execjs (2.8.1) + excon (0.112.0) extended-markdown-filter (0.7.0) html-pipeline (~> 2.9) - factory_bot (4.11.1) - activesupport (>= 3.0.0) - factory_bot_rails (4.11.1) - factory_bot (~> 4.11.1) - railties (>= 3.0.0) - faker (2.23.0) + factory_bot (6.5.0) + activesupport (>= 5.0.0) + factory_bot_rails (6.4.3) + factory_bot (~> 6.4) + railties (>= 5.0.0) + faker (3.4.2) i18n (>= 1.8.11, < 2) - faraday (2.7.2) - faraday-net_http (>= 2.0, < 3.1) - ruby2_keywords (>= 0.0.4) - faraday-net_http (3.0.2) - ffi (1.15.5) + faraday (2.12.0) + faraday-net_http (>= 2.0, < 3.4) + json + logger + faraday-net_http (3.3.0) + net-http + ffi (1.17.0-x86_64-darwin) file_validators (3.0.0) activemodel (>= 3.2) mime-types (>= 1.0) - fog-core (2.3.0) + fog-core (2.5.0) builder excon (~> 0.71) formatador (>= 0.2, < 2.0) @@ -423,49 +404,57 @@ GEM activesupport (>= 4.1, < 7.1) railties (>= 4.1, < 7.1) gemoji (3.0.1) - geocoder (1.8.1) - globalid (1.0.0) - activesupport (>= 5.0) - graphql (1.12.24) - graphql-docs (2.1.0) - commonmarker (~> 0.16) + geocoder (1.8.3) + base64 (>= 0.1.0) + csv (>= 3.0.0) + geom2d (0.4.1) + globalid (1.2.1) + activesupport (>= 6.1) + graphql (2.2.16) + base64 + graphql-docs (4.0.0) + commonmarker (~> 0.23, >= 0.23.6) + dartsass (~> 1.49) escape_utils (~> 1.2) extended-markdown-filter (~> 0.4) gemoji (~> 3.0) - graphql (~> 1.12) - html-pipeline (~> 2.9) - sass (~> 3.4) - hashdiff (1.0.1) + graphql (~> 2.0) + html-pipeline (~> 2.14, >= 2.14.3) + hashdiff (1.1.1) hashie (5.0.0) - highline (2.0.3) - hkdf (0.3.0) + hexapdf (0.32.2) + cmdparse (~> 3.0, >= 3.0.3) + geom2d (~> 0.3) + openssl (>= 2.2.1) + highline (3.1.1) + reline html-pipeline (2.14.3) activesupport (>= 2) nokogiri (>= 1.4) - html_tokenizer (0.0.7) htmlentities (4.3.4) - i18n (1.12.0) + i18n (1.14.6) concurrent-ruby (~> 1.0) - i18n-tasks (0.9.37) + i18n-tasks (1.0.14) activesupport (>= 4.0.2) ast (>= 2.1.0) erubi highline (>= 2.0.0) i18n - parser (>= 2.2.3.0) + parser (>= 3.2.2.1) rails-i18n rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) - icalendar (2.8.0) + icalendar (2.10.3) ice_cube (~> 0.16) - ice_cube (0.16.4) - ice_nine (0.11.2) - image_processing (1.12.2) + ostruct + ice_cube (0.17.0) + image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) invisible_captcha (0.13.0) rails (>= 3.2.0) - json (2.6.3) + io-console (0.7.2) + json (2.7.2) jwt (2.5.0) kaminari (1.2.2) activesupport (>= 4.1.0) @@ -479,66 +468,55 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - kramdown (2.4.0) - rexml - kramdown-parser-gfm (1.1.0) - kramdown (~> 2.0) - launchy (2.5.0) - addressable (~> 2.7) - letter_opener (1.8.1) - launchy (>= 2.2, < 3) + language_server-protocol (3.17.0.3) + launchy (3.0.1) + addressable (~> 2.8) + childprocess (~> 5.0) + letter_opener (1.10.0) + launchy (>= 2.2, < 4) letter_opener_web (2.0.0) actionmailer (>= 5.2) letter_opener (~> 1.7) railties (>= 5.2) rexml - listen (3.7.1) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.3.1) + logger (1.6.1) + loofah (2.22.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) - mail (2.8.0) + nokogiri (>= 1.12.0) + mail (2.8.1) mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.0.2) + marcel (1.0.4) matrix (0.4.2) - mdl (0.12.0) - kramdown (~> 2.3) - kramdown-parser-gfm (~> 1.1) - mixlib-cli (~> 2.1, >= 2.1.1) - mixlib-config (>= 2.2.1, < 4) - mixlib-shellout - method_source (1.0.0) - mime-types (3.4.1) + method_source (1.1.0) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2022.0105) - mini_magick (4.12.0) - mini_mime (1.1.2) - mini_portile2 (2.8.0) - minitest (5.16.3) - mixlib-cli (2.1.8) - mixlib-config (3.0.27) - tomlrb - mixlib-shellout (3.2.7) - chef-utils - msgpack (1.6.0) - multi_xml (0.6.0) - mustache (1.1.1) - net-imap (0.3.3) + mime-types-data (3.2024.1001) + mini_magick (4.13.2) + mini_mime (1.1.5) + minitest (5.25.1) + msgpack (1.7.3) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + net-http (0.4.1) + uri + net-imap (0.4.17) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.3.4) net-protocol - nio4r (2.5.8) - nokogiri (1.13.10) - mini_portile2 (~> 2.8.0) + nio4r (2.7.3) + nokogiri (1.16.7-x86_64-darwin) racc (~> 1.4) oauth (1.1.0) oauth-tty (~> 1.0, >= 1.0.1) @@ -553,240 +531,252 @@ GEM rack (>= 1.2, < 4) snaky_hash (~> 2.0) version_gem (~> 1.1) - omniauth (2.1.0) + omniauth (2.1.2) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection omniauth-facebook (5.0.0) omniauth-oauth2 (~> 1.2) - omniauth-google-oauth2 (1.1.1) + omniauth-google-oauth2 (1.1.3) jwt (>= 2.0) - oauth2 (~> 2.0.6) + oauth2 (~> 2.0) omniauth (~> 2.0) - omniauth-oauth2 (~> 1.8.0) - omniauth-oauth (1.2.0) + omniauth-oauth2 (~> 1.8) + omniauth-oauth (1.2.1) oauth omniauth (>= 1.0, < 3) + rack (>= 1.6.2, < 4) omniauth-oauth2 (1.8.0) oauth2 (>= 1.4, < 3) omniauth (~> 2.0) - omniauth-rails_csrf_protection (1.0.1) + omniauth-rails_csrf_protection (1.0.2) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) rack - origami (2.1.0) - colorize (~> 0.7) + openssl (3.2.0) orm_adapter (0.5.0) + ostruct (0.6.0) paper_trail (12.3.0) activerecord (>= 5.2) request_store (~> 1.1) - parallel (1.22.1) - parallel_tests (3.13.0) + parallel (1.26.3) + parallel_tests (4.7.2) parallel - parser (3.1.3.0) + parser (3.3.5.0) ast (~> 2.4.1) - pg (1.1.4) - pg_search (2.3.6) - activerecord (>= 5.2) - activesupport (>= 5.2) - premailer (1.18.0) + racc + pg (1.4.6) + pg_search (2.3.7) + activerecord (>= 6.1) + activesupport (>= 6.1) + premailer (1.27.0) addressable - css_parser (>= 1.12.0) + css_parser (>= 1.19.0) htmlentities (>= 4.0.0) premailer-rails (1.12.0) actionmailer (>= 3) net-smtp premailer (~> 1.7, >= 1.7.9) - public_suffix (5.0.1) - puma (5.6.5) + psych (4.0.6) + stringio + public_suffix (6.0.1) + puma (6.4.3) nio4r (~> 2.0) - racc (1.6.1) - rack (2.2.4) - rack-attack (6.6.1) - rack (>= 1.0, < 3) + racc (1.8.1) + rack (2.2.10) + rack-attack (6.7.0) + rack (>= 1.0, < 4) rack-cors (1.1.1) rack (>= 2.0.0) - rack-protection (3.0.5) + rack-protection (3.2.0) + base64 (>= 0.1.0) + rack (~> 2.2, >= 2.2.4) + rack-proxy (0.7.7) rack - rack-proxy (0.7.4) - rack - rack-test (2.0.2) + rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7) - actioncable (= 6.1.7) - actionmailbox (= 6.1.7) - actionmailer (= 6.1.7) - actionpack (= 6.1.7) - actiontext (= 6.1.7) - actionview (= 6.1.7) - activejob (= 6.1.7) - activemodel (= 6.1.7) - activerecord (= 6.1.7) - activestorage (= 6.1.7) - activesupport (= 6.1.7) + rails (7.0.8.5) + actioncable (= 7.0.8.5) + actionmailbox (= 7.0.8.5) + actionmailer (= 7.0.8.5) + actionpack (= 7.0.8.5) + actiontext (= 7.0.8.5) + actionview (= 7.0.8.5) + activejob (= 7.0.8.5) + activemodel (= 7.0.8.5) + activerecord (= 7.0.8.5) + activestorage (= 7.0.8.5) + activesupport (= 7.0.8.5) bundler (>= 1.15.0) - railties (= 6.1.7) - sprockets-rails (>= 2.0.0) + railties (= 7.0.8.5) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.4.3) - loofah (~> 2.3) - rails-i18n (6.0.0) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + rails-i18n (7.0.9) i18n (>= 0.7, < 2) - railties (>= 6.0.0, < 7) - railties (6.1.7) - actionpack (= 6.1.7) - activesupport (= 6.1.7) + railties (>= 6.0.0, < 8) + railties (7.0.8.5) + actionpack (= 7.0.8.5) + activesupport (= 7.0.8.5) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rainbow (3.1.1) - rake (13.0.6) - ransack (2.4.2) - activerecord (>= 5.2.4) - activesupport (>= 5.2.4) + rake (13.2.1) + ransack (3.2.1) + activerecord (>= 6.1.5) + activesupport (>= 6.1.5) i18n rb-fsevent (0.11.2) - rb-inotify (0.10.1) + rb-inotify (0.11.1) ffi (~> 1.0) - redcarpet (3.5.1) - redis (4.8.0) - regexp_parser (2.6.1) + redcarpet (3.6.0) + redis (4.8.1) + regexp_parser (2.9.2) + reline (0.5.10) + io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) - responders (3.0.1) - actionpack (>= 5.0) - railties (>= 5.0) - rexml (3.2.5) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-cells (0.3.8) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) + rexml (3.3.8) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-cells (0.3.9) cells (>= 4.0.0, < 6.0.0) - rspec-rails (>= 3.0.0, < 6.1.0) - rspec-core (3.12.0) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.1) + rspec-rails (>= 3.0.0, < 6.2.0) + rspec-core (3.13.1) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-html-matchers (0.9.4) + rspec-support (~> 3.13.0) + rspec-html-matchers (0.10.0) nokogiri (~> 1) - rspec (>= 3.0.0.a, < 4) - rspec-mocks (3.12.1) + rspec (>= 3.0.0.a) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-rails (4.1.2) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-support (~> 3.13.0) + rspec-rails (6.1.5) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.12.0) - rspec_junit_formatter (0.3.0) + rspec-support (3.13.1) + rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.28.2) + rubocop (1.65.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.1.0.0) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml - rubocop-ast (>= 1.17.0, < 2.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.24.0) - parser (>= 3.1.1.0) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.32.3) + parser (>= 3.3.1.0) + rubocop-capybara (2.21.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.26.1) + rubocop (~> 1.61) rubocop-faker (1.1.0) faker (>= 2.12.0) rubocop (>= 0.82.0) - rubocop-rails (2.15.2) + rubocop-performance (1.22.1) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.26.2) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.7.0, < 2.0) - rubocop-rspec (2.11.1) - rubocop (~> 1.19) - ruby-progressbar (1.11.0) - ruby-vips (2.1.4) + rubocop (>= 1.52.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.1.0) + rubocop (~> 1.61) + rubocop-rspec_rails (2.30.0) + rubocop (~> 1.61) + rubocop-rspec (~> 3, >= 3.0.1) + rubocop-rubycw (0.1.6) + rubocop (~> 1.0) + ruby-progressbar (1.13.0) + ruby-vips (2.2.2) ffi (~> 1.12) - ruby2_keywords (0.0.5) - rubyXL (3.4.25) + logger + rubyXL (3.4.27) nokogiri (>= 1.10.8) rubyzip (>= 1.3.0) rubyzip (2.3.2) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - selenium-webdriver (4.1.0) - childprocess (>= 0.5, < 5.0) + selenium-webdriver (4.25.0) + base64 (~> 0.2) + logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) semantic_range (3.0.0) - seven_zip_ruby (1.3.0) - simplecov (0.21.2) + shakapacker (7.1.0) + activesupport (>= 5.2) + rack-proxy (>= 0.6.1) + railties (>= 5.2) + semantic_range (>= 2.3.0) + simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) simplecov-cobertura (2.1.0) rexml simplecov (~> 0.19) - simplecov-html (0.12.3) + simplecov-html (0.13.1) simplecov_json_formatter (0.1.4) smart_properties (1.17.0) snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) - social-share-button (1.2.4) - coffee-rails - spring (2.1.1) - spring-watcher-listen (2.0.1) + spring (4.2.1) + spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) - spring (>= 1.2, < 3.0) - sprockets (4.2.0) - concurrent-ruby (~> 1.0) - rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - sprockets (>= 3.0.0) - ssrf_filter (1.1.1) - temple (0.9.1) + spring (>= 4) + stringio (3.1.1) + temple (0.10.3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - thor (1.2.1) - thread_safe (0.3.6) - tilt (2.0.11) - timeout (0.3.1) - tomlrb (2.0.3) + thor (1.3.2) + tilt (2.4.0) + timeout (0.4.1) twilio-ruby (5.72.1) faraday (>= 0.9, < 3.0) jwt (>= 1.5, <= 2.5) nokogiri (>= 1.6, < 2.0) - tzinfo (2.0.5) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) unaccent (0.4.0) - unicode-display_width (2.3.0) - valid_email2 (2.3.1) + unicode-display_width (2.6.0) + uniform_notifier (1.16.0) + uri (0.13.1) + valid_email2 (4.0.6) activemodel (>= 3.2) mail (~> 2.5) - version_gem (1.1.1) - virtus (2.0.0) - axiom-types (~> 0.1) - coercible (~> 1.0) - descendants_tracker (~> 0.0, >= 0.0.3) + version_gem (1.1.4) w3c_rspec_validators (0.3.0) rails rspec @@ -797,60 +787,53 @@ GEM rexml (~> 3.2) warden (1.2.9) rack (>= 2.0.9) - web-console (4.2.0) + web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.18.1) + web-push (3.0.1) + jwt (~> 2.0) + openssl (~> 3.0) + webmock (3.24.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webpacker (6.0.0.rc.5) - activesupport (>= 5.2) - rack-proxy (>= 0.6.1) - railties (>= 5.2) - semantic_range (>= 2.3.0) - webpush (1.1.0) - hkdf (~> 0.2) - jwt (~> 2.0) - websocket-driver (0.7.5) + websocket (1.2.11) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - wicked (1.4.0) - railties (>= 3.0.7) - wicked_pdf (2.6.3) + wicked_pdf (2.8.1) activesupport wisper (2.0.1) wisper-rspec (1.1.0) wkhtmltopdf-binary (0.12.6.6) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.6) + zeitwerk (2.7.0) PLATFORMS - ruby + x86_64-darwin-23 DEPENDENCIES bootsnap (~> 1.4) - brakeman (~> 5.2) + brakeman (~> 6.1) byebug (~> 11.0) - decidim (~> 0.27.0) - decidim-dev (~> 0.27.0) - decidim-initiatives (~> 0.27.0) + decidim (~> 0.29.0) + decidim-dev (~> 0.29.0) + decidim-initiatives (~> 0.29.0) decidim-ptp! - faker (~> 2.14) + faker (~> 3.2) letter_opener_web (~> 2.0) listen (~> 3.1) - parallel_tests (~> 3.7) - puma (>= 5.6.2) + parallel_tests (~> 4.2) + puma (>= 6.3.1) rubocop-faker - spring (~> 2.0) - spring-watcher-listen (~> 2.0) + spring web-console (~> 4.2) RUBY VERSION - ruby 3.0.4p208 + ruby 3.2.2p53 BUNDLED WITH - 2.2.33 + 2.4.10 diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb index 28867f95..11790dbe 100644 --- a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb +++ b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb @@ -9,9 +9,9 @@ module BudgetListItemCellExtensions included do delegate :voting_open?, :voting_finished?, to: :controller - def button_text - t(:vote, scope: i18n_scope) - end + #def button_text + # t(:vote, scope: i18n_scope) + #end def mark_image_as_voted(budget) return nil unless voted_this?(budget) diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/projectx_list_item_extensions.rb similarity index 100% rename from decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb rename to decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/projectx_list_item_extensions.rb diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb deleted file mode 100644 index 06d3f70f..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb +++ /dev/null @@ -1,88 +0,0 @@ -<% if voting_booth_forced? %> -
-
-
-
- <% if voting_open? && voted_this?(budget) %> -

- <%= translated_attribute(budget.title) %> -

- <% else %> - <%= link_to_budget budget, class: link_class do %> -

- <%= translated_attribute(budget.title) %> -

- <% end %> - <% end%> - -
- <%= decidim_sanitize_editor html_truncate(translated_attribute(budget.description), length: 65, separator: "...") %> -
- - <%= link_to_budget budget, class: "button small hollow show_votes" do %> - - <%= generate_text_for(budget)%> - - <% end %> -
-
-
-
- <% if voting_open? %> -
-
- - <% if !voted_this?(budget) %> - <%= link_to_budget budget, class: "button expanded button--sc" do %> - <%= t("take_part", scope: "decidim.budgets.budget_list_item") %> - - <%= t("current_phase", scope: "decidim.budgets.budget_list_item", phase: translated_attribute(current_phase)) %> - <% end %> - <% end %> -
-
- <% end %> -
-
-
-
-<% else %> -
-
- <%= link_to budget_path(budget), class: link_class do %> -

- <%= translated_attribute(title) %> -

- <% end %> - -
- - <%= budget_to_currency(total_budget) %> - -
- - <%= decidim_sanitize_editor translated_attribute(description) %> -
- - <% if !voting_finished? %> -
- <% if voted? %> - - <%= icon "check", class: "icon--small", role: "img", aria_label: t("decidim.budgets.budget_list_item.voting_finished") %> - - <% elsif progress? %> - - <%= icon "bookmark", class: "icon--small", role: "img", aria_label: t("decidim.budgets.budget_list_item.voting_started") %> - - <% end %> -
- <% end %> - -
- <%= link_to budget_path(budget), class: "button button--sc expanded #{button_class} mb-none" do %> - <%= button_text %> - <%= icon "chevron-right", class: "icon--small", role: "img" %> - <% end %> -
-
-<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb new file mode 100644 index 00000000..6f14377f --- /dev/null +++ b/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb @@ -0,0 +1,134 @@ + + +
+
+ <%= link_to resource_path, class: "p-4" do %> +

+ <%= decidim_escape_translated(title) %> +

+ <% if voted? %> + <%= icon "check-double-line", class: "inline-block align-middle fill-success ml-2 h-[1.5em] w-[1.5em]" %> + <% end %> +
+ <%= decidim_sanitize html_truncate(translated_attribute(description), length: 70) %> +
+ <% unless voted? %> +
+ <%= render :projects_count %> + <%= render :vote_action if voting_context? %> +
+ <% end %> + <% end %> + <% if voted? %> +
+ <%= render :projects_count %> + <%= render :vote_action if voting_context? %> +
+ <% end %> +
+ <% if voting_context? %> + <%= link_to resource_path, class: "budget__card__highlight-vote" do %> +
+ + <%= t("name", scope: "decidim.budgets.admin.models.budget") %> + + + <%= budget_to_currency(total_budget) %> + +
+ <%= button_tag class: "button button__sm #{button_class} #{voted? ? "button__transparent-secondary" : "button__secondary"} budget__card__highlight-vote__button" do %> + <%= button_text %> + <%= icon "arrow-right-line" %> + <% end %> + <% end %> + <% end %> +
diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb similarity index 89% rename from decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/show.erb rename to decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb index bddd5b78..a4de6e50 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb @@ -36,9 +36,15 @@ <% else %>
+
+ <%= decidim_sanitize_editor_admin(landing_page_content) %> +
+
<% end %> + diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_list.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb similarity index 54% rename from decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_list.erb rename to decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb index 8563c5a2..2b997cbf 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_list.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb @@ -20,20 +20,32 @@ <% else %> <%# show highlighted budgets first %> <% if highlighted.any? %> + + <% reordered_highlighted_budgets.each do |budget| %> + <%= cell("decidim/budgets/budget_list_item", budget) %> + <% end %> <% end %> - - <% non_highlighted = (budgets - highlighted - voted) %> + + <% non_highlighted = reorder(budgets).where.not(id: (highlighted + voted).map(&:id)) %> <% if non_highlighted.any? %> + + <% non_highlighted.each do |budget| %> + <%= cell("decidim/budgets/budget_list_item", budget) %> + <% end %> <% end %> <% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb similarity index 91% rename from decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/show.erb rename to decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb index 5bf9ebac..b3f5d576 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb @@ -49,8 +49,13 @@ <% end %>
+ +
+ <%= main_list %>
diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb b/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb new file mode 100644 index 00000000..b570920c --- /dev/null +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Decidim + module Budgets + # This cell renders the budget project card for an instance of a project + # the default size is the Medium Card (:m) + class ProjectCell < Decidim::ViewModel + include Cell::ViewModel::Partial + + def show + cell card_size, model, options + end + + private + + def card_size + case @options[:size] + when :s + "decidim/budgets/project_s" + when :g #added + "decidim/budgets/project_g" + else + "decidim/budgets/project_l" + end + end + end + end +end diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb new file mode 100644 index 00000000..3a330019 --- /dev/null +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb @@ -0,0 +1,30 @@ +<%= link_to resource_path, class: classes[:default], id: resource_id do %> +
+ <% if has_image? %> + <%= image_tag resource_image_path, alt: alt_title %> + <% else %> + <%= external_icon "media/images/project-placeholder-card-g.svg", class: "card__project-placeholder-g" %> + <% end %> +
+
+
+ <%= content_tag title_tag, title, class: title_class %> + <%= translated_attribute(project.title) %> +
+ + <%= description.truncate_words(20) %> + + <% if metadata_cell.present? %> +
+ <%= cell metadata_cell, resource, links: false, skip_state: true, **options %> +
+ <% end %> + +
+ + <%= budget_to_currency(project.budget_amount) %> + + <%= cell("decidim/budgets/project_vote_button", project, show_only_added:, view_mode:) %> +
+
+<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb new file mode 100644 index 00000000..38388a52 --- /dev/null +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require "cell/partial" + +module Decidim + module Budgets + # This cell renders the Grid (:g) project card + # for an instance of a Project + class ProjectGCell < Decidim::CardGCell + include Decidim::Budgets::ProjectsHelper + include Decidim::Proposals::ApplicationHelper + include Decidim::LayoutHelper + + alias project model + + delegate :state_item, to: :metadata_cell_instance + + def show + render + end + + def title + present(model).title(html_escape: true) + end + + def metadata_cell = "decidim/budgets/project_metadata" + + def metadata_cell_instance + @metadata_cell_instance ||= cell("decidim/budgets/project_metadata", model) + end + + def resource_image_path + project.photos.first&.url if project.photos.present? + end + + private + + def resource_path + resource_locator([project.budget, project]).path + end + + def resource_added? + current_order && current_order.projects.include?(model) + end + + def current_order + @current_order ||= controller.try(:current_order) + end + + def show_only_added + options[:show_only_added] + end + + def view_mode + options[:view_mode] + end + + def classes + super.merge(metadata: "card__list-metadata") + end + + def resource_id = "project-#{project.id}-item" + end + end +end diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb index 6430b6d1..d18302bb 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb @@ -1,9 +1,9 @@ <%= action_authorized_button_to( "vote", - budget_order_line_item_path(model.budget, project_id: model), + budget_order_line_item_path(model.budget, project_id: model, show_only_added: options[:show_only_added], view_mode: options[:view_mode]), method: vote_button_method, remote: true, - class: "button #{scale_up} #{selected_budget} customized-budget display-block project-vote-button", + class: "button #{scale_up} budget-list__action project__vote-button button__secondary customized-budget display-block project-#{project.id}-vote-button ", data: { add: !resource_added?, disable: true, diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgetsx_controller_extensions.rb similarity index 92% rename from decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb rename to decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgetsx_controller_extensions.rb index b5f8ffb5..1e3226c8 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgetsx_controller_extensions.rb @@ -20,7 +20,7 @@ def index def determine_layout return layout unless voting_booth_forced? - return layout unless voting_enabled? + return layout unless voting_enabled? return layout if voted_all_budgets? @@ -32,6 +32,7 @@ def open_and_voting_booth_forced? end def layout + #"layouts/decidim/application" current_participatory_space_manifest.context(current_participatory_space_context).layout end end diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb index 7f9383c1..c010bb10 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb @@ -7,6 +7,9 @@ module ProjectsControllerExtensions include VotingSupport included do + before_action :set_view_mode, only: :index # added + layout :determine_layout # added + def index raise ActionController::RoutingError, "Not Found" unless budget @@ -27,6 +30,20 @@ def allow_access? true end + #added + def determine_layout + "decidim/budgets/voting_layout" + end + + def set_view_mode + @view_mode ||= params[:view_mode] || session[:view_mode] || default_view_mode + session[:view_mode] = @view_mode + end + + def default_view_mode + #@default_view_mode ||= current_component.settings.attachments_allowed? ? "grid" : "list" + @default_view_mode = "grid" + end end end end diff --git a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb index 0fa5a49e..9c8cbf92 100644 --- a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb +++ b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb @@ -68,6 +68,24 @@ def voting_booth_forced? def voting_terms translated_attribute(component_settings.try(:voting_terms)).presence end + + def toggle_view_mode_link(current_mode, target_mode, title, params) + path = budget_projects_path(params.permit(:order, filter: {}).merge({ view_mode: target_mode })) + icon_name = target_mode == "grid" ? "layout-grid-fill" : "list-check" + icon_class = "view-icon--disabled" unless current_mode == target_mode + + link_to path, remote: true, title: do + icon(icon_name, class: icon_class, role: "img", "aria-hidden": true) + end + end + + def projects_container_class(view_mode) + view_mode == "grid" ? "card__grid-grid" : "card__list-list" + end + + def card_size_for_view_mode(view_mode) + view_mode == "grid" ? :g : :l + end end end end diff --git a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js index 46125ca0..c956c266 100644 --- a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js +++ b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js @@ -1,6 +1,6 @@ -import initializeProjects from "src/decidim/budgets_booth/projects" -import "src/decidim/budgets_booth/progressFixed" -import "src/decidim/budgets_booth/exit_handler" +//import initializeProjects from "src/decidim/budgets_booth/projects" +//import "src/decidim/budgets_booth/progressFixed" +//import "src/decidim/budgets_booth/exit_handler" import "src/decidim/budgets_booth/popup_selected_project" $(() => { diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets/progressFixed.js b/decidim-budgets_booth/app/packs/src/decidim/budgets/progressXFixed.js similarity index 100% rename from decidim-budgets_booth/app/packs/src/decidim/budgets/progressFixed.js rename to decidim-budgets_booth/app/packs/src/decidim/budgets/progressXFixed.js diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets/projects.js b/decidim-budgets_booth/app/packs/src/decidim/budgets/projectsX.js similarity index 100% rename from decidim-budgets_booth/app/packs/src/decidim/budgets/projects.js rename to decidim-budgets_booth/app/packs/src/decidim/budgets/projectsX.js diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exit_handler.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exitX_handler.js similarity index 100% rename from decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exit_handler.js rename to decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exitX_handler.js diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixed.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixedX.js similarity index 100% rename from decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixed.js rename to decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixedX.js diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projects.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projectsX.js similarity index 100% rename from decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projects.js rename to decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projectsX.js diff --git a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss index 81cfda71..d6015067 100644 --- a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss +++ b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss @@ -1,6 +1,6 @@ /* css for decidim_budgets_booth */ $passive-item-color: #919191; -$active-item-color: $black; +$active-item-color: black; #voting-help, #thanks-message{ @@ -13,9 +13,9 @@ $active-item-color: $black; } .voting-help-item{ - @include breakpoint(medium down){ - margin: 1rem 0; - } + //@include breakpoint(medium down){ + // margin: 1rem 0; + //} .circle{ &.active{ @@ -35,9 +35,9 @@ $active-item-color: $black; height: 150px; left: 10px; - @include breakpoint(medium down){ - left: 20%; - } + //@include breakpoint(medium down){ + // left: 20%; + //} svg{ display: block; @@ -77,9 +77,9 @@ $active-item-color: $black; .filters__section:first-child{ display: none; - @include breakpoint(medium){ - display: block; - } + //@include breakpoint(medium){ + // display: block; + //} } } } @@ -92,9 +92,9 @@ $active-item-color: $black; .budget-summary__progressbox--fixed{ padding: .5rem 2rem 1rem; - @include breakpoint(mediumlarge){ - padding: 1rem 4rem; - } + //@include breakpoint(mediumlarge){ + // padding: 1rem 4rem; + //} } .spaced-bottom{ @@ -103,10 +103,10 @@ $active-item-color: $black; .budget-list{ &__item{ - @include breakpoint(medium down){ - margin-bottom: 2rem; - display: block; - } + //@include breakpoint(medium down){ + // margin-bottom: 2rem; + // display: block; + //} } &__data{ @@ -117,9 +117,9 @@ $active-item-color: $black; .flex-column{ flex-direction: column; - @include breakpoint(medium down){ - flex-direction: column; - } + //@include breakpoint(medium down){ + // flex-direction: column; + //} } .card{ @@ -162,17 +162,17 @@ $active-item-color: $black; width: 2.5rem; text-align: center; - @include breakpoint(smallmedium up){ - height: 3rem; - width: 3rem; - } + //@include breakpoint(smallmedium up){ + // height: 3rem; + // width: 3rem; + //} } } } .zip-code-errors{ .form-error{ - margin-top: $global-margin; + margin-top: 1rem; } } @@ -188,6 +188,101 @@ $active-item-color: $black; } #affirm-checkbox{ - margin-top: $global-margin; + margin-top: 1rem; font-weight: bold; } +//new +.budget__card__grid-project { + display:flex; + justify-content:space-between; + align-items:center; +} +.budget__card__grid-project__amount { + margin-bottom: 0.5rem; + display: inline-block; + text-align: center; + font-size: 20px; + line-height: 25px; + font-weight: 600; + --tw-text-opacity: 1; + color: rgb(62 76 92 / 1); +} +.project__vote-button { + padding: 0.75rem; + font-size: 18px; + line-height: 23px; + font-weight: 600; +} +.budget-summary__new-container { + margin-top:2rem; + position:sticky; + bottom:0; +} + #project-item{ + &.project-show .budget-summary__content { + max-width: 100vw; + } +} +.projects-index { + display:flex; + flex-direction:column; + margin-top:2rem; + height: 100vh; +} +.projects-index__container { + width:90%; + margin:auto; +} +.projects-index__container__header { + margin-bottom:3rem; +} +.project-show { + display:flex; + flex-direction:column; +} +.project-show__budget-summary { + position:sticky; + top:0; +} +#menu-bar-custom { + justify-content: flex-start; + padding-left: 2rem; + color: white; +} +.menu-bar__exit-link { + display:flex; + justify-content:space-between; + align-items:center; +} +.menu-bar__span { + margin:0 1%; +} +.menu-bar__title { + font-weight:bold; +} +.custom-filters > .filter-container+.filter-container { + margin-top: 0; +} +#budget-booth-body > [data-dialog] >* { + --tw-translate-x: -50%; +} +.budget-progress > .budget-summary__progressbar--meter { + background-color: green; +} +.menu-bar__exit-link > svg { + flex: none; + fill: white; + display: block; + vertical-align: middle; + box-sizing: border-box; + border-width: 0; + border-style: solid; + border-color: white; + font-weight: 600; + font-size: 18px; + line-height: 23px; + --tw-bg-opacity: 1; + --tw-text-opacity: 1; + cursor: pointer; + margin-right: 0.5em; +} diff --git a/decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_form.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_formX.html.erb similarity index 100% rename from decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_form.html.erb rename to decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_formX.html.erb diff --git a/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb similarity index 99% rename from decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb rename to decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb index ab86daf2..cb4bf33c 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb @@ -7,3 +7,5 @@ <%= render partial: "decidim/budgets/voting/thanks_message_modal" if vote_success_content.present? && !voted_all_budgets? %> <% handle_thanks_popup %> <%= javascript_pack_tag("decidim_budgets_booth_budgets") %> + + diff --git a/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb b/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb index dc157ad4..5ae12004 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb @@ -1,35 +1,32 @@ -var $orderTotalBudget = $('#order-total-budget'); -var $orderSelectedProjects = $('#order-selected-projects'); -var $orderProgress = $('#order-progress'); +var $orderProgress = document.querySelectorAll('[id^=order-progress] .budget-summary__content'); var $projectItem = $('#project-<%= project.id %>-item'); +var $projectVoteButton = $('.project-<%= project.id %>-vote-button'); var $budgetConfirm = $('#budget-confirm'); -var $projectModal = $('#project-modal-<%= project.id %>'); -morphdom($orderTotalBudget[0], '<%= j(render partial: "decidim/budgets/projects/order_total_budget").strip.html_safe %>'); -morphdom($orderSelectedProjects[0], '<%= j(render partial: "decidim/budgets/projects/order_selected_projects").strip.html_safe %>'); -morphdom($orderProgress[0], '<%= j(render partial: "decidim/budgets/projects/order_progress").strip.html_safe %>'); +$orderProgress.forEach((orderProgress) => { + var $orderTotalBudget = $(orderProgress).find("[id^=order-total-budget]"); + $orderTotalBudget.html('<%= j(render partial: "decidim/budgets/projects/order_total_budget").strip.html_safe %>'); + + if(orderProgress.dataset.orderProgressResponsive) { + morphdom(orderProgress, '<%= j(render partial: "decidim/budgets/projects/order_progress_summary_content", locals: { include_heading: true, responsive: true }).strip.html_safe %>'); + } else { + morphdom(orderProgress, '<%= j(render partial: "decidim/budgets/projects/order_progress_summary_content", locals: { include_heading: true, responsive: false }).strip.html_safe %>'); + } +}) morphdom($budgetConfirm[0], '<%= j(render partial: "decidim/budgets/projects/budget_confirm").strip.html_safe %>') -$("#order-progress").foundation(); -$(".budget-summary__selected").foundation(); if ($projectItem.length > 0) { - morphdom($projectItem[0], '<%= j(render partial: "decidim/budgets/projects/project", locals: { project: project }).strip.html_safe %>'); -} - -if ($projectModal.length > 0) { - $projectModal.foundation("close"); // Close the modal when button has been clicked - var $projectModalButtonForm = $(".project-vote-button", $projectModal).parent(); - morphdom($projectModalButtonForm[0], '<%= j(cell("decidim/budgets/project_vote_button", project, scale_up: true)).strip.html_safe %>'); + <% if params[:action] == "destroy" && params[:show_only_added] == "true" %> + $projectItem[0].remove(); + <% elsif params[:view_mode] == "grid" %> + morphdom($projectItem[0], '<%= j(render partial: "decidim/budgets/projects/project", locals: { project: , view_mode: "grid" }).strip.html_safe %>'); + <% else %> + morphdom($projectItem[0], '<%= j(render partial: "decidim/budgets/projects/project", locals: { project: , view_mode: "list"}).strip.html_safe %>'); + <% end %> } -if ($projectModal.length > 0 && $projectModal.attr("aria-hidden") === "false") { - $(".project-vote-button", $projectModal).focus(); -} else { - $(".project-vote-button", $projectItem).focus(); +if ($projectVoteButton.length > 0) { + morphdom($projectVoteButton[0], '<%= j(cell("decidim/budgets/project_vote_button", project, scale_up: true)).strip.html_safe %>'); } -<% if @show_help_modal %> - $("#voting-help").foundation("open"); -<% end %> - window.DecidimBudgets.checkProgressPosition(); diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_confirm.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_confirm.html.erb similarity index 100% rename from decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_confirm.html.erb rename to decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_confirm.html.erb diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_excess.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb similarity index 86% rename from decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_excess.html.erb rename to decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb index 62072d3d..b464b60c 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_excess.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb @@ -1,7 +1,7 @@

<%= current_order.projects_rule? ? t(".projects_excess.title") : t(".budget_excess.title") %>

-
diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_summary.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_summary.html.erb similarity index 100% rename from decidim-budgets_booth/app/views/decidim/budgets/projects/_budget_summary.html.erb rename to decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_summary.html.erb diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_project.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_project.html.erb index a4743652..529dfb99 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_project.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_project.html.erb @@ -1 +1,3 @@ -<%= cell "decidim/budgets/project_list_item", project, voting_mode: voting_mode? %> +<% show_only_added ||= params.dig(:filter, :addition_type) == "added" %> +<% @view_mode = view_mode if @view_mode.nil? %> +<%= card_for project, from: project, size: card_size_for_view_mode(@view_mode), show_only_added:, view_mode: @view_mode, render_extra_data: true %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb index 3246fd97..8464fefd 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb @@ -1,15 +1,6 @@ -
-
- <%= order_selector available_orders, i18n_scope: "decidim.budgets.projects.orders" %> -
+
+ <%= render partial: "project", collection: projects, as: :project, locals: { card_size: card_size_for_view_mode(@view_mode) } %>
-
- <% projects.each do |project| %> - <%= render partial: "project", locals: { project: project } %> - <%= render partial: "project_modal", locals: { project: project } %> - <% end %> - <%= render partial: "project_modal", locals: { project: @select_project } if @select_project.present? %> -
-<%= render partial: "budget_excess" %> <%= decidim_paginate projects %> + diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb index 4be826aa..14771c98 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb @@ -1,37 +1,48 @@ -<%= render partial: "decidim/shared/component_announcement" %> +
+ <% add_decidim_page_title t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %> + <%= append_javascript_pack_tag "decidim_budgets" %> + <%= append_stylesheet_pack_tag "decidim_budgets" %> -<% cell("decidim/budgets/limit_announcement", budget) %> - -
"> -
- <% if voting_finished? %> -

- <%= t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %> -

- <% else %> - <%= render partial: "budget_summary" %> - <%= render partial: "cancel_voting_modal" %> + <%= render layout: "decidim/shared/custom_filters", locals: { filter_sections: , search_variable: :search_text_cont, skip_to_id: "projects" } do %> + <%= hidden_field_tag :order, order, id: nil, class: "order_filter" %> + <% end %> + <%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: true } %> + <%= cell("decidim/budgets/budget_information_modal", budget) %> +
+ <% content_for :aside do %> +

<%= t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %>

<% end %> -
-
-

- <%= render partial: "count" %> -

-
+ <% if projects.any? %> + <%= render partial: "exit_modal" %> + <%= render partial: "budget_excess" %> + <%= render partial: "budget_confirm" %> -
-
- <%= render partial: "filters_small_view" %> -
- <%= render partial: "filters" %> + <%= cell("decidim/budgets/limit_announcement", budget) %> +
+
+

Projects for Vote

+
+ <%= render partial: "order" %> +
+ +
-
-
- <%= render partial: "projects" %> -
+ +
+ <%= render partial: "projects" %> +
+ <% else %> + <%= cell("decidim/announcement", t("empty", scope: "decidim.budgets.projects")) %> + <% end %>
+ <% unless voting_finished? %> + +
+ <%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: false } %> +
+ <% end %>
-<%= render partial: "decidim/budgets/partials/voting_help_modal" unless current_workflow.try(:disable_voting_instructions?) %> - -<%= javascript_pack_tag("decidim_budgets_booth_voting") %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb index 1966a7e2..ca8eda5d 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb @@ -1,77 +1,101 @@ <% add_decidim_meta_tags( - title: translated_attribute(project.title), - description: translated_attribute(project.description) -) %> + title: translated_attribute(project.title), + description: translated_attribute(project.description) + ) %> <% -edit_link( - resource_locator([project.budget, project]).edit, - :update, - :project, - project: project -) + edit_link( + resource_locator([project.budget, project]).edit, + :update, + :project, + project: + ) %> -<%= cell("decidim/budgets/limit_announcement", budget) %> -
-
- <% if voting_mode? %> - <%= render partial: "budget_summary", locals: { include_heading: true } %> - <% else %> - <%= render partial: "pre_voting_budget_summary", locals: { include_heading: true } %> - <% end %> +<%= append_javascript_pack_tag "decidim_budgets" %> +<%= append_stylesheet_pack_tag "decidim_budgets" %> -
- <%= link_to budget_projects_path(budget), class: "link js-back-to-list" do %> - <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %> - <%= t(".view_all_projects") %> - <% end %> -

<%= translated_attribute project.title %>

-
-
+<%= render partial: "exit_modal" %> -
-
-
-
-
- <%= t(".budget") %> - <%= budget_to_currency project.budget_amount %> -
+
+ <%= render partial: "budget_summary", locals: { include_heading: true, project_item: true, responsive: true } %> + <% content_for :item_header do %> + <% unless voting_finished? %> +
+ <%= render partial: "budget_summary", locals: { include_heading: true, project_item: true, responsive: false } %> +
+ <%= render partial: "budget_excess" %> + <%= render partial: "budget_confirm" %> + <% end %> + <% end %> + <%= render layout: "layouts/decidim/shared/layout_item", locals: { back_path: budget_projects_path(budget) } do %> +
+ <%= cell("decidim/budgets/budget_information_modal", budget) %> + <%= cell("decidim/budgets/limit_announcement", budget) %> - <%= cell("decidim/budgets/project_votes_count", project, layout: :one_line, class: "display-block") %> + <%= cell("decidim/budgets/project_selected_status", project, as_label: true) %> +

+ <%= decidim_sanitize translated_attribute project.title %> +

+
+
+
+ <%= decidim_sanitize_editor_admin translated_attribute project.description %> +
+
+
+ <% if tabs.any? %> +
+
    + <% tabs.each_with_index do |tab, i| %> +
  • + +
  • + <% end %> +
- <% if voting_finished? %> - <%= cell("decidim/budgets/project_voted_hint", project, class: "display-block") %> - <% elsif voting_open? && !current_order_checked_out? %> - <%= t(".pre_vote.introduction") %> - <%= link_to budget_voting_index_path(select_project: project.id), class: "button expanded hollow display-block" do %> - <%= progress?(budget) ? t(".pre_vote.continue_voting") : t(".pre_vote.start_voting") %> + <% panels.each do |panel| %> +
+ <%= send(panel[:method], *panel[:args]) %> +
<% end %> - <% else %> - <%= cell("decidim/budgets/project_voted_hint", project, text_medium: true, class: "success text-m display-block margin-top-1") if current_order_checked_out? && voted_for?(project) %> - <% end %> - - <%= render partial: "decidim/shared/follow_button", locals: { followable: project, large: false } %> +
+ <% end %> +
+
+ <%= cell "decidim/comments_button", nil %> +
+ <%= cell "decidim/budgets/project_tags", project %>
-
- <%= resource_reference(project) %> - <%= render partial: "decidim/shared/share_modal" %> -
-
-
- <%= cell("decidim/budgets/project_selected_status", project, as_label: true) %> - <%= decidim_sanitize_editor translated_attribute project.description %> - <%= cell "decidim/budgets/project_tags", project, context: { extra_classes: ["tags--project"] } %> -
- <%= attachments_for project %> - <%= linked_resources_for project, :proposals, "included_proposals" %> - <%= linked_resources_for project, :results, "included_projects" %> -
-
-
+ -<%= comments_for project, polymorphic: [project.budget] %> + <% content_for :aside do %> +
+ <% if voting_open? %> + <%= cell("decidim/budgets/project_vote_button", project) %> + <% end %> +
+
+ + <%= t("budget", scope: "decidim.budgets.projects.show") %> + +
+ <%= budget_to_currency project.budget_amount %> +
+
+
+ <%= render partial: "decidim/shared/follow_button", class: "text-center", locals: { followable: project, large: false } %> + <%= cell "decidim/share_button", nil %> +
+ <% end %> + <% content_for :item_footer do %> + <%= comments_for project, polymorphic: [project.budget] %> + + <% end %> + <% end %> -<%= javascript_pack_tag("decidim_budgets") %> +
diff --git a/decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb b/decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb new file mode 100644 index 00000000..f8e6aa3c --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb @@ -0,0 +1,55 @@ +<% filter_sections = [] unless local_assigns.has_key?(:filter_sections) %> +<% search_label = t("decidim.searches.filters.search") unless local_assigns.has_key?(:search_label) %> + +<% if filter_sections.present? || local_assigns.has_key?(:search_variable) %> + <%= filter_form_for filter, url_for, class: "new_filter self-stretch", style: "width:90vw;margin:0 auto", data: { filters: "", component: "accordion" } do |form| %> + + + + + + <% end %> +<% end %> + diff --git a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_application.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_application.html.erb index c334e5ea..ce034530 100644 --- a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_application.html.erb +++ b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_application.html.erb @@ -6,21 +6,26 @@ <%= render partial: "layouts/decidim/head" %> - - - <%= cell("decidim/data_consent", current_organization) %> - <%= render partial: "layouts/decidim/impersonation_warning" %> - <%= render partial: "layouts/decidim/timeout_modal" %> - <%= render partial: "layouts/decidim/offline_banner" %> - - - <%= render partial: "layouts/decidim/budgets/voting_notification" %> + + + <%= link_to t("skip_button", scope: "decidim.accessibility"), "#content", class: "layout-container__skip" %> + <%= cell("decidim/data_consent", current_organization) %> + +
+
+ <%= render partial: "layouts/decidim/budgets/voting_menubar" %> +
<%= render "layouts/decidim/budgets/voting_wrapper" do %> <%= yield %> <% end %> + <%= render partial: "layouts/decidim/timeout_modal" %> <%= render partial: "decidim/shared/confirm_modal" %> + <%= render partial: "decidim/shared/login_modal" unless current_user %> + <%= render partial: "decidim/shared/authorization_modal" %> + <%= render partial: "decidim/shared/share_modal" %> <%= render partial: "layouts/decidim/decidim_javascript" %> <%= render partial: "layouts/decidim/data_consent_warning" %> +
diff --git a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb new file mode 100644 index 00000000..ad493d54 --- /dev/null +++ b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb @@ -0,0 +1,22 @@ + + diff --git a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb index b90db179..1981eda0 100644 --- a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb +++ b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb @@ -10,15 +10,7 @@ if respond_to?(:current_component) && current_component && can_be_managed?(curre end %> -
-
-
- -
-
+
+ <%= display_flash_messages %> + <%= yield %>
diff --git a/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb new file mode 100644 index 00000000..4403e8df --- /dev/null +++ b/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb @@ -0,0 +1,21 @@ +
+ <%= yield :item_header %> +
+
+
+ <% if params[:included_in] %> + <%= render partial: "layouts/decidim/shared/linked_resource" %> + <% end %> + + <%= yield %> +
+ + <%# this aside is for moving comments and versions at the bottom of the page only in responsive. %> + <% if content_for?(:item_footer) %> + + <% end %> +
diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 02f2b50c..420c8f20 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -72,6 +72,12 @@ en: ready: I am ready total_budget: 'Total budget: ' vote: Vote + order_selected_projects: + remove: Remove + selected_projects: + one: selected project + other: selected projects + view: See pre_voting_budget_summary: are_you_sure: Are you sure you want to delete your vote? cancel_order: Cancel your vote @@ -98,10 +104,12 @@ en: close_project: Close scope: 'Scope: ' show: + budget: Budget pre_vote: continue_voting: Continue voting introduction: Want to vote this project? start_voting: Start voting + view_all_projects: See all projects user_data: error: only_letters: Only letters and digits are allowed. @@ -172,3 +180,5 @@ en: budgets: voting_notification: notification: You are now in the voting booth. + voting_menubar: + cancel_voting: Exit voting booth diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 8678fd6c..4ca6184f 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -69,6 +69,12 @@ fr: ready: Je suis prêt total_budget: 'Budget total: ' vote: Voter + order_selected_projects: + remove: Supprimer + selected_projects: + one: projet sélectionné + other: projets sélectionnés + view: Voir pre_voting_budget_summary: are_you_sure: Êtes-vous sûr de vouloir annuler votre vote ? cancel_order: Annuler le vote @@ -91,10 +97,12 @@ fr: close_project: Fermer scope: 'Portée : ' show: + budget: Budget pre_vote: continue_voting: Continuer le vote introduction: Vous voulez voter pour ce projet ? start_voting: Commencer à voter + view_all_projects: Voir tous les projets user_data: error: only_letters: Seules les lettres et les chiffres sont autorisés. @@ -154,3 +162,5 @@ fr: budgets: voting_notification: notification: Vous êtes dans la cabine de vote. + voting_menubar: + cancel_voting: Abandonner le vote diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb index b22966a0..a1aac56f 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb @@ -54,9 +54,9 @@ class Engine < ::Rails::Engine Decidim::BudgetsBooth::ProjectVoteButtonCellExtensions ) - Decidim::Budgets::ProjectListItemCell.include( - Decidim::BudgetsBooth::ProjectListItemExtensions - ) + #Decidim::Budgets::ProjectListItemCell.include( + # Decidim::BudgetsBooth::ProjectListItemExtensions + #) Decidim::Budgets::BudgetListItemCell.include( Decidim::BudgetsBooth::BudgetListItemCellExtensions @@ -84,9 +84,9 @@ class Engine < ::Rails::Engine Decidim::BudgetsBooth::OrdersControllerExtensions ) - Decidim::Budgets::BudgetsController.include( - Decidim::BudgetsBooth::BudgetsControllerExtensions - ) + #Decidim::Budgets::BudgetsController.include( + # Decidim::BudgetsBooth::BudgetsControllerExtensions + #) Decidim::Budgets::ProjectsController.include( Decidim::BudgetsBooth::ProjectsControllerExtensions diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/version.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/version.rb index 7907af88..9523d40c 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/version.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/version.rb @@ -4,11 +4,11 @@ module Decidim # This holds the decidim-meetings version. module BudgetsBooth def self.decidim_version - "~> 0.27.0" + "~> 0.29.0" end def self.version - "0.27.0" + "0.29.0" end end end diff --git a/decidim-l10n/app/packs/stylesheets/decidim/l10n/l10n.scss b/decidim-l10n/app/packs/stylesheets/decidim/l10n/l10n.scss index 7fcc2e4c..63369b00 100644 --- a/decidim-l10n/app/packs/stylesheets/decidim/l10n/l10n.scss +++ b/decidim-l10n/app/packs/stylesheets/decidim/l10n/l10n.scss @@ -1,5 +1,5 @@ @import "vendor/flatpickr/flatpickr.min"; input[readonly].flatpickr-input{ - background-color: $input-background; + background-color: gray; } diff --git a/decidim-l10n/lib/decidim/l10n/engine.rb b/decidim-l10n/lib/decidim/l10n/engine.rb index 08ee7484..5a526c5d 100644 --- a/decidim-l10n/lib/decidim/l10n/engine.rb +++ b/decidim-l10n/lib/decidim/l10n/engine.rb @@ -41,13 +41,13 @@ class Engine < ::Rails::Engine initializer "decidim_l10n.add_customizations", after: "decidim.action_controller" do config.to_prepare do # Cells extensions - Decidim::Meetings::MeetingMCell.include( - ::Decidim::L10n::MeetingMCellExtensions - ) + #Decidim::Meetings::MeetingMCell.include( + # ::Decidim::L10n::MeetingMCellExtensions + #) - Decidim::Debates::DebateMCell.include( - ::Decidim::L10n::DebateMCellExtensions - ) + #Decidim::Debates::DebateMCell.include( + # ::Decidim::L10n::DebateMCellExtensions + #) # Form builders Decidim::FormBuilder.include(::Decidim::L10n::FormBuilderExtensions) diff --git a/decidim-l10n/lib/decidim/l10n/version.rb b/decidim-l10n/lib/decidim/l10n/version.rb index e7094e86..129d4f61 100644 --- a/decidim-l10n/lib/decidim/l10n/version.rb +++ b/decidim-l10n/lib/decidim/l10n/version.rb @@ -4,11 +4,11 @@ module Decidim # This holds the decidim-meetings version. module L10n def self.decidim_version - "~> 0.27.0" + "~> 0.29.0" end def self.version - "0.27.0" + "0.29.0" end end end diff --git a/decidim-l10n/spec/cells/decidim/debates/debate_m_cell_spec.rb b/decidim-l10n/spec/cells/decidim/debates/debate_m_cell_spec.rb index 4027f0b3..c7ee7038 100644 --- a/decidim-l10n/spec/cells/decidim/debates/debate_m_cell_spec.rb +++ b/decidim-l10n/spec/cells/decidim/debates/debate_m_cell_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +=begin require "spec_helper" describe Decidim::Debates::DebateMCell, type: :cell do @@ -21,3 +21,4 @@ end end end +=end diff --git a/decidim-l10n/spec/cells/decidim/meetings/meeting_m_cell_spec.rb b/decidim-l10n/spec/cells/decidim/meetings/meeting_m_cell_spec.rb index e0a3687d..1242053a 100644 --- a/decidim-l10n/spec/cells/decidim/meetings/meeting_m_cell_spec.rb +++ b/decidim-l10n/spec/cells/decidim/meetings/meeting_m_cell_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +=begin require "spec_helper" describe Decidim::Meetings::MeetingMCell, type: :cell do @@ -20,3 +20,4 @@ end end end +=end diff --git a/decidim-sms-twilio/lib/decidim/sms/twilio/version.rb b/decidim-sms-twilio/lib/decidim/sms/twilio/version.rb index 9cce74ef..93724fd0 100644 --- a/decidim-sms-twilio/lib/decidim/sms/twilio/version.rb +++ b/decidim-sms-twilio/lib/decidim/sms/twilio/version.rb @@ -5,11 +5,11 @@ module Sms # This holds the decidim-sms-twilio version. module Twilio def self.decidim_version - "~> 0.27.0" + "~> 0.29.0" end def self.version - "0.27.0" + "0.29.0" end end end diff --git a/decidim-smsauth/app/packs/stylesheets/decidim/smsauth/smsauth.scss b/decidim-smsauth/app/packs/stylesheets/decidim/smsauth/smsauth.scss index 3d580353..a546f360 100644 --- a/decidim-smsauth/app/packs/stylesheets/decidim/smsauth/smsauth.scss +++ b/decidim-smsauth/app/packs/stylesheets/decidim/smsauth/smsauth.scss @@ -2,12 +2,12 @@ .ss-main.country-select{ .ss-single-selected{ - padding: $input-padding; - font-size: $input-font-size; - line-height: $input-line-height; + padding: 5px; + font-size: 18px; + line-height: normal; height: 2.4375rem; - border: $input-border; - box-shadow: $input-shadow; + border: 1px solid black; + box-shadow: none; } .ss-single-selected, diff --git a/decidim-smsauth/lib/decidim/smsauth/version.rb b/decidim-smsauth/lib/decidim/smsauth/version.rb index 2fc1b7f5..94860056 100644 --- a/decidim-smsauth/lib/decidim/smsauth/version.rb +++ b/decidim-smsauth/lib/decidim/smsauth/version.rb @@ -4,11 +4,11 @@ module Decidim # This holds the decidim-Smsauth version. module Smsauth def self.decidim_version - "~> 0.27.0" + "~> 0.29.0" end def self.version - "0.27.0" + "0.29.0" end end end diff --git a/lib/decidim/ptp/version.rb b/lib/decidim/ptp/version.rb index 76b5a577..10325db5 100644 --- a/lib/decidim/ptp/version.rb +++ b/lib/decidim/ptp/version.rb @@ -4,11 +4,11 @@ module Decidim # This holds the decidim-ptp version. module Ptp def self.decidim_version - "~> 0.27.0" + "~> 0.29.0" end def self.version - "0.27.0" + "0.29.0" end end end diff --git a/package-lock.json b/package-lock.json index 61826a94..8cc30641 100644 --- a/package-lock.json +++ b/package-lock.json @@ -474,6 +474,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -489,6 +490,7 @@ "version": "7.21.10", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.10.tgz", "integrity": "sha512-3YybmT8FN4sZFXp0kTr9Gbu90wAIhC3feNung+qcRQ1wALGoSHgOz1c+fR3ZLGZ0LXqIpYmtE6Faua6tMDarUg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.21.0", @@ -506,6 +508,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -2166,6 +2169,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -2178,7 +2182,8 @@ "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead" }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", @@ -2503,19 +2508,19 @@ "dev": true }, "node_modules/@types/mdast": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", - "integrity": "sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", "dev": true, "peer": true, "dependencies": { - "@types/unist": "*" + "@types/unist": "^2" } }, "node_modules/@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true, "peer": true }, @@ -2525,9 +2530,9 @@ "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" }, "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true, "peer": true }, @@ -2550,9 +2555,9 @@ "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" }, "node_modules/@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "dev": true, "peer": true }, @@ -3128,13 +3133,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "peer": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4044,6 +4049,7 @@ "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -4704,9 +4710,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "peer": true, "dependencies": { @@ -4739,9 +4745,9 @@ } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "peer": true, "dependencies": { @@ -4787,9 +4793,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "peer": true, "dependencies": { @@ -4990,6 +4996,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5106,9 +5113,9 @@ } }, "node_modules/globby/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "peer": true, "engines": { @@ -5393,6 +5400,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6509,13 +6517,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "peer": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6705,28 +6713,12 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -6734,13 +6726,6 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", @@ -7776,9 +7761,9 @@ } }, "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true, "peer": true }, @@ -8086,9 +8071,9 @@ } }, "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "peer": true, "bin": { @@ -8356,6 +8341,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dependencies": { "glob": "^7.1.3" }, @@ -8887,9 +8873,9 @@ } }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, "peer": true }, @@ -8905,9 +8891,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true, "peer": true }, @@ -9275,9 +9261,9 @@ } }, "node_modules/stylelint/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "peer": true, "engines": { @@ -10444,6 +10430,7 @@ "version": "6.6.0", "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", "dependencies": { "workbox-background-sync": "6.6.0", "workbox-core": "6.6.0", @@ -12268,19 +12255,19 @@ "dev": true }, "@types/mdast": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", - "integrity": "sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", "dev": true, "peer": true, "requires": { - "@types/unist": "*" + "@types/unist": "^2" } }, "@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true, "peer": true }, @@ -12290,9 +12277,9 @@ "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" }, "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true, "peer": true }, @@ -12315,9 +12302,9 @@ "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" }, "@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "dev": true, "peer": true }, @@ -12763,13 +12750,13 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "peer": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -13900,9 +13887,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "peer": true, "requires": { @@ -13929,9 +13916,9 @@ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==" }, "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "peer": true, "requires": { @@ -13973,9 +13960,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "peer": true, "requires": { @@ -14202,9 +14189,9 @@ }, "dependencies": { "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "peer": true } @@ -15197,13 +15184,13 @@ } }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "peer": true, "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -15335,30 +15322,10 @@ "validate-npm-package-license": "^3.0.1" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "requires": { - "yallist": "^4.0.0" - } - }, "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "peer": true } @@ -15998,9 +15965,9 @@ "requires": {} }, "postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true, "peer": true }, @@ -16202,9 +16169,9 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "peer": true }, @@ -16764,9 +16731,9 @@ } }, "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, "peer": true }, @@ -16782,9 +16749,9 @@ } }, "spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true, "peer": true }, @@ -17064,9 +17031,9 @@ "peer": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "peer": true }, diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..a716628d --- /dev/null +++ b/yarn.lock @@ -0,0 +1,6058 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@apideck/better-ajv-errors@^0.3.1": + version "0.3.6" + resolved "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz" + integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== + dependencies: + json-schema "^0.4.0" + jsonpointer "^5.0.0" + leven "^3.1.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.22.0", "@babel/compat-data@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.3.tgz" + integrity sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ== + +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.1", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.15.0", "@babel/core@^7.15.5", "@babel/core@^7.17.9", "@babel/core@^7.4.0-0", "@babel/core@>=7.11.0": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.1.tgz" + integrity sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.22.0" + "@babel/helper-compilation-targets" "^7.22.1" + "@babel/helper-module-transforms" "^7.22.1" + "@babel/helpers" "^7.22.0" + "@babel/parser" "^7.22.0" + "@babel/template" "^7.21.9" + "@babel/traverse" "^7.22.1" + "@babel/types" "^7.22.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/eslint-parser@^7.16.5": + version "7.21.8" + resolved "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz" + integrity sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ== + dependencies: + "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" + eslint-visitor-keys "^2.1.0" + semver "^6.3.0" + +"@babel/generator@^7.22.0", "@babel/generator@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.22.3.tgz" + integrity sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A== + dependencies: + "@babel/types" "^7.22.3" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.3.tgz" + integrity sha512-ahEoxgqNoYXm0k22TvOke48i1PkavGu0qGCmcq9ugi6gnmvKNaMjKBSrZTnWUi1CFEeNAUiVba0Wtzm03aSkJg== + dependencies: + "@babel/types" "^7.22.3" + +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.1.tgz" + integrity sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ== + dependencies: + "@babel/compat-data" "^7.22.0" + "@babel/helper-validator-option" "^7.21.0" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.1.tgz" + integrity sha512-SowrZ9BWzYFgzUMwUmowbPSGu6CXL5MSuuCkG3bejahSpSymioPmuLdhPxNOc9MjuNGjy7M/HaXvJ8G82Lywlw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.1" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-member-expression-to-functions" "^7.22.0" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.22.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-split-export-declaration" "^7.18.6" + semver "^6.3.0" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.1.tgz" + integrity sha512-WWjdnfR3LPIe+0EY8td7WmjhytxXtjKAEpnAxun/hkNiyOaPlvGK+NZaBFIdi9ndYV3Gav7BpFvtUwnaJlwi1w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.3.1" + semver "^6.3.0" + +"@babel/helper-define-polyfill-provider@^0.4.0": + version "0.4.0" + resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz" + integrity sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg== + dependencies: + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.1.tgz" + integrity sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA== + +"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== + dependencies: + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-member-expression-to-functions@^7.22.0": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.3.tgz" + integrity sha512-Gl7sK04b/2WOb6OPVeNy9eFKeD3L6++CzL3ykPOWqTn08xgYYK0wz4TUh2feIImDXxcVW3/9WQ1NMKY66/jfZA== + dependencies: + "@babel/types" "^7.22.3" + +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz" + integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== + dependencies: + "@babel/types" "^7.21.4" + +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.1.tgz" + integrity sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.1" + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-simple-access" "^7.21.5" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.21.9" + "@babel/traverse" "^7.22.1" + "@babel/types" "^7.22.0" + +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.21.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz" + integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg== + +"@babel/helper-remap-async-to-generator@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7", "@babel/helper-replace-supers@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.1.tgz" + integrity sha512-ut4qrkE4AuSfrwHSps51ekR1ZY/ygrP1tp0WFm8oVq6nzc/hvfV/22JylndIbsf2U2M9LOMwiSddr6y+78j+OQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.1" + "@babel/helper-member-expression-to-functions" "^7.22.0" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/template" "^7.21.9" + "@babel/traverse" "^7.22.1" + "@babel/types" "^7.22.0" + +"@babel/helper-simple-access@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz" + integrity sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg== + dependencies: + "@babel/types" "^7.21.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": + version "7.20.0" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz" + integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== + dependencies: + "@babel/types" "^7.20.0" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz" + integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-option@^7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz" + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== + +"@babel/helper-wrap-function@^7.18.9": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz" + integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== + dependencies: + "@babel/helper-function-name" "^7.19.0" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + +"@babel/helpers@^7.22.0": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.3.tgz" + integrity sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w== + dependencies: + "@babel/template" "^7.21.9" + "@babel/traverse" "^7.22.1" + "@babel/types" "^7.22.3" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.21.9", "@babel/parser@^7.22.0", "@babel/parser@^7.22.4": + version "7.22.4" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz" + integrity sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.3.tgz" + integrity sha512-6r4yRwEnorYByILoDRnEqxtojYKuiIv9FojW2E8GUKo9eWBwbKcd9IiZOZpdyXc64RmyGGyPu3/uAcrz/dq2kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/plugin-transform-optional-chaining" "^7.22.3" + +"@babel/plugin-proposal-class-properties@^7.14.5": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-property-in-object@^7.21.0": + version "7.21.10" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.10.tgz" + integrity sha512-3YybmT8FN4sZFXp0kTr9Gbu90wAIhC3feNung+qcRQ1wALGoSHgOz1c+fR3ZLGZ0LXqIpYmtE6Faua6tMDarUg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.20.0" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz" + integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + +"@babel/plugin-syntax-import-attributes@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.3.tgz" + integrity sha512-i35jZJv6aO7hxEbIWQ41adVfOzjm9dcYDNeWlBMd8p0ZQRtNUCBrmGwZt+H5lb+oOC9a3svp956KP0oWGA1YsA== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz" + integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz" + integrity sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-async-generator-functions@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.3.tgz" + integrity sha512-36A4Aq48t66btydbZd5Fk0/xJqbpg/v4QWI4AH4cYHBXy9Mu42UOupZpebKFiCFNT9S9rJFcsld0gsv0ayLjtA== + dependencies: + "@babel/helper-environment-visitor" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-transform-async-to-generator@^7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz" + integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-remap-async-to-generator" "^7.18.9" + +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-block-scoping@^7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz" + integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + +"@babel/plugin-transform-class-properties@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.3.tgz" + integrity sha512-mASLsd6rhOrLZ5F3WbCxkzl67mmOnqik0zrg5W6D/X0QMW7HtvnoL1dRARLKIbMP3vXwkwziuLesPqWVGIl6Bw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-class-static-block@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.3.tgz" + integrity sha512-5BirgNWNOx7cwbTJCOmKFJ1pZjwk5MUfMIwiBBvsirCJMZeQgs5pk6i1OlkVg+1Vef5LfBahFOrdCnAWvkVKMw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.16.7", "@babel/plugin-transform-classes@^7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz" + integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.20.7" + "@babel/helper-split-export-declaration" "^7.18.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz" + integrity sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/template" "^7.20.7" + +"@babel/plugin-transform-destructuring@^7.21.3": + version "7.21.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz" + integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + +"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-dynamic-import@^7.22.1": + version "7.22.1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.1.tgz" + integrity sha512-rlhWtONnVBPdmt+jeewS0qSnMz/3yLFrqAP8hHC6EDcrYRSyuz9f9yQhHvVn2Ad6+yO9fHXac5piudeYrInxwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-export-namespace-from@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.3.tgz" + integrity sha512-5Ti1cHLTDnt3vX61P9KZ5IG09bFXp4cDVFJIAeCZuxu9OXXJJZp5iP0n/rzM2+iAutJY+KWEyyHcRaHlpQ/P5g== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz" + integrity sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + dependencies: + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-json-strings@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.3.tgz" + integrity sha512-IuvOMdeOOY2X4hRNAT6kwbePtK21BUyrAEgLKviL8pL6AEEVUVcqtRdN/HJXBLGIbt9T3ETmXRnFedRRmQNTYw== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-transform-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-logical-assignment-operators@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.3.tgz" + integrity sha512-CbayIfOw4av2v/HYZEsH+Klks3NC2/MFIR3QR8gnpGNNPEaq2fdlVCRYG/paKs7/5hvBLQ+H70pGWOHtlNEWNA== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-modules-amd@^7.20.11": + version "7.20.11" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz" + integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g== + dependencies: + "@babel/helper-module-transforms" "^7.20.11" + "@babel/helper-plugin-utils" "^7.20.2" + +"@babel/plugin-transform-modules-commonjs@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz" + integrity sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ== + dependencies: + "@babel/helper-module-transforms" "^7.21.5" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-simple-access" "^7.21.5" + +"@babel/plugin-transform-modules-systemjs@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.3.tgz" + integrity sha512-V21W3bKLxO3ZjcBJZ8biSvo5gQ85uIXW2vJfh7JSWf/4SLUSr1tOoHX3ruN4+Oqa2m+BKfsxTR1I+PsvkIWvNw== + dependencies: + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-validator-identifier" "^7.19.1" + +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.3.tgz" + integrity sha512-c6HrD/LpUdNNJsISQZpds3TXvfYIAbo+efE9aWmY/PmSRD0agrJ9cPMt4BmArwUQ7ZymEWTFjTyp+yReLJZh0Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-new-target@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.3.tgz" + integrity sha512-5RuJdSo89wKdkRTqtM9RVVJzHum9c2s0te9rB7vZC1zKKxcioWIy+xcu4OoIAjyFZhb/bp5KkunuLin1q7Ct+w== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.3.tgz" + integrity sha512-CpaoNp16nX7ROtLONNuCyenYdY/l7ZsR6aoVa7rW7nMWisoNoQNIH5Iay/4LDyRjKMuElMqXiBoOQCDLTMGZiw== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.3.tgz" + integrity sha512-+AF88fPDJrnseMh5vD9+SH6wq4ZMvpiTMHh58uLs+giMEyASFVhcT3NkoyO+NebFCNnpHJEq5AXO2txV4AGPDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.3.tgz" + integrity sha512-38bzTsqMMCI46/TQnJwPPpy33EjLCc1Gsm2hRTF6zTMWnKsN61vdrpuzIEGQyKEhDSYDKyZHrrd5FMj4gcUHhw== + dependencies: + "@babel/compat-data" "^7.22.3" + "@babel/helper-compilation-targets" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.3" + +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + +"@babel/plugin-transform-optional-catch-binding@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.3.tgz" + integrity sha512-bnDFWXFzWY0BsOyqaoSXvMQ2F35zutQipugog/rqotL2S4ciFOKlRYUu9djt4iq09oh2/34hqfRR2k1dIvuu4g== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.3.tgz" + integrity sha512-63v3/UFFxhPKT8j8u1jTTGVyITxl7/7AfOqK8C5gz1rHURPUGe3y5mvIf68eYKGoBNahtJnTxBKug4BQOnzeJg== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.3.tgz" + integrity sha512-x7QHQJHPuD9VmfpzboyGJ5aHEr9r7DsAsdxdhJiTB3J3j8dyl+NFZ+rX5Q2RWFDCs61c06qBfS4ys2QYn8UkMw== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-private-methods@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.3.tgz" + integrity sha512-fC7jtjBPFqhqpPAE+O4LKwnLq7gGkD3ZmC2E3i4qWH34mH3gOg2Xrq5YMHUq6DM30xhqM1DNftiRaSqVjEG+ug== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-private-property-in-object@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.3.tgz" + integrity sha512-C7MMl4qWLpgVCbXfj3UW8rR1xeCnisQ0cU7YJHV//8oNBS0aCIVg1vFnZXxOckHhEpQyqNNkWmvSEWnMLlc+Vw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-display-name@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz" + integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + +"@babel/plugin-transform-react-jsx@^7.18.6", "@babel/plugin-transform-react-jsx@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.3.tgz" + integrity sha512-JEulRWG2f04a7L8VWaOngWiK6p+JOSpB+DAtwfJgOaej1qdbNxqtK7MwTBHjUA10NeFcszlFNqCdbRcirzh2uQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-jsx" "^7.21.4" + "@babel/types" "^7.22.3" + +"@babel/plugin-transform-react-pure-annotations@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz" + integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-regenerator@^7.13.15", "@babel/plugin-transform-regenerator@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz" + integrity sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + regenerator-transform "^0.15.1" + +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-runtime@^7.15.0": + version "7.22.4" + resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.4.tgz" + integrity sha512-Urkiz1m4zqiRo17klj+l3nXgiRTFQng91Bc1eiLF7BMQu1e7wE5Gcq9xSv062IF068NHjcutSbIMev60gXxAvA== + dependencies: + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-plugin-utils" "^7.21.5" + babel-plugin-polyfill-corejs2 "^0.4.3" + babel-plugin-polyfill-corejs3 "^0.8.1" + babel-plugin-polyfill-regenerator "^0.5.0" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-spread@^7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz" + integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-template-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-unicode-escapes@^7.21.5": + version "7.21.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz" + integrity sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-unicode-property-regex@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.3.tgz" + integrity sha512-5ScJ+OmdX+O6HRuMGW4kv7RL9vIKdtdAj9wuWUKy1wbHY3jaM/UlyIiC1G7J6UJiiyMukjjK0QwL3P0vBd0yYg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.3": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.3.tgz" + integrity sha512-hNufLdkF8vqywRp+P55j4FHXqAX2LRUccoZHH7AFn1pq5ZOO2ISKW9w13bFZVjBoTqeve2HOgoJCcaziJVhGNw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.15.6", "@babel/preset-env@^7.21.5": + version "7.22.4" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.4.tgz" + integrity sha512-c3lHOjbwBv0TkhYCr+XCR6wKcSZ1QbQTVdSkZUaVpLv8CVWotBMArWUi5UAJrcrQaEnleVkkvaV8F/pmc/STZQ== + dependencies: + "@babel/compat-data" "^7.22.3" + "@babel/helper-compilation-targets" "^7.22.1" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-validator-option" "^7.21.0" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.3" + "@babel/plugin-proposal-private-property-in-object" "^7.21.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-attributes" "^7.22.3" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.21.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.3" + "@babel/plugin-transform-async-to-generator" "^7.20.7" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.21.0" + "@babel/plugin-transform-class-properties" "^7.22.3" + "@babel/plugin-transform-class-static-block" "^7.22.3" + "@babel/plugin-transform-classes" "^7.21.0" + "@babel/plugin-transform-computed-properties" "^7.21.5" + "@babel/plugin-transform-destructuring" "^7.21.3" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-dynamic-import" "^7.22.1" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-export-namespace-from" "^7.22.3" + "@babel/plugin-transform-for-of" "^7.21.5" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-json-strings" "^7.22.3" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.3" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.20.11" + "@babel/plugin-transform-modules-commonjs" "^7.21.5" + "@babel/plugin-transform-modules-systemjs" "^7.22.3" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.3" + "@babel/plugin-transform-new-target" "^7.22.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.3" + "@babel/plugin-transform-numeric-separator" "^7.22.3" + "@babel/plugin-transform-object-rest-spread" "^7.22.3" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-optional-catch-binding" "^7.22.3" + "@babel/plugin-transform-optional-chaining" "^7.22.3" + "@babel/plugin-transform-parameters" "^7.22.3" + "@babel/plugin-transform-private-methods" "^7.22.3" + "@babel/plugin-transform-private-property-in-object" "^7.22.3" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.21.5" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.20.7" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.21.5" + "@babel/plugin-transform-unicode-property-regex" "^7.22.3" + "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.3" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.22.4" + babel-plugin-polyfill-corejs2 "^0.4.3" + babel-plugin-polyfill-corejs3 "^0.8.1" + babel-plugin-polyfill-regenerator "^0.5.0" + core-js-compat "^3.30.2" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.12.13": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.3.tgz" + integrity sha512-lxDz1mnZ9polqClBCVBjIVUypoB4qV3/tZUDb/IlYbW1kiiLaXaX+bInbRjl+lNQ/iUZraQ3+S8daEmoELMWug== + dependencies: + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-validator-option" "^7.21.0" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.22.3" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.11.2", "@babel/runtime@^7.15.3", "@babel/runtime@^7.15.4", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz" + integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.21.9": + version "7.21.9" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz" + integrity sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ== + dependencies: + "@babel/code-frame" "^7.21.4" + "@babel/parser" "^7.21.9" + "@babel/types" "^7.21.5" + +"@babel/traverse@^7.20.5", "@babel/traverse@^7.22.1": + version "7.22.4" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.4.tgz" + integrity sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ== + dependencies: + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.22.3" + "@babel/helper-environment-visitor" "^7.22.1" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.22.4" + "@babel/types" "^7.22.4" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.22.0", "@babel/types@^7.22.3", "@babel/types@^7.22.4", "@babel/types@^7.4.4": + version "7.22.4" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.22.4.tgz" + integrity sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA== + dependencies: + "@babel/helper-string-parser" "^7.21.5" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@bufbuild/protobuf@^1.0.0": + version "1.2.1" + resolved "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.2.1.tgz" + integrity sha512-cwwGvLGqvoaOZmoP5+i4v/rbW+rHkguvTehuZyM2p/xpmaNSdT2h3B7kHw33aiffv35t1XrYHIkdJSEkSEMJuA== + +"@csstools/postcss-cascade-layers@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz" + integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA== + dependencies: + "@csstools/selector-specificity" "^2.0.2" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-color-function@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz" + integrity sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-font-format-keywords@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz" + integrity sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-hwb-function@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz" + integrity sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-ic-unit@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz" + integrity sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^2.0.7": + version "2.0.7" + resolved "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz" + integrity sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-nested-calc@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz" + integrity sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz" + integrity sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz" + integrity sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.3.0": + version "1.3.0" + resolved "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz" + integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-stepped-value-functions@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz" + integrity sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-text-decoration-shorthand@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz" + integrity sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-trigonometric-functions@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz" + integrity sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-unset-value@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz" + integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== + +"@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": + version "2.2.0" + resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz" + integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== + +"@decidim/dev@^0.27.2": + version "0.27.3" + resolved "https://registry.npmjs.org/@decidim/dev/-/dev-0.27.3.tgz" + integrity sha512-8g1IrhycJ4Ldc8Fy1foKMMlGWn4SdM0z2Ij+N7a08ELJTY0LOzapIMyU3W4SUpqSPoKxhirXWgulEZocyISd5Q== + dependencies: + axe-core "^4.1.4" + +"@decidim/eslint-config@^0.27.2": + version "0.27.3" + resolved "https://registry.npmjs.org/@decidim/eslint-config/-/eslint-config-0.27.3.tgz" + integrity sha512-bHaTzjgBgJKhRRZoLj9voIQjVB5qOwFMjdngoG4/nkBapzyqBbqZKlzDTJhavrJusKJQuNUFQA+/Hr+0I9IXeA== + +"@decidim/stylelint-config@^0.27.2": + version "0.27.3" + resolved "https://registry.npmjs.org/@decidim/stylelint-config/-/stylelint-config-0.27.3.tgz" + integrity sha512-bhtpi/ysOfvN2Vl1n+sUaYFxz4QscSfqca7f415tHH12DQvm808DH59mQmTiqDBtsI33f5T1UVfuBlTKkf2hiQ== + +"@decidim/webpacker@^0.27.2": + version "0.27.3" + resolved "https://registry.npmjs.org/@decidim/webpacker/-/webpacker-0.27.3.tgz" + integrity sha512-YYGvj+MGJwADcxD/eQBRObKMMxAw8cVUYPBIlTdlDfH9eFOqrKN0PpLcH0YFNwKUGbn5v9BTgAcoVgUJvbjqAw== + dependencies: + "@babel/core" "^7.15.5" + "@babel/eslint-parser" "^7.16.5" + "@babel/plugin-transform-classes" "^7.16.7" + "@babel/plugin-transform-regenerator" "^7.13.15" + "@babel/plugin-transform-runtime" "^7.15.0" + "@babel/preset-env" "^7.15.6" + "@babel/preset-react" "^7.12.13" + "@babel/runtime" "^7.15.4" + "@rails/ujs" "^6.1.3" + "@rails/webpacker" "6.0.0-rc.5" + autoprefixer "^10.4.1" + babel-loader "^8.2.2" + compression-webpack-plugin "^9.0.0" + css-loader "^6.5.1" + expose-loader "^2.0.0" + glob "^7.2.0" + js-yaml "^4.1.0" + mini-css-extract-plugin "^2.4.5" + path-complete-extname "^1.0.0" + pnp-webpack-plugin "^1.7.0" + postcss "^8.4.5" + postcss-flexbugs-fixes "^5.0.2" + postcss-import "^14.0.2" + postcss-loader "^6.2.1" + postcss-preset-env "^7.1.0" + postcss-scss "^4.0.2" + sass-embedded "^1.49.9" + source-map-loader "^0.2.4" + style-loader "^3.0.0" + terser-webpack-plugin "^5.2.4" + webpack "^5.53.0" + webpack-assets-manifest "^5.0.6" + webpack-cli "^4.8.0" + webpack-merge "^5.8.0" + webpack-sources "^3.2.1" + workbox-recipes "^6.4.2" + workbox-webpack-plugin "^6.4.2" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": + version "5.1.1-v1" + resolved "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz" + integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== + dependencies: + eslint-scope "5.1.1" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@rails/ujs@^6.1.3": + version "6.1.7" + resolved "https://registry.npmjs.org/@rails/ujs/-/ujs-6.1.7.tgz" + integrity sha512-0e7WQ4LE/+LEfW2zfAw9ppsB6A8RmxbdAUPAF++UT80epY+7emuQDkKXmaK0a9lp6An50RvzezI0cIQjp1A58w== + +"@rails/webpacker@6.0.0-rc.5": + version "6.0.0-rc.5" + resolved "https://registry.npmjs.org/@rails/webpacker/-/webpacker-6.0.0-rc.5.tgz" + integrity sha512-GOEhRs+mRRVZIiZbnLQ1WTxRCuu687rO4cvUVP7WMJ+z5uFr3EQkCaLq5VOtonWHzYbZIBEWH4rCWv0uZnrywQ== + dependencies: + "@babel/core" "^7.15.0" + "@babel/plugin-proposal-class-properties" "^7.14.5" + "@babel/plugin-transform-runtime" "^7.15.0" + "@babel/preset-env" "^7.15.0" + "@babel/runtime" "^7.15.3" + babel-loader "^8.2.2" + compression-webpack-plugin "^8.0.1" + glob "^7.1.7" + js-yaml "^4.1.0" + path-complete-extname "^1.0.0" + pnp-webpack-plugin "^1.7.0" + terser-webpack-plugin "^5.1.4" + webpack "^5.51.1" + webpack-assets-manifest "^5.0.6" + webpack-cli "^4.8.0" + webpack-merge "^5.8.0" + webpack-sources "^3.2.0" + +"@rollup/plugin-babel@^5.2.0": + version "5.3.1" + resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz" + integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-replace@^2.4.1": + version "2.4.2" + resolved "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz" + integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + magic-string "^0.25.7" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@stylelint/postcss-css-in-js@^0.37.2": + version "0.37.3" + resolved "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.3.tgz" + integrity sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg== + dependencies: + "@babel/core" "^7.17.9" + +"@stylelint/postcss-markdown@^0.36.2": + version "0.36.2" + resolved "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz" + integrity sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ== + dependencies: + remark "^13.0.0" + unist-util-find-all-after "^3.0.2" + +"@surma/rollup-plugin-off-main-thread@^2.2.3": + version "2.2.3" + resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz" + integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== + dependencies: + ejs "^3.1.6" + json5 "^2.2.0" + magic-string "^0.25.0" + string.prototype.matchall "^4.0.6" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.40.0" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz" + integrity sha512-nbq2mvc/tBrK9zQQuItvjJl++GTN5j06DaPtp3hZCpngmG6Q3xoyEmd0TwZI0gAy/G1X0zhGBbr2imsGFdFV0g== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/mdast@^3.0.0": + version "3.0.15" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz" + integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== + dependencies: + "@types/unist" "^2" + +"@types/minimist@^1.2.0": + version "1.2.5" + resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== + +"@types/node@*": + version "20.2.5" + resolved "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz" + integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== + +"@types/normalize-package-data@^2.4.0": + version "2.4.4" + resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + +"@types/trusted-types@^2.0.2": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz" + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== + +"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2": + version "2.0.11" + resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz" + integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== + +"@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@^1.11.5", "@webassemblyjs/wasm-parser@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8, acorn@^8.7.1: + version "8.8.2" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +acorn@^8.8.2: + version "8.8.2" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0: + version "8.12.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.12.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^8.6.0, ajv@>=8: + version "8.12.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^8.8.2, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@^5.1.3: + version "5.1.3" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-includes@^3.1.5, array-includes@^3.1.6: + version "3.1.6" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flat@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz" + integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.1.3" + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== + +ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" + integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@^2.5.0: + version "2.6.4" + resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +async@^3.2.3: + version "3.2.4" + resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +autoprefixer@^10.4.1, autoprefixer@^10.4.13: + version "10.4.14" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +autoprefixer@^9.8.6: + version "9.8.8" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz" + integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + picocolors "^0.2.1" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axe-core@^4.1.4, axe-core@^4.6.2: + version "4.7.2" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz" + integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== + +axobject-query@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz" + integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== + dependencies: + deep-equal "^2.0.5" + +babel-loader@^8.2.2: + version "8.3.0" + resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz" + integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^2.0.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-polyfill-corejs2@^0.4.3: + version "0.4.3" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz" + integrity sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.4.0" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.8.1: + version "0.8.1" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz" + integrity sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.0" + core-js-compat "^3.30.1" + +babel-plugin-polyfill-regenerator@^0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz" + integrity sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.0" + +bail@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5, "browserslist@>= 4.21.0": + version "4.21.7" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz" + integrity sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA== + dependencies: + caniuse-lite "^1.0.30001489" + electron-to-chromium "^1.4.411" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" + +buffer-builder@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz" + integrity sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +builtin-modules@^3.1.0: + version "3.3.0" + resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-keys@^6.2.2: + version "6.2.2" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz" + integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== + dependencies: + camelcase "^5.3.1" + map-obj "^4.0.0" + quick-lru "^4.0.1" + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001489: + version "1.0.30001494" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001494.tgz" + integrity sha512-sY2B5Qyl46ZzfYDegrl8GBCzdawSLT4ThM9b9F+aDYUrAG2zCOyMbd2Tq34mS1g4ZKBfjRlzOohQMxx28x6wJg== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.0.2: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone-regexp@^2.1.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz" + integrity sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q== + dependencies: + is-regexp "^2.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +colorette@^2.0.14: + version "2.0.20" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^2.20.0: + 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== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compression-webpack-plugin@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-8.0.1.tgz" + integrity sha512-VWDXcOgEafQDMFXEnoia0VBXJ+RMw81pmqe/EBiOIBnMfY8pG26eqwIS/ytGpzy1rozydltL0zL6KDH9XNWBxQ== + dependencies: + schema-utils "^3.0.0" + serialize-javascript "^6.0.0" + +compression-webpack-plugin@^9.0.0: + version "9.2.0" + resolved "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-9.2.0.tgz" + integrity sha512-R/Oi+2+UHotGfu72fJiRoVpuRifZT0tTC6UqFD/DUo+mv8dbOow9rVOuTvDv5nPPm3GZhHL/fKkwxwIHnJ8Nyw== + dependencies: + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +core-js-compat@^3.30.1, core-js-compat@^3.30.2: + version "3.30.2" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz" + integrity sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA== + dependencies: + browserslist "^4.21.5" + +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +css-blank-pseudo@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== + dependencies: + postcss-selector-parser "^6.0.9" + +css-has-pseudo@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== + dependencies: + postcss-selector-parser "^6.0.9" + +css-loader@^6.5.1: + version "6.8.1" + resolved "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz" + integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.21" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.3" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +css-prefers-color-scheme@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== + +cssdb@^7.1.0: + version "7.6.0" + resolved "https://registry.npmjs.org/cssdb/-/cssdb-7.6.0.tgz" + integrity sha512-Nna7rph8V0jC6+JBY4Vk4ndErUmfJfV6NJCaZdurL0omggabiy+QB2HCQtu5c/ACLZ0I7REv7A4QyPIoYzZx0w== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize-keys@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz" + integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +deep-equal@^2.0.5: + version "2.2.1" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz" + integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.0" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.0, deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +domelementtype@^1.3.1, domelementtype@1: + version "1.3.1" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +ejs@^3.1.6: + version "3.1.9" + resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + +electron-to-chromium@^1.4.411: + version "1.4.419" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.419.tgz" + integrity sha512-jdie3RiEgygvDTyS2sgjq71B36q2cDSBfPlwzUyuOrfYTNoYWyBxxjGJV/HAu3A2hB0Y+HesvCVkVAFoCKwCSw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +enhanced-resolve@^5.14.1: + version "5.14.1" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz" + integrity sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.21.2" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz" + integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + dependencies: + array-buffer-byte-length "^1.0.0" + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.2.0" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.10" + is-weakref "^1.0.2" + object-inspect "^1.12.3" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-module-lexer@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz" + integrity sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg== + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^8.2.0: + version "8.8.0" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz" + integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + +eslint-config-standard@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz" + integrity sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw== + +eslint-import-resolver-node@^0.3.7: + version "0.3.7" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz" + integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== + dependencies: + debug "^3.2.7" + is-core-module "^2.11.0" + resolve "^1.22.1" + +eslint-module-utils@^2.7.4: + version "2.8.0" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-import@^2.22.0, eslint-plugin-import@>=2.8.0: + version "2.27.5" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz" + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.7.4" + has "^1.0.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.6" + resolve "^1.22.1" + semver "^6.3.0" + tsconfig-paths "^3.14.1" + +eslint-plugin-jsx-a11y@^6.3.1: + version "6.7.1" + resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz" + integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== + dependencies: + "@babel/runtime" "^7.20.7" + aria-query "^5.1.3" + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + ast-types-flow "^0.0.7" + axe-core "^4.6.2" + axobject-query "^3.1.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + has "^1.0.3" + jsx-ast-utils "^3.3.3" + language-tags "=1.0.5" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + semver "^6.3.0" + +eslint-plugin-node@^11.1.0, eslint-plugin-node@>=5.2.1: + version "11.1.0" + resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-promise@^3.8.0, eslint-plugin-promise@>=3.6.0: + version "3.8.0" + resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz" + integrity sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ== + +eslint-plugin-react@^7.20.6: + version "7.32.2" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz" + integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + semver "^6.3.0" + string.prototype.matchall "^4.0.8" + +eslint-plugin-standard@^3.1.0, eslint-plugin-standard@>=3.0.1: + version "3.1.0" + resolved "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz" + integrity sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w== + +eslint-scope@^5.1.1, eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.0.0, eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", eslint@^7.25.0, "eslint@^7.5.0 || ^8.0.0", eslint@>=3.19.0, eslint@>=4.18.0, eslint@>=4.19.1, eslint@>=5.16.0, eslint@>=7.0.0: + version "7.32.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.5.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execall@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz" + integrity sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow== + dependencies: + clone-regexp "^2.1.0" + +expose-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/expose-loader/-/expose-loader-2.0.0.tgz" + integrity sha512-WBpSGlNkn7YwbU2us7O+h0XsoFrB43Y/VCNSpRV4OZFXXKgw8W800BgNxLV0S97N3+KGnFYSCAJi1AV86NO22w== + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + 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== + +fast-glob@^3.2.5, fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.0, file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +functions-have-names@^1.2.2, functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.1" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-stdin@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + 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== + +glob@^7.1.3, glob@^7.1.6, glob@^7.1.7, glob@^7.2.0: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.6.0: + version "13.20.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globals@^13.9.0: + version "13.20.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^11.0.2: + version "11.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +globjoin@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz" + integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg== + +gonzales-pe@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz" + integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== + dependencies: + minimist "^1.2.5" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + 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== + +hard-rejection@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" + integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@^4.0.1: + version "4.1.0" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== + dependencies: + lru-cache "^6.0.0" + +html-tags@^3.1.0: + version "3.3.1" + resolved "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== + +htmlparser2@^3.10.0: + version "3.10.1" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +idb@^7.0.1: + version "7.1.1" + resolved "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1: + version "5.2.4" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +ignore@^5.1.8: + version "5.3.2" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +ignore@^5.2.0: + version "5.3.2" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +immutable@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz" + integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@^2.0.1, inherits@^2.0.3, inherits@2: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.11.0, is-core-module@^2.5.0, is-core-module@^2.9.0: + version "2.12.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + +is-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.4: + 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== + dependencies: + isobject "^3.0.1" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== + +is-regexp@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz" + integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA== + +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jake@^10.8.5: + version "10.8.7" + resolved "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + 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== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.1: + 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" + +json5@^1.0.2: + 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" + +json5@^2.1.2, json5@^2.2.0, json5@^2.2.2: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonpointer@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: + version "3.3.3" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + dependencies: + array-includes "^3.1.5" + object.assign "^4.1.3" + +kind-of@^6.0.2, kind-of@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.5: + version "2.0.6" + resolved "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + +known-css-properties@^0.21.0: + version "0.21.0" + resolved "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz" + integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw== + +language-subtag-registry@~0.3.2: + version "0.3.22" + resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@=1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" + integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== + dependencies: + language-subtag-registry "~0.3.2" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^1.1.0: + 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== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lockfile@^1.0: + version "1.0.4" + resolved "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz" + integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== + dependencies: + signal-exit "^3.0.2" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash.get@^4.0: + version "4.4.2" + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + +lodash.has@^4.0: + version "4.5.2" + resolved "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz" + integrity sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + +lodash@^4.17.14, lodash@^4.17.20: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +longest-streak@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz" + integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== + +loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.25.0, magic-string@^0.25.7: + version "0.25.9" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + +make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" + integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== + +map-obj@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz" + integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== + +mathml-tag-names@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz" + integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== + +mdast-util-from-markdown@^0.8.0: + version "0.8.5" + resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz" + integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-string "^2.0.0" + micromark "~2.11.0" + parse-entities "^2.0.0" + unist-util-stringify-position "^2.0.0" + +mdast-util-to-markdown@^0.6.0: + version "0.6.5" + resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz" + integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ== + dependencies: + "@types/unist" "^2.0.0" + longest-streak "^2.0.0" + mdast-util-to-string "^2.0.0" + parse-entities "^2.0.0" + repeat-string "^1.0.0" + zwitch "^1.0.0" + +mdast-util-to-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz" + integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== + +meow@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz" + integrity sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize "^1.2.0" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.18.0" + yargs-parser "^20.2.3" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromark@~2.11.0: + version "2.11.4" + resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz" + integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== + dependencies: + debug "^4.0.0" + parse-entities "^2.0.0" + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.8" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +mini-css-extract-plugin@^2.4.5: + version "2.7.6" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz" + integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== + dependencies: + schema-utils "^4.0.0" + +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimist-options@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz" + integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + kind-of "^6.0.3" + +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +ms@^2.1.1, ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-releases@^2.0.12: + version "2.0.12" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz" + integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-package-data@^3.0.0: + version "3.0.3" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz" + integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== + dependencies: + hosted-git-info "^4.0.1" + is-core-module "^2.5.0" + semver "^7.3.4" + validate-npm-package-license "^3.0.1" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +normalize-selector@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz" + integrity sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw== + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz" + integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.3, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.fromentries@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.hasown@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz" + integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== + dependencies: + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.values@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-complete-extname@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/path-complete-extname/-/path-complete-extname-1.0.0.tgz" + integrity sha512-CVjiWcMRdGU8ubs08YQVzhutOR5DEfO97ipRIlOGMK5Bek5nQySknBpuxVAVJ36hseTNs+vdIcv57ZrWxH7zvg== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.2.2, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + 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== + dependencies: + find-up "^4.0.0" + +pnp-webpack-plugin@^1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz" + integrity sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg== + dependencies: + ts-pnp "^1.1.6" + +postcss-attribute-case-insensitive@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz" + integrity sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^4.2.4: + version "4.2.4" + resolved "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz" + integrity sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^8.0.4: + version "8.0.4" + resolved "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz" + integrity sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz" + integrity sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-media@^8.0.2: + version "8.0.2" + resolved "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz" + integrity sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-properties@^12.1.10: + version "12.1.11" + resolved "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz" + integrity sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz" + integrity sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^6.0.5: + version "6.0.5" + resolved "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz" + integrity sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-double-position-gradients@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz" + integrity sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-env-function@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz" + integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-flexbugs-fixes@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz" + integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== + +postcss-focus-visible@^6.0.4: + version "6.0.4" + resolved "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-focus-within@^5.0.4: + version "5.0.4" + resolved "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^3.0.5: + version "3.0.5" + resolved "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz" + integrity sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg== + +postcss-html@^0.36.0: + version "0.36.0" + resolved "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz" + integrity sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw== + dependencies: + htmlparser2 "^3.10.0" + +postcss-image-set-function@^4.0.7: + version "4.0.7" + resolved "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz" + integrity sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-import@^14.0.2: + version "14.1.0" + resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz" + integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== + +postcss-lab-function@^4.2.1: + version "4.2.1" + resolved "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz" + integrity sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-less@^3.1.4: + version "3.1.4" + resolved "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz" + integrity sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA== + dependencies: + postcss "^7.0.14" + +postcss-loader@^6.2.1: + version "6.2.1" + resolved "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-logical@^5.0.4: + version "5.0.4" + resolved "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== + +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== + +postcss-media-query-parser@^0.2.3: + version "0.2.3" + resolved "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz" + integrity sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig== + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-nesting@^10.2.0: + version "10.2.0" + resolved "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz" + integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +postcss-opacity-percentage@^1.1.2: + version "1.1.3" + resolved "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz" + integrity sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A== + +postcss-overflow-shorthand@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz" + integrity sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^7.0.5: + version "7.0.5" + resolved "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz" + integrity sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@^7.1.0: + version "7.8.3" + resolved "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz" + integrity sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag== + dependencies: + "@csstools/postcss-cascade-layers" "^1.1.1" + "@csstools/postcss-color-function" "^1.1.1" + "@csstools/postcss-font-format-keywords" "^1.0.1" + "@csstools/postcss-hwb-function" "^1.0.2" + "@csstools/postcss-ic-unit" "^1.0.1" + "@csstools/postcss-is-pseudo-class" "^2.0.7" + "@csstools/postcss-nested-calc" "^1.0.0" + "@csstools/postcss-normalize-display-values" "^1.0.1" + "@csstools/postcss-oklab-function" "^1.1.1" + "@csstools/postcss-progressive-custom-properties" "^1.3.0" + "@csstools/postcss-stepped-value-functions" "^1.0.1" + "@csstools/postcss-text-decoration-shorthand" "^1.0.0" + "@csstools/postcss-trigonometric-functions" "^1.0.2" + "@csstools/postcss-unset-value" "^1.0.2" + autoprefixer "^10.4.13" + browserslist "^4.21.4" + css-blank-pseudo "^3.0.3" + css-has-pseudo "^3.0.4" + css-prefers-color-scheme "^6.0.3" + cssdb "^7.1.0" + postcss-attribute-case-insensitive "^5.0.2" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^4.2.4" + postcss-color-hex-alpha "^8.0.4" + postcss-color-rebeccapurple "^7.1.1" + postcss-custom-media "^8.0.2" + postcss-custom-properties "^12.1.10" + postcss-custom-selectors "^6.0.3" + postcss-dir-pseudo-class "^6.0.5" + postcss-double-position-gradients "^3.1.2" + postcss-env-function "^4.0.6" + postcss-focus-visible "^6.0.4" + postcss-focus-within "^5.0.4" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.5" + postcss-image-set-function "^4.0.7" + postcss-initial "^4.0.1" + postcss-lab-function "^4.2.1" + postcss-logical "^5.0.4" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.2.0" + postcss-opacity-percentage "^1.1.2" + postcss-overflow-shorthand "^3.0.4" + postcss-page-break "^3.0.4" + postcss-place "^7.0.5" + postcss-pseudo-class-any-link "^7.1.6" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-pseudo-class-any-link@^7.1.6: + version "7.1.6" + resolved "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz" + integrity sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-resolve-nested-selector@^0.1.1: + version "0.1.6" + resolved "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz" + integrity sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw== + +postcss-safe-parser@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz" + integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== + dependencies: + postcss "^7.0.26" + +postcss-sass@^0.4.4: + version "0.4.4" + resolved "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz" + integrity sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg== + dependencies: + gonzales-pe "^4.3.0" + postcss "^7.0.21" + +postcss-scss@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz" + integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA== + dependencies: + postcss "^7.0.6" + +postcss-scss@^4.0.2: + version "4.0.6" + resolved "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz" + integrity sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ== + +postcss-selector-not@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz" + integrity sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.9: + version "6.0.13" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-syntax@^0.36.2, postcss-syntax@>=0.36.0, postcss-syntax@>=0.36.2: + version "0.36.2" + resolved "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz" + integrity sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w== + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +"postcss@^7.0.0 || ^8.0.1", postcss@^8, postcss@^8.0.0, postcss@^8.0.3, postcss@^8.1.0, postcss@^8.1.4, postcss@^8.2, postcss@^8.3, postcss@^8.4, postcss@^8.4.19, postcss@^8.4.21, postcss@^8.4.5, postcss@^8.4.6, postcss@>=5.0.0, postcss@>=7.0.0: + version "8.4.24" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz" + integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^7.0.14: + version "7.0.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^7.0.2: + version "7.0.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^7.0.21: + version "7.0.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^7.0.26: + version "7.0.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.6: + version "7.0.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: + version "5.6.0" + resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quick-lru@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" + integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +readable-stream@^3.1.1: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== + dependencies: + "@babel/runtime" "^7.8.4" + +regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" + +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +remark-parse@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz" + integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== + dependencies: + mdast-util-from-markdown "^0.8.0" + +remark-stringify@^9.0.0: + version "9.0.1" + resolved "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz" + integrity sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg== + dependencies: + mdast-util-to-markdown "^0.6.0" + +remark@^13.0.0: + version "13.0.0" + resolved "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz" + integrity sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA== + dependencies: + remark-parse "^9.0.0" + remark-stringify "^9.0.0" + unified "^9.1.0" + +repeat-string@^1.0.0: + version "1.6.1" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +require-from-string@^2.0.2: + 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== + +resolve-cwd@^3.0.0: + 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== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.9.0: + version "1.22.2" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.4: + version "2.0.0-next.4" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" + integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +"rollup@^1.20.0 || ^2.0.0", rollup@^1.20.0||^2.0.0, rollup@^2.0.0, rollup@^2.43.1: + version "2.79.1" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.4.0: + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +sass-embedded-darwin-x64@1.62.0: + version "1.62.0" + resolved "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.62.0.tgz" + integrity sha512-2sBQ4uWjZbf8TKXF8Aq7N0p5V2tKUr4zX9gQAiKvm1NBYwsW22+m8D34heOWu50ikpIxebvt7i/z7hafH5kzKg== + +sass-embedded@^1.49.9: + version "1.62.0" + resolved "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.62.0.tgz" + integrity sha512-SwTIG6UmrMiT94/v8G+2pPf6i+XwY4hOQxm8HZl0ld0st2KdGDj/SBXDznFl7+sJ6tFq6hvVvrB9rW5Nj7EhuQ== + dependencies: + "@bufbuild/protobuf" "^1.0.0" + buffer-builder "^0.2.0" + immutable "^4.0.0" + rxjs "^7.4.0" + supports-color "^8.1.1" + optionalDependencies: + sass-embedded-darwin-arm64 "1.62.0" + sass-embedded-darwin-x64 "1.62.0" + sass-embedded-linux-arm "1.62.0" + sass-embedded-linux-arm64 "1.62.0" + sass-embedded-linux-ia32 "1.62.0" + sass-embedded-linux-x64 "1.62.0" + sass-embedded-win32-ia32 "1.62.0" + sass-embedded-win32-x64 "1.62.0" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0: + version "3.1.2" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz" + integrity sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.1.2" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz" + integrity sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz" + integrity sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz" + integrity sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz" + integrity sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.2.1: + version "7.5.1" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz" + integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + dependencies: + lru-cache "^6.0.0" + +semver@^7.3.4: + version "7.6.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +semver@^7.3.5: + version "7.5.1" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz" + integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + dependencies: + lru-cache "^6.0.0" + +semver@^7.3.8: + version "7.5.1" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz" + integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + dependencies: + lru-cache "^6.0.0" + +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@^0.2.4: + version "0.2.4" + resolved "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz" + integrity sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ== + dependencies: + async "^2.5.0" + loader-utils "^1.1.0" + +source-map-support@~0.5.20: + 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== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.5.0" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.20" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz" + integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw== + +specificity@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz" + integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz" + integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.4.3" + side-channel "^1.0.4" + +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-comments@^2.0.1: + 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== + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.0.0: + version "3.3.3" + resolved "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz" + integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== + +style-search@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz" + integrity sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg== + +stylelint@13.11.0: + version "13.11.0" + resolved "https://registry.npmjs.org/stylelint/-/stylelint-13.11.0.tgz" + integrity sha512-DhrKSWDWGZkCiQMtU+VroXM6LWJVC8hSK24nrUngTSQvXGK75yZUq4yNpynqrxD3a/fzKMED09V+XxO4z4lTbw== + dependencies: + "@stylelint/postcss-css-in-js" "^0.37.2" + "@stylelint/postcss-markdown" "^0.36.2" + autoprefixer "^9.8.6" + balanced-match "^1.0.0" + chalk "^4.1.0" + cosmiconfig "^7.0.0" + debug "^4.3.1" + execall "^2.0.0" + fast-glob "^3.2.5" + fastest-levenshtein "^1.0.12" + file-entry-cache "^6.0.0" + get-stdin "^8.0.0" + global-modules "^2.0.0" + globby "^11.0.2" + globjoin "^0.1.4" + html-tags "^3.1.0" + ignore "^5.1.8" + import-lazy "^4.0.0" + imurmurhash "^0.1.4" + known-css-properties "^0.21.0" + lodash "^4.17.20" + log-symbols "^4.0.0" + mathml-tag-names "^2.1.3" + meow "^9.0.0" + micromatch "^4.0.2" + normalize-selector "^0.2.0" + postcss "^7.0.35" + postcss-html "^0.36.0" + postcss-less "^3.1.4" + postcss-media-query-parser "^0.2.3" + postcss-resolve-nested-selector "^0.1.1" + postcss-safe-parser "^4.0.2" + postcss-sass "^0.4.4" + postcss-scss "^2.1.1" + postcss-selector-parser "^6.0.4" + postcss-syntax "^0.36.2" + postcss-value-parser "^4.1.0" + resolve-from "^5.0.0" + slash "^3.0.0" + specificity "^0.4.1" + string-width "^4.2.0" + strip-ansi "^6.0.0" + style-search "^0.1.0" + sugarss "^2.0.0" + svg-tags "^1.0.0" + table "^6.0.7" + v8-compile-cache "^2.2.0" + write-file-atomic "^3.0.3" + +sugarss@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz" + integrity sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ== + dependencies: + postcss "^7.0.2" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + 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== + +svg-tags@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz" + integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA== + +table@^6.0.7, table@^6.0.9: + version "6.8.1" + resolved "https://registry.npmjs.org/table/-/table-6.8.1.tgz" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + +tapable@^2.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +tempy@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz" + integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== + dependencies: + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + +terser-webpack-plugin@^5.1.4, terser-webpack-plugin@^5.2.4, terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + +terser@^5.0.0, terser@^5.16.8: + version "5.17.7" + resolved "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz" + integrity sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +trim-newlines@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz" + integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== + +trough@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tsconfig-paths@^3.14.1: + version "3.14.2" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^2.1.0: + version "2.5.3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" + integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + +type-fest@^0.18.0: + version "0.18.1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz" + integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unified@^9.1.0: + version "9.2.2" + resolved "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz" + integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +unist-util-find-all-after@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz" + integrity sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ== + dependencies: + unist-util-is "^4.0.0" + +unist-util-is@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz" + integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +upath@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vfile-message@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz" + integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + +vfile@^4.0.0: + version "4.2.1" + resolved "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz" + integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-assets-manifest@^5.0.6: + version "5.1.0" + resolved "https://registry.npmjs.org/webpack-assets-manifest/-/webpack-assets-manifest-5.1.0.tgz" + integrity sha512-kPuTMEjBrqZQVJ5M6yXNBCEdFbQQn7p+loNXt8NOeDFaAbsNFWqqwR0YL1mfG5LbwhK5FLXWXpuK3GuIIZ46rg== + dependencies: + chalk "^4.0" + deepmerge "^4.0" + lockfile "^1.0" + lodash.get "^4.0" + lodash.has "^4.0" + schema-utils "^3.0" + tapable "^2.0" + +webpack-cli@^4.8.0, webpack-cli@4.x.x: + version "4.10.0" + resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-merge@^5.7.3, webpack-merge@^5.8.0: + version "5.9.0" + resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz" + integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^3.2.0, webpack-sources@^3.2.1, webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +"webpack@^4.4.0 || ^5.9.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.2.0, webpack@^5.51.1, webpack@^5.53.0, webpack@>=2, "webpack@4.x.x || 5.x.x": + version "5.85.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz" + integrity sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.9.0" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.14.1" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + +which@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workbox-background-sync@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz" + integrity sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw== + dependencies: + idb "^7.0.1" + workbox-core "6.6.0" + +workbox-broadcast-update@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz" + integrity sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q== + dependencies: + workbox-core "6.6.0" + +workbox-build@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz" + integrity sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ== + dependencies: + "@apideck/better-ajv-errors" "^0.3.1" + "@babel/core" "^7.11.1" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.2" + "@rollup/plugin-babel" "^5.2.0" + "@rollup/plugin-node-resolve" "^11.2.1" + "@rollup/plugin-replace" "^2.4.1" + "@surma/rollup-plugin-off-main-thread" "^2.2.3" + ajv "^8.6.0" + common-tags "^1.8.0" + fast-json-stable-stringify "^2.1.0" + fs-extra "^9.0.1" + glob "^7.1.6" + lodash "^4.17.20" + pretty-bytes "^5.3.0" + rollup "^2.43.1" + rollup-plugin-terser "^7.0.0" + source-map "^0.8.0-beta.0" + stringify-object "^3.3.0" + strip-comments "^2.0.1" + tempy "^0.6.0" + upath "^1.2.0" + workbox-background-sync "6.6.0" + workbox-broadcast-update "6.6.0" + workbox-cacheable-response "6.6.0" + workbox-core "6.6.0" + workbox-expiration "6.6.0" + workbox-google-analytics "6.6.0" + workbox-navigation-preload "6.6.0" + workbox-precaching "6.6.0" + workbox-range-requests "6.6.0" + workbox-recipes "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" + workbox-streams "6.6.0" + workbox-sw "6.6.0" + workbox-window "6.6.0" + +workbox-cacheable-response@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz" + integrity sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw== + dependencies: + workbox-core "6.6.0" + +workbox-core@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz" + integrity sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ== + +workbox-expiration@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz" + integrity sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw== + dependencies: + idb "^7.0.1" + workbox-core "6.6.0" + +workbox-google-analytics@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz" + integrity sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q== + dependencies: + workbox-background-sync "6.6.0" + workbox-core "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" + +workbox-navigation-preload@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz" + integrity sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q== + dependencies: + workbox-core "6.6.0" + +workbox-precaching@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz" + integrity sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw== + dependencies: + workbox-core "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" + +workbox-range-requests@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz" + integrity sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw== + dependencies: + workbox-core "6.6.0" + +workbox-recipes@^6.4.2, workbox-recipes@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz" + integrity sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A== + dependencies: + workbox-cacheable-response "6.6.0" + workbox-core "6.6.0" + workbox-expiration "6.6.0" + workbox-precaching "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" + +workbox-routing@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz" + integrity sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw== + dependencies: + workbox-core "6.6.0" + +workbox-strategies@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz" + integrity sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ== + dependencies: + workbox-core "6.6.0" + +workbox-streams@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz" + integrity sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg== + dependencies: + workbox-core "6.6.0" + workbox-routing "6.6.0" + +workbox-sw@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz" + integrity sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ== + +workbox-webpack-plugin@^6.4.2: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz" + integrity sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A== + dependencies: + fast-json-stable-stringify "^2.1.0" + pretty-bytes "^5.4.1" + upath "^1.2.0" + webpack-sources "^1.4.3" + workbox-build "6.6.0" + +workbox-window@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz" + integrity sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "6.6.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^20.2.3: + version "20.2.9" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +zwitch@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz" + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== From 0709fc2d4526cf4c42d42e472ff325051c9317cd Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 19 Nov 2024 13:47:31 +0100 Subject: [PATCH 02/93] feat: update files for kept functionalities --- ...ons.rb => project_list_item_extensions.rb} | 0 .../decidim/budgets/budget_list_item/show.erb | 51 +++++++ .../budgets/budget_list_item/showx.erb | 134 ------------------ .../decidim/budgets/budgets_list/voted.erb | 16 +++ .../budgets_booth/vote_completed/show.erb | 7 +- ...ns.rb => budgets_controller_extensions.rb} | 15 +- .../budgets_booth/complete_voting_popup.rb | 6 +- .../projects_helper_extensions.rb | 6 +- .../decidim/budgets/user_data_helper.rb | 15 +- .../decidim_budgets_booth_budgets.js | 1 + .../decidim_budgets_booth_voting.js | 8 +- .../{exitX_handler.js => exit_handler.js} | 33 +++-- .../budgets_booth/handle_thanks_session.js | 4 +- .../decidim/budgets_booth/budgets_booth.scss | 89 +++++++++++- .../decidim/budgets/budgets/index.html.erb | 39 +++++ .../decidim/budgets/budgets/indexX.html.erb | 11 -- .../budgets/projects/_exit_modal.html.erb | 19 +++ .../decidim/budgets/projects/index.html.erb | 83 ++++++----- .../decidim/budgets/projects/show.html.erb | 5 +- .../voting/_thanks_message_modal.html.erb | 8 +- .../decidim/shared/_custom_filters.html.erb | 55 ------- .../decidim/budgets/_voting_menubar.html.erb | 6 +- .../decidim/shared/_layout_item.html.erb | 2 +- decidim-budgets_booth/config/locales/en.yml | 1 + decidim-budgets_booth/config/locales/fr.yml | 1 + .../lib/decidim/budgets_booth/engine.rb | 28 ++-- 26 files changed, 337 insertions(+), 306 deletions(-) rename decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/{projectx_list_item_extensions.rb => project_list_item_extensions.rb} (100%) create mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb create mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/voted.erb rename decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/{budgetsx_controller_extensions.rb => budgets_controller_extensions.rb} (63%) rename decidim-budgets_booth/app/packs/src/decidim/budgets_booth/{exitX_handler.js => exit_handler.js} (71%) create mode 100644 decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb create mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_exit_modal.html.erb delete mode 100644 decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/projectx_list_item_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb similarity index 100% rename from decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/projectx_list_item_extensions.rb rename to decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb new file mode 100644 index 00000000..7b3133c1 --- /dev/null +++ b/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/show.erb @@ -0,0 +1,51 @@ +<% finished = voted_all_budgets? && !voted? %> +
+
+ <%= link_to finished ? "#" : resource_path, class: "p-4" do %> +

+ <%= decidim_escape_translated(title) %> +

+ <% if voted? %> + <%= icon "check-double-line", class: "inline-block align-middle fill-success ml-2 h-[1.5em] w-[1.5em]" %> + <% end %> +
+ <%= decidim_sanitize html_truncate(translated_attribute(description), length: 70) %> +
+ <% unless voted? %> +
+ <%= render :projects_count %> + <%= render :vote_action if voting_context? %> +
+ <% end %> + <% end %> + <% if voted? %> +
+ <%= render :projects_count %> + <%= render :vote_action if voting_context? %> +
+ <% end %> +
+ <% if voting_context? %> + <%= link_to finished ? "#" : resource_path, class: "budget__card__highlight-vote" do %> +
+ + <%= t("name", scope: "decidim.budgets.admin.models.budget") %> + + + <%= budget_to_currency(total_budget) %> + +
+ <% if finished %> + + <% else %> + <%= button_tag class: "button button__sm #{button_class} #{voted? ? "button__transparent-secondary" : "button__secondary"} budget__card__highlight-vote__button" do %> + <%= button_text %> + <%= icon "arrow-right-line" %> + <% end %> + <% end %> + <% end %> + <% end %> +
diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb deleted file mode 100644 index 6f14377f..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budget_list_item/showx.erb +++ /dev/null @@ -1,134 +0,0 @@ - - -
-
- <%= link_to resource_path, class: "p-4" do %> -

- <%= decidim_escape_translated(title) %> -

- <% if voted? %> - <%= icon "check-double-line", class: "inline-block align-middle fill-success ml-2 h-[1.5em] w-[1.5em]" %> - <% end %> -
- <%= decidim_sanitize html_truncate(translated_attribute(description), length: 70) %> -
- <% unless voted? %> -
- <%= render :projects_count %> - <%= render :vote_action if voting_context? %> -
- <% end %> - <% end %> - <% if voted? %> -
- <%= render :projects_count %> - <%= render :vote_action if voting_context? %> -
- <% end %> -
- <% if voting_context? %> - <%= link_to resource_path, class: "budget__card__highlight-vote" do %> -
- - <%= t("name", scope: "decidim.budgets.admin.models.budget") %> - - - <%= budget_to_currency(total_budget) %> - -
- <%= button_tag class: "button button__sm #{button_class} #{voted? ? "button__transparent-secondary" : "button__secondary"} budget__card__highlight-vote__button" do %> - <%= button_text %> - <%= icon "arrow-right-line" %> - <% end %> - <% end %> - <% end %> -
diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/voted.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/voted.erb new file mode 100644 index 00000000..b9895a08 --- /dev/null +++ b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/voted.erb @@ -0,0 +1,16 @@ +<% if voted? %> + <% if voted_all_budgets? %> +

<%= t(:voted_on_all_allowed, scope: i18n_scope, links: budgets_link_list(voted)) %>

+ <% else %> +

<%= t(:voted_on, scope: i18n_scope, links: budgets_link_list(voted)) %>

+ <% end %> +
+ <% voted.each do |budget| %> + <%= cell("decidim/budgets/budget_list_item", budget) %> + <% end %> +
+ + <% if finished? %> +

<%= t(:finished_message, scope: i18n_scope) %>

+ <% end %> +<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb index 3c153a50..e533c40f 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb @@ -1,13 +1,12 @@ -

<%= t("title", scope: "decidim.budgets.voting.vote_completed_modal") %>

-
-
+
<%= vote_completed_content %>
diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgetsx_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb similarity index 63% rename from decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgetsx_controller_extensions.rb rename to decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb index 1e3226c8..f752d337 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgetsx_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb @@ -8,12 +8,13 @@ module BudgetsControllerExtensions included do layout :determine_layout - before_action :ensure_authenticated, if: :open_and_voting_booth_forced? - before_action :ensure_user_zip_code, if: :open_and_voting_booth_forced? - before_action :ensure_multiple_budgets, unless: :open_and_voting_booth_forced? - def index + #before_action :ensure_authenticated, if: :open_and_voting_booth_forced? + #before_action :ensure_user_zip_code, if: :open_and_voting_booth_forced? + #before_action :ensure_multiple_budgets, unless: :open_and_voting_booth_forced? + + #def index # we need to redefine this action to avoid redirect in case of single budget - end + #end private @@ -32,8 +33,8 @@ def open_and_voting_booth_forced? end def layout - #"layouts/decidim/application" - current_participatory_space_manifest.context(current_participatory_space_context).layout + "layouts/decidim/application" + #current_participatory_space_manifest.context(current_participatory_space_context).layout end end end diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index 6db0122c..e2f5d83d 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -26,7 +26,11 @@ def completed_vote_snippets HTML ) - snippets.add(:head, helpers.javascript_pack_tag("decidim_handle_voting_complete")) + # snippets.add(:head, helpers.javascript_pack_tag("decidim_handle_voting_complete")) + snippets.add(:head, <<~HTML + + HTML + ) end end end diff --git a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb index 9c8cbf92..03f014e3 100644 --- a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb +++ b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb @@ -65,9 +65,9 @@ def voting_booth_forced? current_workflow.try(:voting_booth_forced?) end - def voting_terms - translated_attribute(component_settings.try(:voting_terms)).presence - end + #def voting_terms + # translated_attribute(component_settings.try(:voting_terms)).presence + #end def toggle_view_mode_link(current_mode, target_mode, title, params) path = budget_projects_path(params.permit(:order, filter: {}).merge({ view_mode: target_mode })) diff --git a/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb b/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb index 620c5e47..d9dcb834 100644 --- a/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb +++ b/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb @@ -15,13 +15,14 @@ def zip_code_length # want to candel the user_data entering, and they don't have a zip code. otherwise we # get into infinit redirect loop, since the budgets index path redirects users # to this view if they dont have a zip code. - def cancel_redirect_path - if user_zip_code - decidim_budgets.budgets_path - else - decidim.root_path - end - end + + #def cancel_redirect_path + # if user_zip_code + # decidim_budgets.budgets_path + # else + # decidim.root_path + # end + #end end end end diff --git a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_budgets.js b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_budgets.js index 22144b64..db8970de 100644 --- a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_budgets.js +++ b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_budgets.js @@ -1 +1,2 @@ import "src/decidim/budgets_booth/handle_thanks_session" + diff --git a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js index c956c266..d1b250ef 100644 --- a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js +++ b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_voting.js @@ -1,8 +1,8 @@ //import initializeProjects from "src/decidim/budgets_booth/projects" //import "src/decidim/budgets_booth/progressFixed" -//import "src/decidim/budgets_booth/exit_handler" +import "src/decidim/budgets_booth/exit_handler" import "src/decidim/budgets_booth/popup_selected_project" -$(() => { - initializeProjects(); -}); +//$(() => { +// initializeProjects(); +//}); diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exitX_handler.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exit_handler.js similarity index 71% rename from decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exitX_handler.js rename to decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exit_handler.js index b0c20aa2..d2e2224a 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exitX_handler.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/exit_handler.js @@ -9,7 +9,7 @@ const isSafeUrl = (exitUrl) => { } const safeUrls = [ - $(".budget-summary").attr("data-safe-url").split("?")[0], + $(".budget-summary").attr("data-safe-url").replace(location.origin, ""), `${location.pathname}#`, `${location.href}#`, "#" @@ -18,7 +18,7 @@ const isSafeUrl = (exitUrl) => { let safe = false; safeUrls.forEach((url) => { if (exitUrl.startsWith(url)) { - safe = true + safe = true } }); @@ -36,20 +36,32 @@ const allowExitFrom = ($el) => { return true; } else if ($el.attr("id") === "exit-notification-link") { return true; - } else if ($el.parents(".voting-wrapper").length > 0) { + } else if ($el.parents("main").length > 0) { return true; } else if (isSafeUrl($el.attr("href"))) { return true + } else if (document.querySelector(".panel-container") && document.querySelector(".panel-container").contains($el[0])) { + return true } return false; } - +$(function(){ + const $link = $('.menu-bar__exit-link'); + if ($link.attr("href").substring(0, 4) == "http"){ + return; + } else if ($link.attr("href")[0] == "/") { + $link.attr("href", window.location.origin + $link.attr("href")); + } else { + $link.attr("href", window.location.origin + "/" + $link.attr("href")); + } +}); $(() => { const $exitNotification = $("#exit-notification"); const $exitLink = $("#exit-notification-link"); const defaultExitUrl = $exitLink.attr("href"); const defaultExitLinkText = $exitLink.text(); + const signOutPath = window.Decidim.config.get("sign_out_path"); let exitLinkText = defaultExitLinkText; if ($exitNotification.length < 1) { @@ -63,26 +75,25 @@ $(() => { } else { $exitLink.removeAttr("data-method"); } - $exitLink.attr("href", url); - $exitLink.html(exitLinkText); - $exitNotification.foundation("open"); + $exitLink.text(exitLinkText); + window.Decidim.currentDialogs["exit-notification"].open(); }; $(document).on("click", "a", (event) => { exitLinkText = defaultExitLinkText; - const $link = $(event.currentTarget); + if (!allowExitFrom($link)) { event.preventDefault(); openExitNotification($link.attr("href"), $link.data("method")); } }); - // Custom handling for the header sign out so that it won't trigger the + // Custom handling for the header sign out so that it will not trigger the // logout form submit and so that it changes the exit link text. This does // not trigger the document link click listener because it has the // data-method attribute to trigger a form submit event. - $(".header a.sign-out-link").on("click", (event) => { + $(`[href='${signOutPath}']`).on("click", (event) => { event.preventDefault(); event.stopPropagation(); @@ -93,7 +104,7 @@ $(() => { // Custom handling for the exit link which needs to change the exit link // text to the default text as this is not handled by the document click // listener. - $("a[data-open='exit-notification']").on("click", () => { + $("a[data-dialog-open='exit-notification']").on("click", () => { exitLinkText = defaultExitLinkText; openExitNotification(defaultExitUrl); }); diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js index 51594f16..37075533 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js @@ -1,7 +1,9 @@ $(() => { const $modal = $("#thanks-message"); - + console.log(`bool: ${Boolean($modal)}`) + console.log(`session: ${$modal.attr("data-session") === "true"}`) if (Boolean($modal) && $modal.attr("data-session") === "true") { $modal.foundation("open"); } }); + diff --git a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss index d6015067..34418e37 100644 --- a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss +++ b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss @@ -197,6 +197,16 @@ $active-item-color: black; justify-content:space-between; align-items:center; } +@media (max-width: 1366px) { + .budget__card__grid-project { + flex-direction: column; + } +} +.card__list > .budget__card__list-project{ + display:flex; + flex-direction: column; + place-items: center; +} .budget__card__grid-project__amount { margin-bottom: 0.5rem; display: inline-block; @@ -214,11 +224,11 @@ $active-item-color: black; font-weight: 600; } .budget-summary__new-container { - margin-top:2rem; position:sticky; bottom:0; + z-index: 20; } - #project-item{ +#project-item{ &.project-show .budget-summary__content { max-width: 100vw; } @@ -240,10 +250,7 @@ $active-item-color: black; display:flex; flex-direction:column; } -.project-show__budget-summary { - position:sticky; - top:0; -} + #menu-bar-custom { justify-content: flex-start; padding-left: 2rem; @@ -286,3 +293,73 @@ $active-item-color: black; cursor: pointer; margin-right: 0.5em; } +//.reveal-overlay { +// display: none; +// position: absolute; +// top: 50%; +// left: 50%; +// transform: translate(-50%, -50%); +// z-index: 30; +// background-color: lightgrey; +// height: -moz-fit-content; +// height: fit-content; +// max-height: 95vh; +// width: 90%; +//} +.reveal-overlay { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1005; + display: none; + background-color: rgba(26, 24, 29, 0.45); + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} +.reveal { + z-index: 1006; + backface-visibility: hidden; + display: none; + padding: 1rem; + border: 1px solid #e8e8e8; + border-radius: 4px; + background-color: #fafafa; + position: relative; + top: 100px; + margin-right: auto; + margin-left: auto; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + width: 600px; + max-width: 75rem; + right: auto; + left: auto; + margin: 0 auto; +} + +#thanks-message, #vote-completed { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 20px 0; + font-size: 18px; + + button { + padding: 10px; + } + .text-content { + margin: 10px 0; + } +} +.reveal__header{ + display: flex; + align-items: center; + justify-content: center; + + h4 { + font-weight: bold; + } +} diff --git a/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb new file mode 100644 index 00000000..a4b1644e --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb @@ -0,0 +1,39 @@ + + +<% add_decidim_page_title component_name %> +<%= append_javascript_pack_tag "decidim_budgets" %> +<%= append_stylesheet_pack_tag "decidim_budgets", media: "all" %> +<%#= append_javascript_pack_tag "decidim_handle_voting_complete" %> + +<% content_for :aside do %> +

<%= component_name %>

+<% end %> + +<%= render layout: "layouts/decidim/shared/layout_two_col" do %> + <%= render partial: "decidim/shared/component_announcement" %> + + <% if current_workflow.budgets.empty? %> + <%= cell("decidim/announcement", t("empty", scope: "decidim.budgets.budgets_list")) %> + <% end %> + +
+ <%= cell("decidim/budgets/budgets_header", current_workflow) %> +
+ +
+ <%= cell("decidim/budgets/budgets_list", current_workflow) %> +
+<% end %> +<%= render partial: "decidim/budgets/voting/thanks_message_modal" if vote_success_content.present? && !voted_all_budgets? %> +<% handle_thanks_popup %> +<%= append_javascript_pack_tag "decidim_budgets_booth_budgets" %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb deleted file mode 100644 index cb4bf33c..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/budgets/indexX.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -<%= render partial: "decidim/shared/component_announcement" %> - -<%= cell("decidim/budgets/budgets_header", current_workflow) %> - -<%= cell("decidim/budgets/budgets_list", current_workflow) %> - -<%= render partial: "decidim/budgets/voting/thanks_message_modal" if vote_success_content.present? && !voted_all_budgets? %> -<% handle_thanks_popup %> -<%= javascript_pack_tag("decidim_budgets_booth_budgets") %> - - diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_exit_modal.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_exit_modal.html.erb new file mode 100644 index 00000000..bb2275e6 --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_exit_modal.html.erb @@ -0,0 +1,19 @@ +<% if current_user && current_component.current_settings.votes == "enabled" && !current_workflow.voted?(budget) %> + <%= decidim_modal id: "exit-notification" do %> +
+ <%= icon "information-line" %> +

+ <%= t("title", scope: "decidim.budgets.projects.exit_modal") %> +

+

+ <%= t("message", scope: "decidim.budgets.projects.exit_modal") %> +

+
+
+ + <%= link_to t("exit", scope: "decidim.budgets.projects.exit_modal"), cancel_redirect_path, id: "exit-notification-link", class: "button button__sm md:button__lg button__secondary" %> +
+ <% end %> +<% end %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb index 14771c98..eda578d1 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb @@ -1,48 +1,53 @@ -
- <% add_decidim_page_title t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %> - <%= append_javascript_pack_tag "decidim_budgets" %> - <%= append_stylesheet_pack_tag "decidim_budgets" %> +<% add_decidim_meta_tags( + description: translated_attribute(budget.description), + title: t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)), + url: budget_url(budget), + resource: budget) %> - <%= render layout: "decidim/shared/custom_filters", locals: { filter_sections: , search_variable: :search_text_cont, skip_to_id: "projects" } do %> +<%= append_javascript_pack_tag "decidim_budgets" %> +<%= append_javascript_pack_tag "decidim_budgets_booth_voting" %> +<%= append_stylesheet_pack_tag "decidim_budgets" %> + +<%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: true } %> +<%= cell("decidim/budgets/budget_information_modal", budget) %> + +<% content_for :aside do %> +

<%= t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %>

+ + <%= render layout: "decidim/shared/filters", locals: { filter_sections: , search_variable: :search_text_cont, skip_to_id: "projects" } do %> <%= hidden_field_tag :order, order, id: nil, class: "order_filter" %> <% end %> - <%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: true } %> - <%= cell("decidim/budgets/budget_information_modal", budget) %> -
- <% content_for :aside do %> -

<%= t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %>

- <% end %> +<% end %> - <% if projects.any? %> - <%= render partial: "exit_modal" %> - <%= render partial: "budget_excess" %> - <%= render partial: "budget_confirm" %> +<%= render layout: "layouts/decidim/shared/layout_two_col" do %> + <% if projects.any? %> + <%= render partial: "exit_modal" %> + <%= render partial: "budget_excess" %> + <%= render partial: "budget_confirm" %> - <%= cell("decidim/budgets/limit_announcement", budget) %> -
-
-

Projects for Vote

-
- <%= render partial: "order" %> -
- + <%= cell("decidim/budgets/limit_announcement", budget) %> +
+
+

Projects for Vote

+
+ <%= render partial: "order" %> +
+
- -
- <%= render partial: "projects" %> -
- <% else %> - <%= cell("decidim/announcement", t("empty", scope: "decidim.budgets.projects")) %> - <% end %> -
- <% unless voting_finished? %> - -
- <%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: false } %>
+ +
+ <%= render partial: "projects" %> +
+ <% else %> + <%= cell("decidim/announcement", t("empty", scope: "decidim.budgets.projects")) %> <% end %> -
+<% end %> +<% unless voting_finished? %> +
+ <%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: false } %> +
+<% end %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb index ca8eda5d..66d36830 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/show.html.erb @@ -17,11 +17,11 @@ <%= render partial: "exit_modal" %> -
+
<%= render partial: "budget_summary", locals: { include_heading: true, project_item: true, responsive: true } %> <% content_for :item_header do %> <% unless voting_finished? %> -
+
<%= render partial: "budget_summary", locals: { include_heading: true, project_item: true, responsive: false } %>
<%= render partial: "budget_excess" %> @@ -97,5 +97,4 @@ <% end %> <% end %> -
diff --git a/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb index c6cb3e8b..32e7e206 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb @@ -1,9 +1,9 @@

<%= t(".title") %>

-
<% unless current_workflow.try(:hide_image_in_popup?) %>
@@ -14,7 +14,7 @@
<% end %> -
+
<%= vote_success_content %>
@@ -25,3 +25,5 @@
+ + diff --git a/decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb b/decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb deleted file mode 100644 index f8e6aa3c..00000000 --- a/decidim-budgets_booth/app/views/decidim/shared/_custom_filters.html.erb +++ /dev/null @@ -1,55 +0,0 @@ -<% filter_sections = [] unless local_assigns.has_key?(:filter_sections) %> -<% search_label = t("decidim.searches.filters.search") unless local_assigns.has_key?(:search_label) %> - -<% if filter_sections.present? || local_assigns.has_key?(:search_variable) %> - <%= filter_form_for filter, url_for, class: "new_filter self-stretch", style: "width:90vw;margin:0 auto", data: { filters: "", component: "accordion" } do |form| %> - - - - - - <% end %> -<% end %> - diff --git a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb index ad493d54..bbf5c448 100644 --- a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb +++ b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb @@ -2,12 +2,13 @@ + diff --git a/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb index 4403e8df..4e301859 100644 --- a/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb +++ b/decidim-budgets_booth/app/views/layouts/decidim/shared/_layout_item.html.erb @@ -1,4 +1,4 @@ -
+
<%= yield :item_header %>
diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 420c8f20..0b8655db 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -28,6 +28,7 @@ en: no_budgets_found: No budgets were found based on your ZIP code. You can change your ZIP code if it's not correct, or you can search again later. vote: Show + voted_on_all_allowed: You have voted on %{links}. You have voted on the maximum budgets allowed. orders: modal: assigned: 'Assigned: ' diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 4ca6184f..6ad5d42c 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -27,6 +27,7 @@ fr: budgets_list: no_budgets_found: Aucun budget n'a été trouvé en fonction de votre code postal. Vous pouvez modifier votre code postal si il est incorrect. vote: Afficher + voted_on_all_allowed: Vous avez voté sur %{links}. Vous avez voté pour le maximum de budgets autorisé. orders: modal: assigned: 'Attribuer: ' diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb index a1aac56f..4a639ab1 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb @@ -47,9 +47,9 @@ class Engine < ::Rails::Engine ) # Cells extensions - Decidim::Budgets::ProjectVotedHintCell.include( - Decidim::BudgetsBooth::ProjectVotedHintCellExtensions - ) + #Decidim::Budgets::ProjectVotedHintCell.include( + # Decidim::BudgetsBooth::ProjectVotedHintCellExtensions + #) Decidim::Budgets::ProjectVoteButtonCell.include( Decidim::BudgetsBooth::ProjectVoteButtonCellExtensions ) @@ -58,13 +58,13 @@ class Engine < ::Rails::Engine # Decidim::BudgetsBooth::ProjectListItemExtensions #) - Decidim::Budgets::BudgetListItemCell.include( - Decidim::BudgetsBooth::BudgetListItemCellExtensions - ) + #Decidim::Budgets::BudgetListItemCell.include( + # Decidim::BudgetsBooth::BudgetListItemCellExtensions + #) - Decidim::Budgets::BudgetsHeaderCell.include( - Decidim::BudgetsBooth::BudgetsHeaderCellExtensions - ) + #Decidim::Budgets::BudgetsHeaderCell.include( + # Decidim::BudgetsBooth::BudgetsHeaderCellExtensions + #) Decidim::Budgets::BudgetsListCell.include( Decidim::BudgetsBooth::VotingSupport ) @@ -84,9 +84,9 @@ class Engine < ::Rails::Engine Decidim::BudgetsBooth::OrdersControllerExtensions ) - #Decidim::Budgets::BudgetsController.include( - # Decidim::BudgetsBooth::BudgetsControllerExtensions - #) + Decidim::Budgets::BudgetsController.include( + Decidim::BudgetsBooth::BudgetsControllerExtensions + ) Decidim::Budgets::ProjectsController.include( Decidim::BudgetsBooth::ProjectsControllerExtensions @@ -133,10 +133,10 @@ class Engine < ::Rails::Engine settings.attribute :maximum_budgets_to_vote_on, type: :integer, default: 0 settings.attribute :vote_success_content, type: :text, translated: true, editor: true settings.attribute :vote_completed_content, type: :text, translated: true, editor: true - settings.attribute :voting_terms, type: :text, translated: true, editor: true + #settings.attribute :voting_terms, type: :text, translated: true, editor: true settings.attribute :vote_success_url, type: :string settings.attribute :vote_cancel_url, type: :string - settings.attribute :show_full_description_on_listing_page, type: :boolean, default: false + #settings.attribute :show_full_description_on_listing_page, type: :boolean, default: false end end From c8e011a10d8ac5e36f6a90aaf9fc71fc8fac24ee Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 19 Nov 2024 16:08:35 +0100 Subject: [PATCH 03/93] feat: delete unused files, and update other files accordingly --- .../budget_list_item_cell_extensions.rb | 52 ------ .../budgets_header_cell_extensions.rb | 15 -- .../project_list_item_extensions.rb | 35 ---- .../project_voted_hint_cell_extensions.rb | 18 -- .../decidim/budgets/budgets_header/showx.erb | 50 ------ .../budgets/budgets_list/card_listx.erb | 51 ------ .../decidim/budgets/budgets_list/showx.erb | 63 ------- .../project_list_item/project_data.erb | 23 --- .../project_list_item/project_text.erb | 45 ----- .../project_list_item/selected_button_tag.erb | 1 - .../decidim/budgets/create_user_data.rb | 52 ------ .../line_items_controller_extensions.rb | 27 --- .../decidim/budgets/user_data_controller.rb | 67 -------- .../decidim/budgets/voting_controller.rb | 60 ------- .../forms/decidim/budgets/user_data_form.rb | 17 -- .../decidim/budgets/user_data_helper.rb | 28 ---- .../budgets_booth/component_extensions.rb | 15 -- .../decidim/budgets_booth/scope_extensions.rb | 22 --- .../decidim/budgets_booth/user_extensions.rb | 15 -- .../app/models/decidim/budgets/user_data.rb | 13 -- .../decidim_budgets_booth_zip_code.js | 1 - .../src/decidim/budgets/progressXFixed.js | 3 - .../packs/src/decidim/budgets/projectsX.js | 3 - .../decidim/budgets_booth/progressFixedX.js | 23 --- .../src/decidim/budgets_booth/projectsX.js | 53 ------ .../src/decidim/budgets_booth/zip_coder.js | 149 ----------------- .../decidim/budgets/budgets/index.html.erb | 13 -- .../budgets/line_items/update_budget.js.erb | 4 + .../projects/_budgetx_confirm.html.erb | 42 ----- .../budgets/projects/_budgetx_excess.html.erb | 14 -- .../projects/_budgetx_summary.html.erb | 69 -------- .../decidim/budgets/user_data/new.html.erb | 66 -------- decidim-budgets_booth/config/assets.rb | 1 - .../lib/decidim/budgets_booth.rb | 7 +- .../lib/decidim/budgets_booth/engine.rb | 40 ----- .../decidim/budgets_booth/scope_manager.rb | 156 ------------------ .../lib/decidim/budgets_booth/workflows.rb | 3 - .../budgets_booth/workflows/zip_code.rb | 53 ------ 38 files changed, 5 insertions(+), 1364 deletions(-) delete mode 100644 decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb delete mode 100644 decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budgets_header_cell_extensions.rb delete mode 100644 decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb delete mode 100644 decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_voted_hint_cell_extensions.rb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_data.erb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_text.erb delete mode 100644 decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/selected_button_tag.erb delete mode 100644 decidim-budgets_booth/app/commands/decidim/budgets/create_user_data.rb delete mode 100644 decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/line_items_controller_extensions.rb delete mode 100644 decidim-budgets_booth/app/controllers/decidim/budgets/user_data_controller.rb delete mode 100644 decidim-budgets_booth/app/controllers/decidim/budgets/voting_controller.rb delete mode 100644 decidim-budgets_booth/app/forms/decidim/budgets/user_data_form.rb delete mode 100644 decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb delete mode 100644 decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/component_extensions.rb delete mode 100644 decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/scope_extensions.rb delete mode 100644 decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/user_extensions.rb delete mode 100644 decidim-budgets_booth/app/models/decidim/budgets/user_data.rb delete mode 100644 decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_zip_code.js delete mode 100644 decidim-budgets_booth/app/packs/src/decidim/budgets/progressXFixed.js delete mode 100644 decidim-budgets_booth/app/packs/src/decidim/budgets/projectsX.js delete mode 100644 decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixedX.js delete mode 100644 decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projectsX.js delete mode 100644 decidim-budgets_booth/app/packs/src/decidim/budgets_booth/zip_coder.js delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_confirm.html.erb delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_summary.html.erb delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/user_data/new.html.erb delete mode 100644 decidim-budgets_booth/lib/decidim/budgets_booth/scope_manager.rb delete mode 100644 decidim-budgets_booth/lib/decidim/budgets_booth/workflows.rb delete mode 100644 decidim-budgets_booth/lib/decidim/budgets_booth/workflows/zip_code.rb diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb deleted file mode 100644 index 11790dbe..00000000 --- a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budget_list_item_cell_extensions.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module BudgetListItemCellExtensions - extend ActiveSupport::Concern - include VotingSupport - - included do - delegate :voting_open?, :voting_finished?, to: :controller - - #def button_text - # t(:vote, scope: i18n_scope) - #end - - def mark_image_as_voted(budget) - return nil unless voted_this?(budget) - - return nil unless voting_open? - - " voted-budget" - end - - def link_to_budget(budget, **options) - link_options = options - - link_target = - if voting_open? && !voted_this?(budget) - budget_voting_index_path(budget) - elsif voting_open? && voted_this?(budget) - link_options[:remote] = true - decidim_budgets.budget_order_path(budget) - else - budget_projects_path(budget) - end - - link_to link_target, **link_options do - yield - end - end - - def generate_text_for(budget) - if voted_this?(budget) - t("decidim.budgets.budget_list_item.show_my_vote") - else - t("decidim.budgets.budget_list_item.more_info") - end - end - end - end - end -end diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budgets_header_cell_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budgets_header_cell_extensions.rb deleted file mode 100644 index e81b1183..00000000 --- a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/budgets_header_cell_extensions.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module BudgetsHeaderCellExtensions - extend ActiveSupport::Concern - include ::Decidim::BudgetsBooth::VotingSupport - - included do - delegate :voting_open?, :voting_finished?, :component_settings, :current_workflow, to: :controller - delegate :user_zip_code, to: :current_workflow - end - end - end -end diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb deleted file mode 100644 index 15cf82ec..00000000 --- a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_list_item_extensions.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - # Customizes the project card cell - module ProjectListItemExtensions - extend ActiveSupport::Concern - delegate :current_workflow, to: :controller - - included do - def resource_text - return translated_attribute(model.description) if show_full_description? && voting_open? - - decidim_sanitize_editor html_truncate(translated_attribute(model.description), length: 65, separator: "...") - end - - def selected_budget - return unless can_have_order? && resource_added? - - "hollow" - end - - def voting_mode? - options[:voting_mode] - end - - private - - def show_full_description? - current_component.settings.show_full_description_on_listing_page == true - end - end - end - end -end diff --git a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_voted_hint_cell_extensions.rb b/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_voted_hint_cell_extensions.rb deleted file mode 100644 index e2ae6511..00000000 --- a/decidim-budgets_booth/app/cells/concerns/decidim/budgets_booth/project_voted_hint_cell_extensions.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module ProjectVotedHintCellExtensions - extend ActiveSupport::Concern - - included do - def css_class - css = ["text-success"] - css << options[:class] if options[:class] - css << "text-sm" unless options[:class]&.include?("text-m") - css.join(" ") - end - end - end - end -end diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb deleted file mode 100644 index a4de6e50..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_header/showx.erb +++ /dev/null @@ -1,50 +0,0 @@ -<% if voting_open? && voting_booth_forced? %> - <% unless voted_all_budgets? %> -
-
- <%= button_to cancel_redirect_path, class: "link margin-bottom-3", method: :get, data: { - confirm: t("actions.cancel_voting", scope: "decidim.budgets.budgets") - } do %> - <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %> - <%= t("cancel_voting", scope: "decidim.budgets.budgets.index") %> - <% end %> -
-
- <% end %> -
-
-
-

- <%= t("title", scope: "decidim.budgets.budgets_header") %> -

-

- <%= t("based_on_zip_code", scope: "decidim.budgets.budgets_header", zip_code: user_zip_code)%> - <% if !voted_any? %> - <%= t("not_right_one", scope: "decidim.budgets.budgets_header", link: link_to(t("change_it_here", scope: "decidim.budgets.budgets_header"), new_zip_code_path)) %> - <% end %> -

-
-
-
- <% if !voted_any? && landing_page_content.present? %> -
- <%= decidim_sanitize_editor(landing_page_content) %> -
- <% end %> -
-
-<% else %> -
-
-
- <%= decidim_sanitize_editor_admin(landing_page_content) %> -
- -
-
-<% end %> - diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb deleted file mode 100644 index 2b997cbf..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/card_listx.erb +++ /dev/null @@ -1,51 +0,0 @@ -<% if voting_booth_forced? %> - <% if budgets.none? %> -
-
- <%= t("no_budgets_found", scope: "decidim.budgets.budgets_list") %> -
-
- <% end %> - -
- <% if budgets.any? %> - <% budgets.each do |budget| %> - <% next if hide_unvoted?(budget) %> -
- <%= cell("decidim/budgets/budget_list_item", budget) %> -
- <% end %> - <% end %> -
-<% else %> - <%# show highlighted budgets first %> - <% if highlighted.any? %> - - <% reordered_highlighted_budgets.each do |budget| %> - <%= cell("decidim/budgets/budget_list_item", budget) %> - <% end %> - <% end %> - - <% non_highlighted = reorder(budgets).where.not(id: (highlighted + voted).map(&:id)) %> - - <% if non_highlighted.any? %> - - <% non_highlighted.each do |budget| %> - <%= cell("decidim/budgets/budget_list_item", budget) %> - <% end %> - <% end %> -<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb b/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb deleted file mode 100644 index b3f5d576..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/budgets_list/showx.erb +++ /dev/null @@ -1,63 +0,0 @@ -<% if voting_booth_forced? %> -
-
- <%= render :card_list %> -
-
- <% if voting_open? && voted? %> -
-
-

- <%= t(:if_change_opinion, scope: i18n_scope) %> - <%= link_to( - t("cancel_order.only_one", scope: i18n_scope), - budget_order_path(voted.first), - method: :delete, - data: { confirm: t("projects.budget_summary.are_you_sure", scope: "decidim.budgets") }) if voted.one? %> -

- <% if !voted.one? && voted.any? %> -
    - <% voted.each do |budget| %> -
  • - <%= link_to( - t("cancel_order.more_than_one", scope: i18n_scope, name: translated_attribute(budget.title)), - budget_order_path(budget), - method: :delete, - class: "cancel-order", - data: { - confirm: t("projects.budget_summary.are_you_sure", scope: "decidim.budgets") - } - ) %> -
  • - <% end %> -
- <% end %> -
-
- <% end %> -<% else %> -
-
- <% if !voting_finished? && (voted?) %> -
-

- <%= t(:my_budgets, scope: i18n_scope) %> -

- - <%= render :voted %> -
- <% end %> - -
- -
- <%= main_list %> -
-
-
-
-<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_data.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_data.erb deleted file mode 100644 index 28b60f56..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_data.erb +++ /dev/null @@ -1,23 +0,0 @@ -
" data-category="<%= model&.category&.id %>" > - <% if voting_finished? %> -
- <%= cell("decidim/budgets/project_votes_count", model) %> - - <%= cell("decidim/budgets/project_voted_hint", model, class: "display-block margin-top-1") %> -
- <% else %> -
- <%= render :selected_button_tag if resource_added? && current_order_checked_out? %> -
-
- - <%= budget_to_currency(model.budget_amount) %> - - <%= cell("decidim/budgets/project_votes_count", model, layout: :one_line, class: "display-inline-block") %> - - <%= cell("decidim/budgets/project_voted_hint", model, class: "display-block margin-top-1") if current_order_checked_out? && resource_added? %> - -
- <%= cell("decidim/budgets/project_vote_button", model) if !current_order_checked_out? && voting_open? && voting_mode? %> - <% end %> -
diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_text.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_text.erb deleted file mode 100644 index e985e1d0..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/project_text.erb +++ /dev/null @@ -1,45 +0,0 @@ - -
-
- <% if voting_open? %> - <% if show_full_description? %> -

- <%= resource_title %> -

- <% else %> -

- <% if voting_mode? %> - - <% else %> - <%= link_to resource_title, resource_path, class: "link" %> - <% end %> -

- <% end %> - <% else %> - <%= link_to resource_path, class: "link" do %> -

- <%= cell("decidim/budgets/project_selected_status", model) %> - <%= resource_title %> -

- <% end %> - <% end %> - -
- <%= resource_text %> -
- <%= cell("decidim/budgets/project_tags", model, context: { extra_classes: [" tags--project"] } ) %> - - <% if !show_full_description? %> - <% if voting_mode? %> - - <% else %> - <%= link_to t("read_more", scope: "decidim.budgets.project_list_item"), resource_path, class: "link" %> - <% end %> - <% end %> - -
-
diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/selected_button_tag.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/selected_button_tag.erb deleted file mode 100644 index 2bf212f7..00000000 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_list_item/selected_button_tag.erb +++ /dev/null @@ -1 +0,0 @@ -<%= icon "actions", class: "card--list__icon card--list__check", role: "img", aria_label: I18n.t("ordered_item", scope: "decidim.budgets.project_list_item") %> diff --git a/decidim-budgets_booth/app/commands/decidim/budgets/create_user_data.rb b/decidim-budgets_booth/app/commands/decidim/budgets/create_user_data.rb deleted file mode 100644 index cff2538a..00000000 --- a/decidim-budgets_booth/app/commands/decidim/budgets/create_user_data.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - class CreateUserData < Decidim::Command - def initialize(form, zip_codes) - @zip_codes = zip_codes - @form = form - end - - def call - return broadcast(:invalid) if form.invalid? - - return broadcast(:invalid, zip_code_not_exit) unless zip_code_included? - - create_user_data! - - broadcast(:ok) - end - - private - - attr_reader :form, :budget, :zip_codes - - def create_user_data! - attributes = { - metadata: { zip_code: form.zip_code }, - affirm_statements_are_correct: form.affirm_statements_are_correct - } - @user_data = Decidim::Budgets::UserData.find_or_create_by!( - user: form.user, - component: form.component - ) - - Decidim.traceability.update!( - @user_data, - form.user, - attributes, - visibility: "all" - ) - end - - def zip_code_included? - zip_codes.include?(form.zip_code) - end - - def zip_code_not_exit - I18n.t("zip_code_included", scope: "decidim.budgets.user_data.error") - end - end - end -end diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/line_items_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/line_items_controller_extensions.rb deleted file mode 100644 index 1eb9cede..00000000 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/line_items_controller_extensions.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -# Customizes the line items controller -module Decidim - module BudgetsBooth - module LineItemsControllerExtensions - extend ActiveSupport::Concern - - included do - before_action :set_help_modal - - helper Decidim::Budgets::VotingHelper - - private - - def set_help_modal - @show_help_modal = - if current_workflow.try(:disable_voting_instructions?) - false - else - Decidim::Budgets::Order.find_by(user: current_user, budget: budget).blank? - end - end - end - end - end -end diff --git a/decidim-budgets_booth/app/controllers/decidim/budgets/user_data_controller.rb b/decidim-budgets_booth/app/controllers/decidim/budgets/user_data_controller.rb deleted file mode 100644 index f50d5e0d..00000000 --- a/decidim-budgets_booth/app/controllers/decidim/budgets/user_data_controller.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - class UserDataController < ApplicationController - include FormFactory - include ::Decidim::BudgetsBooth::VotingSupport - - delegate :user_zip_code, to: :current_workflow - - layout "decidim/budgets/voting_layout" - before_action :ensure_voting_booth_forced - before_action :ensure_authenticated - before_action :ensure_voting_open - before_action :ensure_not_voted - - helper_method :user_zip_code - - def new - @form = form(UserDataForm).instance - @form.zip_code = user_zip_code - end - - def create - @invalid = false - @form = form(UserDataForm).from_params(params.merge(user: current_user, component: current_component)) - CreateUserData.call(@form, all_zip_codes) do - on(:ok) do - flash[:notice] = I18n.t("success", scope: "decidim.budgets.user_data") - redirect_to decidim_budgets.budgets_path - end - - on(:invalid) do |result| - invalidate_form if result.present? - flash.now[:alert] = I18n.t("unknown", scope: "decidim.budgets.user_data.error") - render action: "new" - end - end - end - - private - - def ensure_voting_open - return if voting_open? - - flash[:warning] = t("voting_ended", scope: "decidim.budgets.user_data.new") - redirect_to decidim.root_path - end - - def all_zip_codes - @all_zip_codes ||= scope_manager.zip_codes_for(current_component) - end - - def budgets - @budgets ||= Decidim::Budgets::Budget.where(component: current_component) - end - - def scope_manager - @scope_manager ||= ::Decidim::BudgetsBooth::ScopeManager.new(current_component) - end - - def invalidate_form - @invalid = true - end - end - end -end diff --git a/decidim-budgets_booth/app/controllers/decidim/budgets/voting_controller.rb b/decidim-budgets_booth/app/controllers/decidim/budgets/voting_controller.rb deleted file mode 100644 index 3d73fd7c..00000000 --- a/decidim-budgets_booth/app/controllers/decidim/budgets/voting_controller.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - class VotingController < ProjectsController - include Decidim::Budgets::NeedsCurrentOrder - include ::Decidim::BudgetsBooth::VotingSupport - - layout "decidim/budgets/voting_layout" - before_action :store_user_location!, if: :storable_location? - # The callback which stores the current location must be added before you authenticate the user - # as `authenticate_user!` (or whatever your resource is) will halt the filter chain and redirect - # before the location can be stored. - - before_action :ensure_voting_open! - before_action :ensure_authenticated - before_action :ensure_not_voted_this! - - def index - enforce_permission_to :vote, :project, project: budget.projects.first, budget: budget, workflow: current_workflow - end - - private - - delegate :voted?, to: :current_workflow - - # Its important that the location is NOT stored if: - # - The request method is not GET (non idempotent) - # - The request is handled by a Devise controller such as Devise::SessionsController as that could cause an - # infinite redirect loop. - # - The request is an Ajax request as this can lead to very unexpected behaviour. - def storable_location? - request.get? && is_navigational_format? && !devise_controller? && !request.xhr? - end - - def store_user_location! - # :user is the scope we are authenticating - store_location_for(:user, request.fullpath) - end - - def ensure_voting_open! - return if voting_open? - - flash[:warning] = I18n.t("not_open_warning", scope: "decidim.budgets.voting.general") - redirect_to decidim_budgets.budget_projects_path(budget) - end - - def ensure_not_voted_this! - return unless current_order.checked_out? - - flash[:warning] = I18n.t("not_allowed", scope: "decidim.budgets.budgets.index") - redirect_to decidim.root_path - end - - def decidim_budgets - @decidim_budgets ||= Decidim::EngineRouter.main_proxy(current_component) - end - end - end -end diff --git a/decidim-budgets_booth/app/forms/decidim/budgets/user_data_form.rb b/decidim-budgets_booth/app/forms/decidim/budgets/user_data_form.rb deleted file mode 100644 index e56617ee..00000000 --- a/decidim-budgets_booth/app/forms/decidim/budgets/user_data_form.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - class UserDataForm < Decidim::Form - attribute :zip_code, type: :string - attribute :affirm_statements_are_correct, type: :boolean - attribute :user, type: :string - attribute :component, type: :string - - validates :zip_code, presence: true - validates :affirm_statements_are_correct, acceptance: true - validates :user, presence: true - validates :component, presence: true - end - end -end diff --git a/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb b/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb deleted file mode 100644 index d9dcb834..00000000 --- a/decidim-budgets_booth/app/helpers/decidim/budgets/user_data_helper.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - module UserDataHelper - def voting_terms - translated_attribute(component_settings.try(:voting_terms)).presence - end - - def zip_code_length - ::Decidim::BudgetsBooth.zip_code_length.to_i - end - - # we need to redirect user to the root path if they - # want to candel the user_data entering, and they don't have a zip code. otherwise we - # get into infinit redirect loop, since the budgets index path redirects users - # to this view if they dont have a zip code. - - #def cancel_redirect_path - # if user_zip_code - # decidim_budgets.budgets_path - # else - # decidim.root_path - # end - #end - end - end -end diff --git a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/component_extensions.rb b/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/component_extensions.rb deleted file mode 100644 index dadfb303..00000000 --- a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/component_extensions.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require "active_support/concern" - -module Decidim - module BudgetsBooth - module ComponentExtensions - extend ActiveSupport::Concern - - included do - has_many :budgets_user_data, foreign_key: "decidim_component_id", class_name: "Decidim::Budgets::UserData", dependent: :destroy - end - end - end -end diff --git a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/scope_extensions.rb b/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/scope_extensions.rb deleted file mode 100644 index 6d9627e0..00000000 --- a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/scope_extensions.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require "active_support/concern" - -module Decidim - module BudgetsBooth - module ScopeExtensions - extend ActiveSupport::Concern - - included do - after_save :clear_budgets_booth_cache - after_destroy :clear_budgets_booth_cache - end - - private - - def clear_budgets_booth_cache - Decidim::BudgetsBooth::ScopeManager.clear_cache! - end - end - end -end diff --git a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/user_extensions.rb b/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/user_extensions.rb deleted file mode 100644 index bfd55d55..00000000 --- a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/user_extensions.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require "active_support/concern" - -module Decidim - module BudgetsBooth - module UserExtensions - extend ActiveSupport::Concern - - included do - has_many :budgets_user_data, foreign_key: "decidim_user_id", class_name: "Decidim::Budgets::UserData", dependent: :destroy - end - end - end -end diff --git a/decidim-budgets_booth/app/models/decidim/budgets/user_data.rb b/decidim-budgets_booth/app/models/decidim/budgets/user_data.rb deleted file mode 100644 index 4df2645b..00000000 --- a/decidim-budgets_booth/app/models/decidim/budgets/user_data.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - class UserData < ApplicationRecord - include Decidim::RecordEncryptor - - encrypt_attribute :metadata, type: :hash - belongs_to :component, foreign_key: "decidim_component_id", class_name: "Decidim::Component" - belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User" - end - end -end diff --git a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_zip_code.js b/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_zip_code.js deleted file mode 100644 index 8f8849a1..00000000 --- a/decidim-budgets_booth/app/packs/entrypoints/decidim_budgets_booth_zip_code.js +++ /dev/null @@ -1 +0,0 @@ -import "src/decidim/budgets_booth/zip_coder" diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets/progressXFixed.js b/decidim-budgets_booth/app/packs/src/decidim/budgets/progressXFixed.js deleted file mode 100644 index 39239abd..00000000 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets/progressXFixed.js +++ /dev/null @@ -1,3 +0,0 @@ -// We are customizing this functionality at decidim/budgets_booth/projects.js -// which is why we have disabled the default functionality by overriding this -// file. diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets/projectsX.js b/decidim-budgets_booth/app/packs/src/decidim/budgets/projectsX.js deleted file mode 100644 index 39239abd..00000000 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets/projectsX.js +++ /dev/null @@ -1,3 +0,0 @@ -// We are customizing this functionality at decidim/budgets_booth/projects.js -// which is why we have disabled the default functionality by overriding this -// file. diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixedX.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixedX.js deleted file mode 100644 index 5b0f05d9..00000000 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/progressFixedX.js +++ /dev/null @@ -1,23 +0,0 @@ -$(() => { - const checkProgressPosition = () => { - let progressFix = document.querySelector("[data-progressbox-fixed]"), - progressRef = document.querySelector("[data-progress-reference]"), - progressVisibleClass = "is-progressbox-visible"; - - if (!progressRef || !progressFix) { - return; - } - - let progressPosition = progressRef.getBoundingClientRect().bottom; - if (progressPosition > 0) { - progressFix.classList.remove(progressVisibleClass); - } else { - progressFix.classList.add(progressVisibleClass); - } - } - - window.addEventListener("scroll", checkProgressPosition); - - window.DecidimBudgets = window.DecidimBudgets || {}; - window.DecidimBudgets.checkProgressPosition = checkProgressPosition; -}); diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projectsX.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projectsX.js deleted file mode 100644 index 28049f80..00000000 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/projectsX.js +++ /dev/null @@ -1,53 +0,0 @@ -const initializeProjects = () => { - const $projects = $("#projects, #project, .reveal.large"); - const $budgetSummaryTotal = $(".budget-summary__total"); - const $budgetExceedModal = $("#budget-excess"); - const $budgetSummary = $(".budget-summary__progressbox"); - const $voteButton = $(".budget-vote-button"); - const totalAllocation = parseInt($budgetSummaryTotal.attr("data-total-allocation"), 10); - - const cancelEvent = (event) => { - $(event.currentTarget).removeClass("loading-spinner"); - event.stopPropagation(); - event.preventDefault(); - }; - - $voteButton.on("click", "span", () => { - $(".budget-list__action").click(); - }); - - $projects.on("click", ".customized-budget", (event) => { - const currentAllocation = parseInt($budgetSummary.attr("data-current-allocation"), 10); - const $currentTarget = $(event.currentTarget); - const projectAllocation = parseInt($currentTarget.attr("data-allocation"), 10); - - - let $targetCategory = null; - const $targetCategoryId = $currentTarget.parents(".budget-list__data").first().data("categoryId"); - if ($targetCategoryId !== undefined) { - $targetCategory = $(`.vote_by_category[data-category-id=${$targetCategoryId}]`).first(); - } - - let quotaExceeded = ((currentAllocation + projectAllocation) > totalAllocation); - let categoryQuotaExceeded = false; - - if ($targetCategory && $targetCategory.length > 0) { - const currentCategoryAllocation = parseInt($targetCategory.attr("data-current-allocation"), 10); - const totalCategoryAllocation = parseInt($targetCategory.attr("data-allocation"), 10); - categoryQuotaExceeded = ((currentCategoryAllocation + projectAllocation) > totalCategoryAllocation || quotaExceeded); - } - - if ($currentTarget.attr("disabled")) { - cancelEvent(event); - } else if (($currentTarget.attr("data-add") === "true") && categoryQuotaExceeded === true) { - $(`#budget-excess-${$targetCategoryId}`).foundation("toggle"); - cancelEvent(event); - } else if (($currentTarget.attr("data-add") === "true") && quotaExceeded === true) { - $budgetExceedModal.foundation("toggle"); - cancelEvent(event); - } - }); -}; - - -export default initializeProjects; diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/zip_coder.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/zip_coder.js deleted file mode 100644 index 75f2061e..00000000 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/zip_coder.js +++ /dev/null @@ -1,149 +0,0 @@ -$(() => { - const zipcodeInputs = document.querySelectorAll('#zip-code input[type="text"]'); - const zipCodeNotValid = document.querySelector("#zip-code-not-valid"); - const zipCodeError = document.querySelector("#zip-code-error"); - const onlyLettersAllowed = document.querySelector("#only-letters-allowed"); - const submitBotton = document.querySelector("button[name='commit']"); - - const removeAllErrorMessages = () => { - document.querySelectorAll(".form-error").forEach((element) => { - if (element.classList.contains("is-visible")) { - element.classList.remove("is-visible") - element.classList.add("is-invisible") - } - }) - } - - const showErrorMessage = (element) => { - removeAllErrorMessages() - if (element.classList.contains("is-invisible")) { - element.classList.remove("is-invisible") - element.classList.add("is-visible") - } - } - const invalidField = (element) => { - zipcodeInputs.forEach((item) => { - if (!item.classList.contains("is-invalid-input")) { - item.classList.add("is-invalid-input") - } - }) - showErrorMessage(element) - } - - const resetField = () => { - zipcodeInputs.forEach((item) => { - if (item.classList.contains("is-invalid-input")) { - item.classList.remove("is-invalid-input") - } - }) - } - - const validUserInput = (val) => (/^[a-zA-Z0-9]+$/).test(val) - - // check if the hidden zip code input field has a value - const hiddenZipCodeField = document.querySelector('input[name="user_data[zip_code]"]'); - if (hiddenZipCodeField.value.trim() !== "") { - const zipCodeValue = hiddenZipCodeField.value.trim().split(""); - zipcodeInputs.forEach((input, index) => { - input.value = zipCodeValue[index] || ""; - }); - } - - if (zipCodeNotValid.dataset.invalid) { - zipcodeInputs.forEach((input) => { - input.classList.add("is-invalid-input") - }); - invalidField(zipCodeNotValid) - } - zipcodeInputs.forEach((input, ind) => { - input.setAttribute("maxlength", "1"); - input.addEventListener("click", () => { - resetField(); - input.select(); - }) - - input.addEventListener("paste", (event) => { - const clipboardData = event.clipboardData || window.clipboardData; - const pastedData = clipboardData.getData("text").trim(); - if (!validUserInput(pastedData)) { - invalidField(onlyLettersAllowed) - input.blur(); - input.classList.add("is-invalid-input"); - return - } - - // find the first empty input field and paste the data there - let jj = 0; - for (let ii = ind; ii < zipcodeInputs.length; ii += 1) { - if (jj > pastedData.length) { - return; - } - if (pastedData.substr(jj, 1)) { - zipcodeInputs[ii].value = pastedData.substr(jj, 1); - zipcodeInputs[ii].focus(); - jj += 1 - } - } - event.preventDefault(); - }); - input.addEventListener("keydown", function(event) { - const previousInput = zipcodeInputs[ind - 1]; - if (event.key === "Backspace") { - if (previousInput) { - previousInput.select(); - event.preventDefault(); - input.value = "" - } - } - }); - - input.addEventListener("input", () => { - const val = input.value - - if (!validUserInput(val)) { - input.value = "" - return - } - const nextInput = zipcodeInputs[ind + 1]; - if (nextInput) { - nextInput.select(); - } else { - let checkbox = document.querySelector("#user_data_affirm_statements_are_correct") - if (checkbox.checked) { - submitBotton.focus(); - } else { - checkbox.focus() - } - } - }) - }); - const fieldsvalid = () => { - let allFieldsFilled = true; - zipcodeInputs.forEach((input) => { - if (input.value.trim() === "") { - allFieldsFilled = false; - } - }); - return allFieldsFilled - }; - - const setZipcodeField = () => { - let combinedValue = ""; - zipcodeInputs.forEach((input) => { - combinedValue += input.value.trim(); - }); - document.querySelector('input[name="user_data[zip_code]"]').value = combinedValue - }; - - const form = document.querySelector(".new_user_data"); - $(form).on("submit", (ev) => { - removeAllErrorMessages() - setZipcodeField(); - if (fieldsvalid()) { - return; - } - - ev.preventDefault(); - invalidField(zipCodeError); - }); -}) diff --git a/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb index a4b1644e..71afa170 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/budgets/index.html.erb @@ -1,19 +1,6 @@ - - <% add_decidim_page_title component_name %> <%= append_javascript_pack_tag "decidim_budgets" %> <%= append_stylesheet_pack_tag "decidim_budgets", media: "all" %> -<%#= append_javascript_pack_tag "decidim_handle_voting_complete" %> <% content_for :aside do %>

<%= component_name %>

diff --git a/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb b/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb index 5ae12004..6738cb47 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb @@ -1,3 +1,4 @@ +var $orderSelectedProjectsCount = $('#order-selected-projects-count'); var $orderProgress = document.querySelectorAll('[id^=order-progress] .budget-summary__content'); var $projectItem = $('#project-<%= project.id %>-item'); var $projectVoteButton = $('.project-<%= project.id %>-vote-button'); @@ -14,6 +15,9 @@ $orderProgress.forEach((orderProgress) => { } }) morphdom($budgetConfirm[0], '<%= j(render partial: "decidim/budgets/projects/budget_confirm").strip.html_safe %>') +if ($orderSelectedProjectsCount.length > 0) { + morphdom($orderSelectedProjectsCount[0], '<%= j(render partial: "decidim/budgets/projects/projects_count", locals: { count: current_order.projects.size }).strip.html_safe %>') +} if ($projectItem.length > 0) { <% if params[:action] == "destroy" && params[:show_only_added] == "true" %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_confirm.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_confirm.html.erb deleted file mode 100644 index a7a86856..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_confirm.html.erb +++ /dev/null @@ -1,42 +0,0 @@ -
- <% if current_order.present? %> -
-

<%= t(".title") %>

- -
-

<%= t(".description") %>

-
-
    - <% current_order.projects.each do |project| %> -
  • - <%= translated_attribute(project.title) %> - - <%= budget_to_currency project.budget_amount %> - -
  • - <% end %> -
-
-

<%= t(".are_you_sure") %>

- - <% if !voting_booth_forced? && voting_terms.present? %> -

<%= t(".is_this_correct") %>

-
-
- <%== voting_terms %> -
-
- <% end %> - -
-
- <%= button_to t(".confirm"), checkout_budget_order_path(budget), class: "button expanded", data: { disable: true } %> -
-
-
- -
- <% end %> -
diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb deleted file mode 100644 index b464b60c..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_excess.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -
-
-

<%= current_order.projects_rule? ? t(".projects_excess.title") : t(".budget_excess.title") %>

- -
-

<%= current_order.projects_rule? ? t(".projects_excess.description") : t(".budget_excess.description") %>

-
-
- -
-
-
diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_summary.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_summary.html.erb deleted file mode 100644 index 47b16665..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_budgetx_summary.html.erb +++ /dev/null @@ -1,69 +0,0 @@ -
- <% if voting_mode? %> -
-
- -
-
- <% elsif budgets.count > 1 %> -
-
- <%= button_to(decidim_budgets.budgets_path, class: "link m-bottom", method: :get) do %> - <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %> - <%= t(".back_to_budgets") %> - <% end %> -
-
- <% end %> -
-<% if voting_mode? %> -
-
-

- <%= t(".choose_budget", budget_title: translated_attribute(budget.title)) %> -

-

- <%= t(".choose_description") %> -

- - <% if current_order.projects_rule? %> -
- <%= t(".total_projects") %> - - <%= current_order.maximum_projects %> - - -
- <% else %> -
- <%= t(".total_budget") %> - - <%= budget_to_currency(budget.total_budget) %> - - -
- <% end %> - - <%= render partial: "order_progress" %> - -
- - <%= t(".assigned") %> - <%= render partial: "order_total_budget" %> - -
-
- - <%= render partial: "order_selected_projects" %> -
-<% else %> - <% if current_order_checked_out? %> - <%= render partial: "pre_voting_budget_summary" %> - <% else %> - <%= render partial: "pre_voting_budget_summary" %> - <% end %> -<% end %> -<%= render partial: "budget_confirm" %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/user_data/new.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/user_data/new.html.erb deleted file mode 100644 index eb2b82f3..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/user_data/new.html.erb +++ /dev/null @@ -1,66 +0,0 @@ -
-
-

<%= t(".welcome", organization: current_organization.name).html_safe %>

-
-
- -
-
- - <%= button_to cancel_redirect_path, class: "link margin-bottom-1", method: :get, data: { - confirm: t("actions.cancel_zip_code", scope: "decidim.budgets.budgets") - } do %> - <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %> - <%= t("cancel", scope:"decidim.budgets.user_data.new") %> - <% end %> -
-
-
-
-

<%= t(".title") %>

-

<%= t(".description") %>

- <%= decidim_form_for(@form, url: zip_code_index_path, method: :post) do |form| %> -
-
-
-
- <% zip_code_length.times do |ind| %> -
- " autocomplete="off" aria-label="<%= t(".inputs", count: ind + 1) %>"> -
- <% end %> -
-
- - - -
- <%= form.hidden_field :zip_code, vlaue: @form.zip_code %> -
-
-
- <% if voting_terms.present? %> -
-
-
- <%= raw(voting_terms) %> -
-
-
- <% end %> - -
- <%= form.check_box :affirm_statements_are_correct, label: t(".affirm_statements"), required: true %> - <%= t(".must_be_accepted") %> -
-
-
- <%= form.submit t(".submit"), class:"button expanded" %> -
-
- <% end %> -
-
-
-
-<%= javascript_pack_tag "decidim_budgets_booth_zip_code" %> diff --git a/decidim-budgets_booth/config/assets.rb b/decidim-budgets_booth/config/assets.rb index 6513d41f..78aa5647 100644 --- a/decidim-budgets_booth/config/assets.rb +++ b/decidim-budgets_booth/config/assets.rb @@ -5,7 +5,6 @@ Decidim::Webpacker.register_path("#{base_path}/app/packs", prepend: true) Decidim::Webpacker.register_entrypoints( decidim_budgets_booth_voting: "#{base_path}/app/packs/entrypoints/decidim_budgets_booth_voting.js", - decidim_budgets_booth_zip_code: "#{base_path}/app/packs/entrypoints/decidim_budgets_booth_zip_code.js", decidim_budgets_booth_budgets: "#{base_path}/app/packs/entrypoints/decidim_budgets_booth_budgets.js", decidim_handle_voting_complete: "#{base_path}/app/packs/entrypoints/decidim_handle_voting_complete.js" ) diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth.rb b/decidim-budgets_booth/lib/decidim/budgets_booth.rb index f01ed2da..c3edeeeb 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth.rb @@ -1,18 +1,13 @@ # frozen_string_literal: true require "decidim/budgets_booth/engine" -require "decidim/budgets_booth/workflows" +#require "decidim/budgets_booth/workflows" module Decidim # This namespace holds the logic of the `BudgetsBooth` component. This component # allows users to create budgets_booth in a participatory space. module BudgetsBooth autoload :VotingSupport, "decidim/budgets_booth/voting_support" - autoload :ScopeManager, "decidim/budgets_booth/scope_manager" include ActiveSupport::Configurable - # Default configuration digits to generate the zip code. - config_accessor :zip_code_length do - 5 - end end end diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb index 4a639ab1..f157cf16 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb @@ -47,24 +47,10 @@ class Engine < ::Rails::Engine ) # Cells extensions - #Decidim::Budgets::ProjectVotedHintCell.include( - # Decidim::BudgetsBooth::ProjectVotedHintCellExtensions - #) Decidim::Budgets::ProjectVoteButtonCell.include( Decidim::BudgetsBooth::ProjectVoteButtonCellExtensions ) - #Decidim::Budgets::ProjectListItemCell.include( - # Decidim::BudgetsBooth::ProjectListItemExtensions - #) - - #Decidim::Budgets::BudgetListItemCell.include( - # Decidim::BudgetsBooth::BudgetListItemCellExtensions - #) - - #Decidim::Budgets::BudgetsHeaderCell.include( - # Decidim::BudgetsBooth::BudgetsHeaderCellExtensions - #) Decidim::Budgets::BudgetsListCell.include( Decidim::BudgetsBooth::VotingSupport ) @@ -92,32 +78,10 @@ class Engine < ::Rails::Engine Decidim::BudgetsBooth::ProjectsControllerExtensions ) - Decidim::Budgets::LineItemsController.include( - Decidim::BudgetsBooth::LineItemsControllerExtensions - ) - - # Commands extensions - Decidim::Budgets::Admin::CreateBudget.include( - Decidim::BudgetsBooth::CreateBudgetExtensions - ) - - Decidim::Budgets::Admin::UpdateBudget.include( - Decidim::BudgetsBooth::UpdateBudgetExtensions - ) - # Models extensions Decidim::Budgets::Budget.include( Decidim::BudgetsBooth::BudgetExtensions ) - Decidim::User.include( - Decidim::BudgetsBooth::UserExtensions - ) - Decidim::Component.include( - Decidim::BudgetsBooth::ComponentExtensions - ) - Decidim::Scope.include( - Decidim::BudgetsBooth::ScopeExtensions - ) # Forms extensions Decidim::Budgets::Admin::BudgetForm.include( @@ -139,10 +103,6 @@ class Engine < ::Rails::Engine #settings.attribute :show_full_description_on_listing_page, type: :boolean, default: false end end - - initializer "decidim_budgets.add_zip_code_workflow" do - Decidim::Budgets.workflows[:zip_code] = Decidim::BudgetsBooth::Workflows::ZipCode - end end end end diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/scope_manager.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/scope_manager.rb deleted file mode 100644 index 64770435..00000000 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/scope_manager.rb +++ /dev/null @@ -1,156 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - class ScopeManager - attr_reader :component, :top_scope - - class << self - # This method allows storing the scopes mappings locally so that they do - # not have to be re-fetched for the multiple instances of the - # ScopeManager class. - def scopes_mapping_for(scope) - scopes_mapping_cache[scope.id] ||= Rails.cache.fetch( - cache_key(scope.cache_key_with_version), - expires_in: 1.hour - ) { generate_scopes_mapping_for(scope) } - end - - # Allow clearing the cache, useful for the specs. - def clear_cache! - scopes_mapping_cache.keys.each do |id| - scope = Decidim::Scope.find(id) - Rails.cache.delete(cache_key(scope.cache_key_with_version)) - rescue ActiveRecord::RecordNotFound - # If the record was not found, cache key cannot be regenerated, so - # deleting the old cache record can be omitted. - end - @scopes_mapping_cache = {} - end - - private - - def cache_key_prefix - "decidim/budgets_booth/scopes_mapping" - end - - def cache_key(key) - "#{cache_key_prefix}/#{key}" - end - - # Stores the local cache of the scopes mappings. - def scopes_mapping_cache - @scopes_mapping_cache ||= {} - end - - # Generates the scopes mapping for the given top-level scope. - def generate_scopes_mapping_for(scope) - locale = scope.organization.default_locale - table = Decidim::Scope.table_name - connection = ActiveRecord::Base.connection - columns = "id, parent_id, code, name->>#{connection.quote(locale)} AS name" - topquery = "SELECT %columns% FROM #{table} WHERE parent_id = #{connection.quote(scope.id)}" - queries = [] - - # Maximum of 3 levels below the top scope: - # Boroughs -> Neighborhoods -> Postal codes - # - # The postal codes are defined at the deepest level regardless of the - # amount of levels. - subquery = topquery - 3.times do |i| - queries << subquery.sub("%columns%", "#{columns}, #{i} AS depth") - subquery = "SELECT %columns% FROM #{table} WHERE parent_id IN (#{subquery.sub("%columns%", "id")})" - end - - # Query all the levels and store the postal code mapping. Note that - # the order by depth is important for the further processing. The - # lowest depth needs to be processed first. - result = connection.select_all("#{queries.join(" UNION ALL ")} ORDER BY depth, name").to_a - - zip_codes_hash(scope, result) - end - - # Converts the multi-level query results into a flat hash which has the - # scope IDs as keys and their related ZIP codes as values. This approach - # allows quickly fetching the ZIP codes for each scope. - def zip_codes_hash(parent_scope, result) - max_depth = result.pluck("depth").max - parents = { parent_scope.id => [] } - - {}.tap do |mapping| - result.each do |item| - if item["depth"] == max_depth - # Postal code - mapping[item["parent_id"]] ||= [] - mapping[item["parent_id"]] << item["name"] - - each_item(parents, item["parent_id"]) do |parent_id| - mapping[parent_id] ||= [] - mapping[parent_id] << item["name"] - end - elsif item["depth"].positive? - parents[item["id"]] ||= [] - parents[item["id"]] << item["parent_id"] unless parents[item["id"]].include?(item["parent_id"]) - - each_item(parents, item["parent_id"]) do |parent_id| - parents[item["id"]] << parent_id unless parents[item["id"]].include?(parent_id) - end - end - end - end - end - - # This is a helper method to reduce the cyclomatic complexity of the - # `zip_codes_hash` method. - def each_item(parents, id) - return unless parents[id] - - parents[id].each { |parent_id| yield parent_id } - end - end - - def initialize(component) - @component = component - @top_scope = component.scope - end - - def zip_codes_for(resource) - return [] unless top_scope - - scope = scope_for(resource) - return [] if scope.blank? - return scopes_mapping.values.flatten.uniq if scope == top_scope - - scopes_mapping[scope.id]&.uniq || [] - end - - def user_zip_code(user) - return nil if user.blank? - - user_data_for(user)["zip_code"] - end - - private - - # Loads the metadata for a specific user from the user data records. If - # the cache clear method has been called after the user data was loaded - # (e.g. the data was deleted or updated at the same process), this will - # reload the data accordingly. - def user_data_for(user) - user_data = user.budgets_user_data.find_by(component: component) - user_data&.metadata || {} - end - - def scope_for(resource) - return resource if resource.is_a?(Decidim::Scope) - - resource.scope - end - - def scopes_mapping - self.class.scopes_mapping_for(top_scope) - end - end - end -end diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/workflows.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/workflows.rb deleted file mode 100644 index 004d1a75..00000000 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/workflows.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: true - -require_relative "workflows/zip_code" diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/workflows/zip_code.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/workflows/zip_code.rb deleted file mode 100644 index 8ef18c3f..00000000 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/workflows/zip_code.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module Workflows - # This is the zip_code Workflow class. - class ZipCode < ::Decidim::Budgets::Workflows::Base - # No budget is highlighted for this workflow - def highlighted?(_resource) - false - end - - def disable_voting_instructions? - true - end - - def hide_image_in_popup? - true - end - - # User can vote in the resource inside their area where they live. This is being determined - # by their zip code. - def vote_allowed?(resource, consider_progress: true) # rubocop:disable Lint/UnusedMethodArgument - return false if user_zip_code.blank? - - scope_manager.zip_codes_for(resource).include?(user_zip_code) - end - - def budgets - super.select { |item| vote_allowed?(item) } - end - - def voting_booth_forced? - true - end - - def user_zip_code - @user_zip_code ||= scope_manager.user_zip_code(user) - end - - private - - def scope_manager - @scope_manager ||= ::Decidim::BudgetsBooth::ScopeManager.new(budgets_component) - end - - def projects(budget) - Decidim::Budgets::Project.where(budget: budget) - end - end - end - end -end From 176ec54df576ef2b5e7f5ed44ed4aba24830fd02 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 19 Nov 2024 16:42:32 +0100 Subject: [PATCH 04/93] test: delete files not necessary anymore --- ...project_voted_hint_cell_extensions_spec.rb | 47 ------ .../decidim/budgets/create_user_data_spec.rb | 70 -------- .../budgets/user_data_controller_spec.rb | 88 ---------- .../decidim/budgets/voting_controller_spec.rb | 80 --------- .../decidim/budgets/user_data_form_spec.rb | 52 ------ .../budgets_booth/scope_manager_spec.rb | 159 ------------------ .../budgets_booth/workflows/zip_code_spec.rb | 91 ---------- .../models/decidim/budgets/user_data_spec.rb | 58 ------- .../spec/models/decidim/scope_spec.rb | 47 ------ 9 files changed, 692 deletions(-) delete mode 100644 decidim-budgets_booth/spec/cells/decidim/budgets_booth/project_voted_hint_cell_extensions_spec.rb delete mode 100644 decidim-budgets_booth/spec/commands/decidim/budgets/create_user_data_spec.rb delete mode 100644 decidim-budgets_booth/spec/controllers/decidim/budgets/user_data_controller_spec.rb delete mode 100644 decidim-budgets_booth/spec/controllers/decidim/budgets/voting_controller_spec.rb delete mode 100644 decidim-budgets_booth/spec/forms/decidim/budgets/user_data_form_spec.rb delete mode 100644 decidim-budgets_booth/spec/lib/decidim/budgets_booth/scope_manager_spec.rb delete mode 100644 decidim-budgets_booth/spec/lib/decidim/budgets_booth/workflows/zip_code_spec.rb delete mode 100644 decidim-budgets_booth/spec/models/decidim/budgets/user_data_spec.rb delete mode 100644 decidim-budgets_booth/spec/models/decidim/scope_spec.rb diff --git a/decidim-budgets_booth/spec/cells/decidim/budgets_booth/project_voted_hint_cell_extensions_spec.rb b/decidim-budgets_booth/spec/cells/decidim/budgets_booth/project_voted_hint_cell_extensions_spec.rb deleted file mode 100644 index bfab40d2..00000000 --- a/decidim-budgets_booth/spec/cells/decidim/budgets_booth/project_voted_hint_cell_extensions_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::BudgetsBooth::ProjectVotedHintCellExtensions do - let(:klass) do - Class.new do - include Decidim::BudgetsBooth::ProjectVotedHintCellExtensions - end - end - - before do - allow_any_instance_of(klass).to receive(:options).and_return(options) # rubocop:disable RSpec/AnyInstance - end - - describe "#css_class" do - context "when options[:class] is not present" do - let(:options) do - { class: nil } - end - - it "returns a string containing 'text-success'" do - expect(klass.new.css_class).to eq("text-success text-sm") - end - end - - context "when options[:class] is present" do - let(:options) do - { class: "my-class" } - end - - it "returns a string containing 'text-success'" do - expect(klass.new.css_class).to eq("text-success my-class text-sm") - end - end - - context "when options[:class] includes 'text-m'" do - let(:options) do - { class: "text-m" } - end - - it "does not add 'text-sm' to the returned string" do - expect(klass.new.css_class).to eq("text-success text-m") - end - end - end -end diff --git a/decidim-budgets_booth/spec/commands/decidim/budgets/create_user_data_spec.rb b/decidim-budgets_booth/spec/commands/decidim/budgets/create_user_data_spec.rb deleted file mode 100644 index 55c8352b..00000000 --- a/decidim-budgets_booth/spec/commands/decidim/budgets/create_user_data_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Budgets - describe CreateUserData do - subject { described_class.new(form, zip_codes) } - - let(:user) { create(:user, :confirmed, organization: component.organization) } - let(:affirm_statements_are_correct) { true } - let(:zip_codes) { %w(foo bar baz) } - let(:zip_code) { "" } - let(:component) do - create( - :budgets_component, - settings: { workflow: "zip_code" } - ) - end - - let(:form) do - double( - invalid?: invalid?, - user: user, - zip_code: zip_code, - affirm_statements_are_correct: affirm_statements_are_correct, - component: component - ) - end - - context "when invalid" do - let(:invalid?) { true } - - it { is_expected.to broadcast(:invalid) } - end - - context "when form is valid" do - let(:invalid?) { false } - - context "when zip code is not included" do - let(:zip_code) { "quox" } - - it { is_expected.to broadcast(:invalid) } - end - - context "when zip code included" do - let(:zip_code) { "baz" } - - context "when user does not exist" do - it "creates the user and broadcasts ok" do - expect { subject.call }.to change(Decidim::Budgets::UserData, :count).by(1) - end - end - - context "when user data exists" do - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "quox" }) } - let(:zip_code) { "foo" } - - it "updates the user data" do - subject.call - user_data = Decidim::Budgets::UserData.last - expect(Decidim::Budgets::UserData.count).to eq(1) - expect(user_data.metadata["zip_code"]).to eq("foo") - end - end - end - end - end - end -end diff --git a/decidim-budgets_booth/spec/controllers/decidim/budgets/user_data_controller_spec.rb b/decidim-budgets_booth/spec/controllers/decidim/budgets/user_data_controller_spec.rb deleted file mode 100644 index 38c1a832..00000000 --- a/decidim-budgets_booth/spec/controllers/decidim/budgets/user_data_controller_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Budgets - describe UserDataController, type: :controller do - routes { Decidim::Budgets::Engine.routes } - - include_context "with scoped budgets" - - let(:projects_count) { 5 } - let(:user) { create(:user, :confirmed, organization: organization) } - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:votes) { "enabled" } - - before do - request.env["decidim.current_organization"] = organization - request.env["decidim.current_participatory_space"] = component.participatory_space - request.env["decidim.current_component"] = component - end - - context "when not zip_code workflow" do - it "redirects the user with error message" do - get :new - expect(response).to redirect_to("/") - expect(flash[:warning]).to have_content("You are not allowed to perform this action.") - end - end - - context "when zip code workflow" do - let(:active_step_id) { component.participatory_space.active_step.id } - - before do - component.update!(settings: component_settings.merge(workflow: "zip_code"), step_settings: { active_step_id => { votes: votes } }) - end - - context "when not authenticated" do - it "redirects to the login page" do - get :new - expect(response).to redirect_to("/users/sign_in") - end - end - - context "when voted" do - let!(:order) { create(:order, :with_projects, user: user, budget: budgets.first) } - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "10004" }) } - - before do - order.update!(checked_out_at: Time.current) - sign_in user, scope: :user - end - - it "redirects to the root path" do - get :new - expect(response).to redirect_to("/") - expect(flash[:warning]).to have_content("You can not change your ZIP code after started voting. Delete all of your votes first.") - end - end - - context "when voting not open" do - let(:votes) { "finished" } - - before do - sign_in user, scope: :user - end - - it "redirects to the root path with warning" do - get :new - expect(response).to redirect_to("/") - expect(flash[:warning]).to have_content("You can not set your ZIP code when the voting is not open.") - end - end - - context "when zip code workflow, voting open, not voted, and login" do - before do - sign_in user, scope: :user - end - - it "renders new page with voting layout" do - get :new - expect(response).to render_template(:new, layout: "decidim/budgets/voting_layout") - end - end - end - end - end -end diff --git a/decidim-budgets_booth/spec/controllers/decidim/budgets/voting_controller_spec.rb b/decidim-budgets_booth/spec/controllers/decidim/budgets/voting_controller_spec.rb deleted file mode 100644 index aee92c0d..00000000 --- a/decidim-budgets_booth/spec/controllers/decidim/budgets/voting_controller_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Budgets - describe VotingController, type: :controller do - routes { Decidim::Budgets::Engine.routes } - - let(:user) { create(:user, :confirmed, organization: component.organization) } - let(:component) do - create( - :budgets_component, - settings: { workflow: "zip_code" } - ) - end - let(:vote) { "enabled" } - let(:current_settings) { double(:current_settings, votes: vote) } - let!(:budgets) { create_list(:budget, 3, component: component, total_budget: 100_000_000) } - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 45_000_000) } - let(:current_workflow) { double(:current_workflow, voting_booth_forced?: zip_code?) } - let(:zip_code?) { true } - - before do - request.env["decidim.current_organization"] = component.organization - request.env["decidim.current_participatory_space"] = component.participatory_space - request.env["decidim.current_component"] = component - allow(controller).to receive(:current_settings).and_return(current_settings) - allow(controller).to receive(:current_workflow).and_return(current_workflow) - end - - describe "#index" do - context "when voting is not open" do - let!(:vote) { "foo" } - - it "redirects the user with proper message" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to redirect_to(decidim_budgets.budget_projects_path(budgets.last)) - expect(flash[:warning]).to have_content("Voting is not allowed.") - end - end - - context "when not singed in" do - it "redirects to the sign in page" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to redirect_to("/users/sign_in") - end - end - - context "when voted that budget" do - let!(:order) { create(:order, :with_projects, user: user, budget: budgets.last) } - - before do - order.update!(checked_out_at: Time.current) - sign_in user, scope: :user - end - - it "redirects the user" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to redirect_to("/") - expect(flash[:warning]).to have_content("You are not allowed to perform this action.") - end - end - - context "when all before actions checked" do - before do - allow(controller).to receive(:enforce_permission_to).and_return(true) - sign_in user, scope: :user - end - - it "renders the voting booth" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") - end - end - end - end - end -end diff --git a/decidim-budgets_booth/spec/forms/decidim/budgets/user_data_form_spec.rb b/decidim-budgets_booth/spec/forms/decidim/budgets/user_data_form_spec.rb deleted file mode 100644 index 1a2f23a6..00000000 --- a/decidim-budgets_booth/spec/forms/decidim/budgets/user_data_form_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Budgets - describe UserDataForm do - subject(:form) { described_class.from_params(attributes) } - - let(:zip_code) { "dummy metadata" } - let(:organization) { create(:organization) } - let(:affirm_statements_are_correct) { true } - let(:user) { create(:user, :confirmed, organization: organization) } - let(:component) { create(:budgets_component) } - - let(:attributes) do - { - zip_code: zip_code, - affirm_statements_are_correct: affirm_statements_are_correct, - user: user, - component: component - } - end - - it { is_expected.to be_valid } - - context "when no user" do - let!(:user) { nil } - - it { is_expected.not_to be_valid } - end - - context "when no component" do - let!(:component) { nil } - - it { is_expected.not_to be_valid } - end - - context "when statement is not affirmed" do - let!(:affirm_statements_are_correct) { false } - - it { is_expected.not_to be_valid } - end - - context "when no metadata" do - let!(:zip_code) { nil } - - it { is_expected.not_to be_valid } - end - end - end -end diff --git a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/scope_manager_spec.rb b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/scope_manager_spec.rb deleted file mode 100644 index e3c0aa37..00000000 --- a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/scope_manager_spec.rb +++ /dev/null @@ -1,159 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::BudgetsBooth::ScopeManager do - subject { described_class.new(component) } - - let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, settings: component_settings, organization: organization) } - let(:component_settings) { { scopes_enabled: true, scope_id: parent_scope.id } } - - describe "#zip_codes_for" do - include_context "with scopes" - - let!(:first_budget) { create(:budget, component: component, scope: parent_scope) } - let!(:second_budget) { create(:budget, component: component, scope: subscopes.first) } - - it "returns correct zip_codes" do - expect(subject.zip_codes_for(first_budget)).to match_array( - [(10_000..10_004).to_a, (10_010..10_016).to_a, (10_020..10_027).to_a].flatten.map(&:to_s) - ) - expect(subject.zip_codes_for(second_budget)).to match_array((10_000..10_004).to_a.map(&:to_s)) - end - - describe "performance" do - # Disable transactional tests to optimize the query performance and ensure - # consistent results. With transactional queries, there may be fluctuation - # in the query performance. - self.use_transactional_tests = false - - let(:parent_scope) { city } - let!(:city) { create(:scope, organization: organization) } - let!(:boroughs) { create_list(:scope, 10, parent: city, organization: organization) } - let!(:neighborhoods) do - [].tap do |list| - boroughs.each do |parent| - 5.times do - list << create(:scope, parent: parent, organization: organization) - end - end - end - end - - before do - # Create the postal codes for all neighborhoods - neighborhoods.each_with_index do |neighborhood, i| - 20.times do |j| - postal = "#{(i + 1).to_s.rjust(2, "0")}#{j.to_s.rjust(3, "0")}" - create(:scope, code: "#{i}_#{postal}", name: { en: postal }, parent: neighborhood) - end - end - end - - after do - # Because the transactional tests are disabled, we need to manually - # clear the tables after the test. - connection = ActiveRecord::Base.connection - connection.disable_referential_integrity do - connection.tables.each do |table_name| - next if connection.select_value("SELECT COUNT(*) FROM #{table_name}").zero? - - connection.execute("TRUNCATE #{table_name} CASCADE") - end - end - end - - it "performs fairly" do - time_start = Time.zone.now - expect(subject.zip_codes_for(city).count).to eq(1000) - expect(Time.zone.now - time_start).to be < 0.1 - end - end - end - - describe "#user_zip_code" do - let(:parent_scope) { create(:scope, organization: organization) } - - context "when user does not exist" do - it "returns flase" do - expect(subject.user_zip_code(nil)).to be_falsey - end - end - - context "when user exist" do - include_context "with user data" - - let!(:user) { create(:user, organization: organization) } - let!(:another_component) { create(:budgets_component, organization: organization) } - - before do - user_data.update(metadata: { zip_code: "dummy metadata" }) - end - - it "returns the user_data" do - expect(subject.user_zip_code(user)).to eq("dummy metadata") - end - - it "does not return user data for another component" do - expect(described_class.new(another_component).user_zip_code(user)).to be_nil - end - end - - context "with multiple processes or threads", :caching do - # File cache store needed to persist the cache over multiple processes. - let(:file_store) { ActiveSupport::Cache.lookup_store(:file_store, cache_location) } - let(:cache_location) { Rails.root.join("tmp/test-file-cache-store") } - - let(:user) { create(:user, organization: organization) } - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "12345" }) } - - # Disable transactional tests to persist the data over multiple - # processes. - self.use_transactional_tests = false - - before do - # Has to be set in order to use the actual memory store because the - # runtime configuration has been already loaded with the :null_store - # configuration at the testing environment. - allow(Rails).to receive(:cache).and_return(file_store) - Rails.cache.clear - end - - after do - FileUtils.rm_rf(cache_location) - - # Because the transactional tests are disabled, we need to manually - # clear the tables after the test. - connection = ActiveRecord::Base.connection - connection.disable_referential_integrity do - connection.tables.each do |table_name| - next if connection.select_value("SELECT COUNT(*) FROM #{table_name}").zero? - - connection.execute("TRUNCATE #{table_name} CASCADE") - end - end - end - - it "does not persist the state in other processes" do - expect(subject.user_zip_code(user)).to eq("12345") - - pid = Process.fork do - subcomp = Decidim::Component.find(component.id) - subsm = Decidim::BudgetsBooth::ScopeManager.new(subcomp) - expect(subsm.user_zip_code(user)).to eq("12345") - sleep 5 - expect(subsm.user_zip_code(user)).to eq("67890") - end - - # Give enough time for the other process to do the first expectation - sleep(2) - user_data.destroy! - create(:user_data, component: component, user: user, metadata: { zip_code: "67890" }) - - Process.wait(pid) - expect($CHILD_STATUS.exitstatus).to eq(0) - end - end - end -end diff --git a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/workflows/zip_code_spec.rb b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/workflows/zip_code_spec.rb deleted file mode 100644 index fe73fe4c..00000000 --- a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/workflows/zip_code_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::BudgetsBooth::Workflows::ZipCode do - subject { described_class.new(component, user) } - - let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, settings: component_settings, organization: organization) } - let(:component_settings) { { scopes_enabled: true, scope_id: parent_scope.id } } - let!(:user) { create(:user, organization: organization) } - - describe "#vote_allowed?" do - let!(:allowed_budget) { create(:budget, component: component, scope: subscopes.first) } - let!(:not_allowed_budget) { create(:budget, component: component, scope: subscopes.second) } - - include_context "with scopes" - include_context "with user data" - - context "when user zip code is blank" do - before do - user_data.update(metadata: { zip_code: "" }) - end - - it "returns false" do - expect(subject).not_to be_vote_allowed(not_allowed_budget, consider_progress: true) - end - end - - context "when user zip code presents" do - before do - user_data.update(metadata: { zip_code: "10004" }) - end - - it "returns false for not_allowed_budget" do - expect(subject).not_to be_vote_allowed(not_allowed_budget, consider_progress: true) - end - - it "returns true for allowed_budget" do - expect(subject).to be_vote_allowed(allowed_budget, consider_progress: true) - end - end - end - - describe "#budgets" do - let(:parent_scope) { create(:scope, organization: organization) } - let!(:budgets) { create_list(:budget, 3, component: component) } - - let(:scope_manager) { instance_double(Decidim::BudgetsBooth::ScopeManager) } - - before do - allow(::Decidim::BudgetsBooth::ScopeManager).to receive(:new).with(component).and_return(scope_manager) - allow(scope_manager).to receive(:user_zip_code).with(user).and_return("dummy zip_code") - allow(scope_manager).to receive(:zip_codes_for).with(budgets.first).and_return(["dummy zip_code"]) - allow(scope_manager).to receive(:zip_codes_for).with(budgets.second).and_return(["dummy zip_code"]) - allow(scope_manager).to receive(:zip_codes_for).with(budgets.last).and_return(["another code"]) - end - - it "returns the correct budgets list" do - expect(subject.budgets).to include(budgets.first) - expect(subject.budgets).to include(budgets.second) - expect(subject.budgets).not_to include(budgets.last) - end - end - - describe "#highlighted?" do - let(:parent_scope) { create(:scope, organization: organization) } - let!(:budgets) { create_list(:budget, 3, component: component) } - - it "returs false" do - result = subject.highlighted?(budgets.first) - expect(result).to be_falsey - end - end - - describe "#disable_voting_instructions?" do - let(:parent_scope) { create(:scope, organization: organization) } - - it "is disabled by default" do - expect(subject).to be_disable_voting_instructions - end - end - - describe "hide_image_in_popup?" do - let(:parent_scope) { create(:scope, organization: organization) } - - it "is disabled by default" do - expect(subject).to be_hide_image_in_popup - end - end -end diff --git a/decidim-budgets_booth/spec/models/decidim/budgets/user_data_spec.rb b/decidim-budgets_booth/spec/models/decidim/budgets/user_data_spec.rb deleted file mode 100644 index e4500791..00000000 --- a/decidim-budgets_booth/spec/models/decidim/budgets/user_data_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Budgets::UserData do - let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, organization: organization) } - let(:user) { create(:user, organization: organization) } - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "12345" }) } - - shared_examples "fetched through the scope manager" do - let(:scope_manager) { Decidim::BudgetsBooth::ScopeManager.new(component) } - - describe "#create" do - it "clears the cache" do - expect(scope_manager.user_zip_code(user)).to eq("12345") - - user_data.destroy! - create(:user_data, component: component, user: user, metadata: { zip_code: "67890" }) - expect(scope_manager.user_zip_code(user)).to eq("67890") - end - end - - describe "#update" do - it "clears the cache" do - expect(scope_manager.user_zip_code(user)).to eq("12345") - - user_data.update!(metadata: { zip_code: "67890" }) - expect(scope_manager.user_zip_code(user)).to eq("67890") - end - end - - describe "#destroy" do - it "clears the cache" do - expect(scope_manager.user_zip_code(user)).to eq("12345") - - user_data.destroy! - expect(scope_manager.user_zip_code(user)).to be_nil - end - end - end - - it_behaves_like "fetched through the scope manager" - - context "when using the memory cache store", :caching do - let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } - - before do - # Has to be set in order to use the actual memory store because the - # runtime configuration has been already loaded with the :null_store - # configuration at the testing environment. - allow(Rails).to receive(:cache).and_return(memory_store) - Rails.cache.clear - end - - it_behaves_like "fetched through the scope manager" - end -end diff --git a/decidim-budgets_booth/spec/models/decidim/scope_spec.rb b/decidim-budgets_booth/spec/models/decidim/scope_spec.rb deleted file mode 100644 index fffa76e2..00000000 --- a/decidim-budgets_booth/spec/models/decidim/scope_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Scope do - let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, organization: organization, settings: component_settings) } - let(:component_settings) { { scopes_enabled: true, scope_id: parent_scope.id } } - - let(:parent_scope) { create(:scope, organization: organization) } - let!(:postal_scopes) do - [].tap do |scopes| - (10_000..10_005).each do |code| - scopes << create(:scope, parent: parent_scope, name: { en: code.to_s }, code: "POSTAL_#{code}") - end - end - end - let(:scope_manager) { Decidim::BudgetsBooth::ScopeManager.new(component) } - - describe "#create" do - it "clears the cache" do - expect(scope_manager.zip_codes_for(parent_scope)).to match_array(%w(10000 10001 10002 10003 10004 10005)) - - postal_scopes.last.destroy! - create(:scope, parent: parent_scope, name: { en: "10006" }, code: "POSTAL_10006") - expect(scope_manager.zip_codes_for(parent_scope)).to match_array(%w(10000 10001 10002 10003 10004 10006)) - end - end - - describe "#update" do - it "clears the cache" do - expect(scope_manager.zip_codes_for(parent_scope)).to match_array(%w(10000 10001 10002 10003 10004 10005)) - - postal_scopes.last.update!(name: { en: "10006" }, code: "POSTAL_10006") - expect(scope_manager.zip_codes_for(parent_scope)).to match_array(%w(10000 10001 10002 10003 10004 10006)) - end - end - - describe "#destroy" do - it "clears the cache" do - expect(scope_manager.zip_codes_for(parent_scope)).to match_array(%w(10000 10001 10002 10003 10004 10005)) - - postal_scopes.last.destroy! - expect(scope_manager.zip_codes_for(parent_scope)).to match_array(%w(10000 10001 10002 10003 10004)) - end - end -end From a11bdddf51a0bfee25eee9c355f1d66d25ee2540 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 20 Nov 2024 17:56:08 +0100 Subject: [PATCH 05/93] feat: update controllers and cells --- .../app/cells/decidim/budgets/project_g/show.erb | 5 ++--- .../app/cells/decidim/budgets/project_g_cell.rb | 2 +- .../budgets_controller_extensions.rb | 15 ++++++++------- .../projects_controller_extensions.rb | 14 +++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb index 3a330019..43691691 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb @@ -3,7 +3,7 @@ <% if has_image? %> <%= image_tag resource_image_path, alt: alt_title %> <% else %> - <%= external_icon "media/images/project-placeholder-card-g.svg", class: "card__project-placeholder-g" %> + <%= external_icon "media/images/decidim_budgets.svg", class: "card__project-placeholder-g" %> <% end %>
@@ -19,8 +19,7 @@ <%= cell metadata_cell, resource, links: false, skip_state: true, **options %>
<% end %> - -
+
<%= budget_to_currency(project.budget_amount) %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb index 38388a52..ebc08c0e 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb @@ -30,7 +30,7 @@ def metadata_cell_instance end def resource_image_path - project.photos.first&.url if project.photos.present? + project.photos.first&.url if project.attachments.present? end private diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb index f752d337..c6316ecb 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb @@ -19,18 +19,19 @@ module BudgetsControllerExtensions private def determine_layout - return layout unless voting_booth_forced? + "layouts/decidim/application" + #return layout unless voting_booth_forced? - return layout unless voting_enabled? + #return layout unless voting_enabled? - return layout if voted_all_budgets? + #return layout if voted_all_budgets? - "decidim/budgets/voting_layout" + #"decidim/budgets/voting_layout" end - def open_and_voting_booth_forced? - voting_booth_forced? && voting_open? - end + #def open_and_voting_booth_forced? + # voting_booth_forced? && voting_open? + #end def layout "layouts/decidim/application" diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb index c010bb10..5a60052b 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb @@ -13,23 +13,23 @@ module ProjectsControllerExtensions def index raise ActionController::RoutingError, "Not Found" unless budget - raise ActionController::RoutingError, "Not Found" unless allow_access? + #raise ActionController::RoutingError, "Not Found" unless allow_access? end def show raise ActionController::RoutingError, "Not Found" unless budget raise ActionController::RoutingError, "Not Found" unless project - raise ActionController::RoutingError, "Not Found" unless allow_access? + #raise ActionController::RoutingError, "Not Found" unless allow_access? end end private - def allow_access? - return false if voting_booth_forced? && voting_enabled? && !voted_this?(budget) - - true - end + #def allow_access? + # return false if voting_booth_forced? && voting_enabled? && !voted_this?(budget) + # + # true + #end #added def determine_layout "decidim/budgets/voting_layout" From ede9e06aab48b35a1a13ea65e78a102271db4f1d Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 20 Nov 2024 17:56:45 +0100 Subject: [PATCH 06/93] style: update css --- .../stylesheets/decidim/budgets_booth/budgets_booth.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss index 34418e37..c88c6ee0 100644 --- a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss +++ b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss @@ -363,3 +363,7 @@ $active-item-color: black; font-weight: bold; } } +.card__project-placeholder-g{ + width: 100%; + height: 100%; +} From e20d43592c002c4aef00ddc42048306a35398243 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 20 Nov 2024 17:59:30 +0100 Subject: [PATCH 07/93] test: begin updating tests --- .../budgets_controller_extensions_spec.rb | 73 ++---------- .../orders_controller_extensions_spec.rb | 5 +- .../projects_controller_extensions_spec.rb | 111 ++++-------------- .../budgets_booth/voting_support_spec.rb | 18 +-- 4 files changed, 51 insertions(+), 156 deletions(-) diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb index 646319f4..4e666273 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb @@ -12,27 +12,18 @@ module BudgetsBooth describe "#index" do routes { Decidim::Budgets::Engine.routes } - let(:user) { create(:user, :confirmed, organization: organization) } let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, settings: component_settings, organization: organization) } - let(:component_settings_base) { { scopes_enabled: true, scope_id: parent_scope.id } } - let(:component_settings) { component_settings_base.merge(workflow: "zip_code", votes: "enabled") } - let(:parent_scope) { create(:scope, organization: organization) } - let!(:subscopes) do - [].tap do |scopes| - scopes << create(:scope, name: { en: "123456" }, parent: parent_scope, organization: organization) - scopes << create(:scope, name: { en: "789012" }, parent: parent_scope, organization: organization) - scopes << create(:scope, name: { en: "345678" }, parent: parent_scope, organization: organization) - end - end + let(:component) { create(:budgets_component, organization:, settings: component_settings) } + let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } + let(:component_settings) { { votes: "enabled" } } let!(:budgets) do [].tap do |list| - list << create(:budget, component: component, scope: subscopes[0]) - list << create(:budget, component: component, scope: subscopes[1]) - list << create(:budget, component: component, scope: subscopes[2]) + list << create(:budget, component:) + list << create(:budget, component:) + list << create(:budget, component:) end end - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } + before do request.env["decidim.current_organization"] = organization @@ -40,62 +31,24 @@ module BudgetsBooth request.env["decidim.current_component"] = component end - context "when zip_code workflow" do context "when voting enabled" do - context "when not logged in" do - it "redirects to the login page" do - get :index - expect(response).to redirect_to("/users/sign_in") - end - end - - context "when user data is not set" do - before do - sign_in user, scope: :user - end - - it "redirects to the zip code" do - get :index - expect(response).to redirect_to(decidim_budgets.new_zip_code_path) - end - end - - context "when user data is set" do - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "123456" }) } - - before do - sign_in user, scope: :user - end - - it "renders index with booth layout" do - get :index - expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") - end + it "renders index with budgets_booth application layout" do + get :index + expect(response).to render_template(:index, layout: "layouts/decidim/application") end end context "when voting is not enabled" do before do - component.update(settings: component_settings_base.merge(votes: "finished")) + component.update(settings: component_settings.merge(votes: "finished")) end - it "does not render the layout" do + it "renders index with budgets_booth voting_layout" do get :index - expect(response).to render_template(:index, layout: "layouts/decidim/participatory_process") + expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") end end - end - context "when not zip_code workflow" do - before do - component.update(settings: component_settings_base.merge(workflow: "one")) - end - - it "renders the index" do - get :index - expect(response).to render_template(:index, layout: "layouts/decidim/participatory_process") - end - end end end end diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb index 0839674c..c690c160 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb @@ -11,13 +11,12 @@ include_context "with scoped budgets" - let(:user) { create(:user, :confirmed, organization: organization) } - let(:component) { create(:budgets_component, settings: component_settings.merge(workflow: "zip_code"), organization: organization) } + let(:user) { create(:user, :confirmed, organization:) } + let(:component) { create(:budgets_component, organization:) } let(:projects_count) { 5 } let!(:budgets) { create_list(:budget, 3, component: component, total_budget: 100_000_000) } let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 75_000_000) } - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "10004" }) } let!(:order) { create(:order, user: user, budget: budgets.first) } before do diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb index d96ad4d9..30e0d0d6 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb @@ -12,20 +12,17 @@ module BudgetsBooth end let(:organization) { create(:organization) } - let(:participatory_space) { create(:participatory_process, :with_steps, organization: organization) } - let(:user) { create(:user, :confirmed, organization: organization) } + let(:participatory_space) { create(:participatory_process, :with_steps, organization:) } + let(:user) { create(:user, :confirmed, organization:) } let(:component) do create( :budgets_component, - settings: component_settings, step_settings: step_settings, participatory_space: participatory_space, organization: organization ) end let(:parent_scope) { create(:scope, organization: organization) } - let(:component_settings_base) { { scopes_enabled: true, scope_id: parent_scope.id } } - let(:component_settings) { component_settings_base } let(:step_settings) { { active_step_id => { votes: votes } } } let(:active_step_id) { participatory_space.active_step.id } let!(:budgets) { create_list(:budget, 3, component: component) } @@ -40,99 +37,43 @@ module BudgetsBooth end describe "#index" do - context "when zip_code workflow" do - let(:component_settings) { component_settings_base.merge(workflow: "zip_code") } - - context "when voting enabled" do - context "when not voted all budgets" do - before do - allow(controller).to receive(:voted_this?).and_return(false) - end - - it "raises error" do - expect do - get :index, params: { budget_id: budgets.last.id } - end.to raise_error(ActionController::RoutingError, "Not Found") - end - end - - context "when voted that budget" do - before do - allow(controller).to receive(:voted_this?).and_return(true) - end - - it "does not raise error" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to render_template(:index) - end - end - end - - context "when voting is disabled" do - let(:votes) { "disabled" } - - it "renders projects index" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to render_template(:index) - end + context "when budget" do + it "renders index" do + get :index, params: { budget_id: budgets.last.id } + expect(response).to render_template(:index) end end - context "when not zip code workflow" do - let(:component_settings) { component_settings_base.merge(workflow: "one") } - - it "renders the index template" do - get :index, params: { budget_id: budgets.last.id } - expect(response).to render_template(:index) + context "when no budget" do + it "raises error" do + expect do + get :index, params: { budget_id: nil } + end.to raise_error(ActionController::RoutingError, "Not Found") end end end describe "#show" do - context "when zip_code workflow" do - let(:component_settings) { component_settings_base.merge(workflow: "zip_code") } - - context "when voting enabled" do - context "when not voted that budget" do - before do - allow(controller).to receive(:voted_this?).and_return(false) - end - - it "raises error" do - expect do - get :show, params: { id: project.id, budget_id: budgets.last.id } - end.to raise_error(ActionController::RoutingError, "Not Found") - end - end - - context "when voted that budget" do - before do - allow(controller).to receive(:voted_this?).and_return(true) - end - - it "does not raise error" do - get :show, params: { id: project.id, budget_id: budgets.last.id } - expect(response).to render_template(:show) - end - end + context "when budget and project" do + it "renders show" do + get :show, params: { id: project.id, budget_id: budgets.last.id } + expect(response).to render_template(:show) end + end - context "when voting is disabled" do - let!(:votes) { "disabled" } - - it "renders projects index" do - get :show, params: { id: project.id, budget_id: budgets.last.id } - expect(response).to render_template(:show) - end + context "when budget and no project" do + it "raises error" do + expect do + get :show, params: { id: 1000000, budget_id: budgets.last.id } + end.to raise_error(ActionController::RoutingError, "Not Found") end end - context "when not zip code workflow" do - let(:component_settings) { component_settings_base.merge(workflow: "one") } - - it "renders the index template" do - get :show, params: { id: project.id, budget_id: budgets.last.id } - expect(response).to render_template(:show) + context "when no budget and project" do + it "raises error" do + expect do + get :show, params: { id: project.id, budget_id: nil } + end.to raise_error(ActionController::RoutingError, "Not Found") end end end diff --git a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb index 369efb52..c419f2da 100644 --- a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb +++ b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb @@ -27,7 +27,7 @@ def current_component end def current_workflow - Decidim::BudgetsBooth::Workflows::ZipCode.new(current_component, current_user) + Decidim::Budgets::Workflows::One.new(current_component, current_user) end def voting_open? @@ -39,7 +39,7 @@ def voting_open? let(:component) do create( :budgets_component, - settings: component_settings.merge(workflow: "zip_code"), + settings: component_settings.merge(workflow: "one"), step_settings: step_settings, organization: organization ) @@ -52,9 +52,10 @@ def voting_open? let(:projects_count) { 5 } let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 75_000) } let(:second_projects) { create_list(:project, 3, budget: budgets.second, budget_amount: 75_000) } - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "10004" }) } + let(:third_projects) { create_list(:project, 3, budget: budgets.third, budget_amount: 75_000) } let!(:order) { create(:order, user: user, budget: budgets.first) } let!(:second_order) { create(:order, user: user, budget: budgets.second) } + let!(:third_order) { create(:order, user: user, budget: budgets.third) } include_context "with scoped budgets" @@ -73,7 +74,7 @@ def voting_open? describe "#voted_any?" do context "when user exist but not voted" do - it "returns flase" do + it "returns false" do expect(subject).not_to be_voted_any end end @@ -103,10 +104,11 @@ def voting_open? end end - context "when voted all of the busgets" do + context "when voted all of the budgets" do before do vote_this(order, projects.first) vote_this(second_order, second_projects.first) + vote_this(third_order, third_projects.first) end it "returns true" do @@ -118,7 +120,7 @@ def voting_open? context "when maximum_budgets_to_vote_on is set" do context "when voted the limit" do before do - component.update!(settings: component_settings.merge(workflow: "zip_code", maximum_budgets_to_vote_on: 1)) + component.update!(settings: component_settings.merge(workflow: "one", maximum_budgets_to_vote_on: 1)) vote_this(order, projects.first) end @@ -143,7 +145,7 @@ def voting_open? context "when maximum_budgets_to_vote_on is set" do before do - component.update(settings: component_settings.merge(workflow: "zip_code", maximum_budgets_to_vote_on: 1)) + component.update(settings: component_settings.merge(workflow: "one", maximum_budgets_to_vote_on: 1)) vote_this(order, projects.first) end @@ -160,7 +162,7 @@ def voting_open? let(:votes) { "disabled" } before do - component.update!(settings: component_settings.merge(workflow: "zip_code", maximum_budgets_to_vote_on: 1), step_settings: step_settings) + component.update!(settings: component_settings.merge(workflow: "one", maximum_budgets_to_vote_on: 1), step_settings: step_settings) vote_this(order, projects.first) allow(dummy).to receive(:current_settings).and_return(component.current_settings) From ee2e27690791a5a2d2df540add4a7d994b3127cc Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 25 Nov 2024 09:35:27 +0100 Subject: [PATCH 08/93] feat: delete files linked to main image --- .../budgets_booth/create_budget_extensions.rb | 31 ----------------- .../budgets_booth/update_budget_extensions.rb | 33 ------------------- .../budgets_booth/budget_form_extensions.rb | 25 -------------- .../budgets_booth/budget_extensions.rb | 17 ---------- .../budgets/admin/budgets/_formX.html.erb | 30 ----------------- 5 files changed, 136 deletions(-) delete mode 100644 decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/create_budget_extensions.rb delete mode 100644 decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/update_budget_extensions.rb delete mode 100644 decidim-budgets_booth/app/forms/concerns/decidim/budgets_booth/budget_form_extensions.rb delete mode 100644 decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/budget_extensions.rb delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_formX.html.erb diff --git a/decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/create_budget_extensions.rb b/decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/create_budget_extensions.rb deleted file mode 100644 index abf651ce..00000000 --- a/decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/create_budget_extensions.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module CreateBudgetExtensions - extend ActiveSupport::Concern - - included do - private - - def create_budget! - attributes = { - component: form.current_component, - scope: form.scope, - title: form.title, - weight: form.weight, - description: form.description, - total_budget: form.total_budget, - main_image: form.main_image - } - @budget = Decidim.traceability.create!( - ::Decidim::Budgets::Budget, - form.current_user, - attributes, - visibility: "all" - ) - end - end - end - end -end diff --git a/decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/update_budget_extensions.rb b/decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/update_budget_extensions.rb deleted file mode 100644 index ae4f2ab1..00000000 --- a/decidim-budgets_booth/app/commands/concerns/decidim/budgets_booth/update_budget_extensions.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module UpdateBudgetExtensions - extend ActiveSupport::Concern - include ::Decidim::AttachmentAttributesMethods - - included do - private - - def update_budget! - attributes = { - scope: form.scope, - title: form.title, - weight: form.weight, - description: form.description, - total_budget: form.total_budget - }.merge( - attachment_attributes(:main_image) - ) - - Decidim.traceability.update!( - budget, - form.current_user, - attributes, - visibility: "all" - ) - end - end - end - end -end diff --git a/decidim-budgets_booth/app/forms/concerns/decidim/budgets_booth/budget_form_extensions.rb b/decidim-budgets_booth/app/forms/concerns/decidim/budgets_booth/budget_form_extensions.rb deleted file mode 100644 index 85a6bcad..00000000 --- a/decidim-budgets_booth/app/forms/concerns/decidim/budgets_booth/budget_form_extensions.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - module BudgetFormExtensions - extend ActiveSupport::Concern - - included do - attribute :main_image - validates :main_image, passthru: { - to: ::Decidim::Budgets::Budget, - with: { - component: lambda do |form| - space = Decidim.participatory_space_manifests.first.model_class_name.constantize.new( - organization: form.current_organization - ) - - Decidim::Component.new(participatory_space: space) - end - } - } - end - end - end -end diff --git a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/budget_extensions.rb b/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/budget_extensions.rb deleted file mode 100644 index 33725570..00000000 --- a/decidim-budgets_booth/app/models/concerns/decidim/budgets_booth/budget_extensions.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require "active_support/concern" - -module Decidim - module BudgetsBooth - module BudgetExtensions - extend ActiveSupport::Concern - include Decidim::HasUploadValidations - - included do - has_one_attached :main_image - validates_upload :main_image, uploader: Decidim::BudgetsBooth::MainImageUploader - end - end - end -end diff --git a/decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_formX.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_formX.html.erb deleted file mode 100644 index 7e9ba7c7..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/admin/budgets/_formX.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -
-
-

<%= title %>

-
- -
-
- <%= form.translated :text_field, :title, autofocus: true %> - - <%= form.number_field :weight %> - - <%= form.translated :editor, :description %> - - <%= form.number_field :total_budget %> - <% if current_component.has_subscopes? %> -
- <%= scopes_picker_field form, :decidim_scope_id, root: current_component.scope %> -
- <% end %> -
-
-
-

<%= t("images", scope: "decidim.budgets.admin.budgets.edit") %>

-
-
-
- <%= form.upload :main_image %> -
-
-
From 89aa59206a440ab0954e3098a5fdcb16685353e7 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 27 Nov 2024 12:22:40 +0100 Subject: [PATCH 09/93] feat: remove budget and budgetform extensions from engine file --- .../lib/decidim/budgets_booth/engine.rb | 13 - .../spec/system/budgets_view_spec.rb | 246 --------- .../spec/system/non_zip_code_workflow_spec.rb | 304 ----------- .../spec/system/user_data_workflow_spec.rb | 260 ---------- .../spec/system/voting_index_page_spec.rb | 484 ------------------ 5 files changed, 1307 deletions(-) delete mode 100644 decidim-budgets_booth/spec/system/budgets_view_spec.rb delete mode 100644 decidim-budgets_booth/spec/system/non_zip_code_workflow_spec.rb delete mode 100644 decidim-budgets_booth/spec/system/user_data_workflow_spec.rb delete mode 100644 decidim-budgets_booth/spec/system/voting_index_page_spec.rb diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb index f157cf16..21b68964 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb @@ -22,10 +22,6 @@ class Engine < ::Rails::Engine resources :projects, only: [:show] end resource :order, only: [:show] - - collection do - resources :zip_code, only: [:new, :create], controller: "user_data", path: "user/zip_code" - end end end end @@ -78,15 +74,6 @@ class Engine < ::Rails::Engine Decidim::BudgetsBooth::ProjectsControllerExtensions ) - # Models extensions - Decidim::Budgets::Budget.include( - Decidim::BudgetsBooth::BudgetExtensions - ) - - # Forms extensions - Decidim::Budgets::Admin::BudgetForm.include( - Decidim::BudgetsBooth::BudgetFormExtensions - ) end end diff --git a/decidim-budgets_booth/spec/system/budgets_view_spec.rb b/decidim-budgets_booth/spec/system/budgets_view_spec.rb deleted file mode 100644 index e2e5a470..00000000 --- a/decidim-budgets_booth/spec/system/budgets_view_spec.rb +++ /dev/null @@ -1,246 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Budgets view", type: :system do - let(:projects_count) { 1 } - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:user) { create(:user, :confirmed, organization: organization) } - - before do - switch_to_host(organization.host) - end - - context "with multiple budgets" do - include_context "with scoped budgets" - - context "when not signed in" do - before { visit decidim_budgets.budgets_path } - - it "shows the normal layout" do - expect(page).to have_link(translated(budgets.first.title), href: decidim_budgets.budget_path(budgets.first)) - expect(page).to have_selector("a", text: /show/i, count: 3) - expect(page).to have_content("€100,000") - end - end - - context "when workflow" do - include_context "with zip_code workflow" - - context "when not signed in" do - before { visit decidim_budgets.budgets_path } - - it_behaves_like "ensure user sign in" - end - - context "when signed in" do - before { sign_in user, scope: :user } - - context "when no zip code" do - before { visit decidim_budgets.budgets_path } - - it "redirects user to zipcode entering path" do - expect(page).to have_current_path(decidim_budgets.new_zip_code_path) - end - end - - context "with user zip_code exist" do - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "dummy_1234" }) } - - context "when no budgets to vote" do - before { visit decidim_budgets.budgets_path } - - it "renders budgets page" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(page).to have_content "No budgets were found based on your ZIP code. You can change your ZIP code if it's not correct, or you can search again later." - end - end - - context "when budgets to vote" do - let(:first_budget) { budgets.first } - let(:second_budget) { budgets.second } - let(:landing_page_content) { Decidim::Faker::Localized.sentence(word_count: 5) } - - before do - user_data.update!(metadata: { zip_code: "10004" }) - visit decidim_budgets.budgets_path - end - - it "renders the budgets page and budgets" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(page).to have_content "You are now in the voting booth." - within "#budgets" do - expect(page).to have_css(".card.card--list.budget-list", count: 2) - expect(page).to have_selector("a", text: "More info", count: 2) - expect(page).to have_link(text: /TAKE PART/, href: decidim_budgets.budget_voting_index_path(first_budget)) - expect(page).to have_link(text: /TAKE PART/, href: decidim_budgets.budget_voting_index_path(second_budget)) - expect(page).to have_link(translated(first_budget.title), href: decidim_budgets.budget_voting_index_path(budgets.first)) - expect(page).to have_link(translated(second_budget.title), href: decidim_budgets.budget_voting_index_path(second_budget)) - expect(page).to have_content("Eius officiis expedita. 55") - expect(page).to have_content("Eius officiis expedita. 56") - end - expect(page).to have_no_css(".callout.warning.font-customizer") - expect(page).to have_button("Cancel voting") - click_button "Cancel voting" - within ".small.reveal.confirm-reveal" do - expect(page).to have_content("Are you sure you want to exit the voting booth?") - click_link "OK" - end - expect(page).to have_link(href: "/") - end - - context "when description is long" do - before do - first_budget.update!(description: { en: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fus. ultricies lacus vel dui vestibulum, eu aliquam libero convallis. Donec vitae ligula velitFooba ligul dolor sit amet, consectetur adipiscing elit. Fus. ultricies lacus vel dui vestibulum, eu aliquam libero convallis. Donec vitae ligula velitSome dummy text

" })) - vote_for_this(budget) - end - - it "sets the text message with svg image by default" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(page).to have_css("div#thanks-message", count: 1) - - within "#thanks-message" do - expect(page).to have_content("Thank you for voting!") - expect(page).to have_css("svg", count: 1) - expect(page).to have_button("Continue") - end - end - end - - context "when vote_success_content is nil" do - before do - vote_for_this(budget) - end - - it "does not show popup" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(page).to have_no_css("div#thanks-message") - end - end - - context "when the current_workflow sets not to show thanks message image" do - before do - allow_any_instance_of(Decidim::Budgets::Workflows::All).to receive(:hide_image_in_popup?).and_return(true) # rubocop:disable RSpec/AnyInstance - component.update!(settings: component_settings.merge(vote_success_content: { en: "

Some dummy text

" })) - vote_for_this(budget) - end - - it "sets the text message without svg image" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - within "#thanks-message" do - expect(page).to have_content("Thank you for voting!") - expect(page).to have_no_css("svg") - expect(page).to have_button("Continue") - end - end - end - end - - describe "complete all votes popup" do - context "when maximum_budgets_to_vote_on is set to zero" do - let!(:order) { create(:order, user: user, budget: second_budget) } - - before do - order.projects << second_budgets_project - order.checked_out_at = Time.current - order.save - end - - it "does not show the popup when vote_completed_content is nil" do - vote_for_this(budget) - expect(page).to have_no_css("div#vote-completed") - end - - it "shows the popup with the text when the popup text is set" do - component.update!(settings: component_settings.merge(vote_completed_content: { en: "

Some dummy text

" })) - vote_for_this(budget) - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(page).to have_css("div#vote-completed", count: 1) - within "div#vote-completed" do - expect(page).to have_content("You successfully completed your votes") - expect(page).to have_content("Some dummy text") - end - end - end - - context "when maximum_budgets_to_vote_on is set" do - before do - component.update!(settings: component_settings.merge(vote_completed_content: { en: "

Some dummy text

" }, maximum_budgets_to_vote_on: 1)) - vote_for_this(budget) - end - - it "shows the completed message" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(page).to have_css("div#vote-completed", count: 1) - within "div#vote-completed" do - expect(page).to have_content("You successfully completed your votes") - expect(page).to have_content("Some dummy text") - end - end - end - end - end - end - end - end - - context "when one budget" do - before do - switch_to_host(organization.host) - end - - context "when visiting the budgets list" do - before do - sign_in user - visit decidim_budgets.budgets_path - end - - it "redirects the user to projects list" do - expect(page).to have_current_path(decidim_budgets.budget_projects_path(budget)) - expect(page).to have_no_content("Back to budgets") - expect(page).to have_no_content("Show all budgets") - click_button "Start voting" - expect(page).to have_current_path(decidim_budgets.budget_voting_index_path(budget)) - expect(page).to have_no_content("Back to budgets") - expect(page).to have_no_content("Show all budgets") - end - end - end - - private - - def vote_for_this(budget) - visit decidim_budgets.budget_voting_index_path(budget) - click_button("Add to your vote", match: :first) - click_button("I understand how to vote") - click_button("Add to your vote", match: :first) - click_button("I am ready") - click_button("Confirm") - end -end diff --git a/decidim-budgets_booth/spec/system/user_data_workflow_spec.rb b/decidim-budgets_booth/spec/system/user_data_workflow_spec.rb deleted file mode 100644 index af002ed3..00000000 --- a/decidim-budgets_booth/spec/system/user_data_workflow_spec.rb +++ /dev/null @@ -1,260 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "user data workflow", type: :system do - include_context "with scoped budgets" - - let(:projects_count) { 4 } - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:user) { create(:user, :confirmed, organization: organization) } - let(:first_budget) { budgets.first } - - before do - switch_to_host(organization.host) - end - - context "when not zip_code workflow" do - before do - visit decidim_budgets.new_zip_code_path - end - - it_behaves_like "ensure zip code workflow" - end - - context "when not signed in" do - before do - component.update(settings: component_settings.merge(workflow: "zip_code")) - visit decidim_budgets.new_zip_code_path - end - - it_behaves_like "ensure user sign in" - end - - context "when voted" do - let!(:order) { create(:order, user: user, budget: first_budget) } - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "10004" }) } - - before do - component.update(settings: component_settings.merge(workflow: "zip_code")) - order.projects << first_budget.projects.first - order.projects << first_budget.projects.second - order.projects << first_budget.projects.third - order.checked_out_at = Time.current - order.save! - sign_in user, scope: :user - visit decidim_budgets.new_zip_code_path - end - - it "does not let adding zip code" do - within_flash_messages do - expect(page).to have_content("You can not change your ZIP code after started voting. Delete all of your votes first.") - end - expect(page).to have_current_path("/") - end - end - - context "when voting is not open" do - let(:active_step_id) { component.participatory_space.active_step.id } - - before do - component.update!(settings: component_settings.merge(workflow: "zip_code"), step_settings: { active_step_id => { votes: :finished } }) - sign_in user, scope: :user - visit decidim_budgets.new_zip_code_path - end - - it "does not let the user to add their zip code" do - within_flash_messages do - expect(page).to have_content("You can not set your ZIP code when the voting is not open.") - end - expect(page).to have_current_path("/") - end - end - - context "when before_actions met" do - let(:non_existing_zip_code) { "12345" } - let(:existing_zip_code) { "10004" } - - before do - component.update!(settings: component_settings.merge(workflow: "zip_code")) - sign_in user, scope: :user - visit decidim_budgets.new_zip_code_path - end - - context "when default zip_code_length" do - it_behaves_like "rendering new zip code page", 5 - end - - context "when zip_code_length is set" do - before do - allow(Decidim::BudgetsBooth.config).to receive(:zip_code_length).and_return(6) - visit decidim_budgets.new_zip_code_path - end - - it_behaves_like "rendering new zip code page", 6 - end - - context "when submitting the form" do - context "when empty" do - before do - click_button "Find my ballots" - end - - it "renders errors" do - within ".zip-code-errors" do - expect(page).to have_content("ZIP code format is not correct.") - end - within "#affirm-checkbox" do - expect(page).to have_content("must be accepted") - end - check "By checking this box, I affirm that these stamenets are true, and that I meet the voting eligibility requirements." - click_button "Find my ballots" - - expect(page).to have_no_selector("#affirm-checkbox") - expect(page).to have_no_content("must be accepted") - - fill_in_code(non_existing_zip_code, "digit") - click_button "Find my ballots" - within "#zip-code-not-valid" do - expect(page).to have_content("The ZIP code you provided is not part of the areas that are eligible for voting.") - end - end - end - end - - describe "cancel button" do - context "when no user data" do - it "redirects to the root path" do - expect(page).to have_button("Cancel") - click_button "Cancel" - expect(page).to have_content("Are you sure you want to exit?") - click_link("OK") - expect(page).to have_current_path("/") - end - end - - context "when user data exists" do - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "10004" }) } - - before do - visit decidim_budgets.new_zip_code_path - end - - it "redirects to the budgets path" do - expect(page).to have_button("Cancel") - click_button "Cancel" - expect(page).to have_content("Are you sure you want to exit?") - click_link("OK") - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end - end - - context "when submitting with correct data" do - before do - check "By checking this box, I affirm that these stamenets are true, and that I meet the voting eligibility requirements." - fill_in_code(existing_zip_code, "digit") - click_button "Find my ballots" - end - - context "when user data does not exist" do - it "creates user_data and redirects the user" do - within_flash_messages do - expect(page).to have_content("You have successfully registered your ZIP code.") - end - expect(page).to have_current_path(decidim_budgets.budgets_path) - expect(user.budgets_user_data.last.metadata).to eq({ "zip_code" => existing_zip_code }) - end - end - end - - context "when userdata exists" do - let!(:user_data) { create(:user_data, component: component, user: user, metadata: { zip_code: "quox" }) } - - before do - check "By checking this box, I affirm that these stamenets are true, and that I meet the voting eligibility requirements." - fill_in_code(existing_zip_code, "digit") - click_button "Find my ballots" - end - - it "updates existing metadata" do - within_flash_messages do - expect(page).to have_content("You have successfully registered your ZIP code.") - end - expect(page).to have_current_path(decidim_budgets.budgets_path) - data = Decidim::Budgets::UserData.last - expect(Decidim::Budgets::UserData.count).to eq(1) - expect(data.metadata).to eq({ "zip_code" => "10004" }) - end - end - end - - describe "input fields" do - context "when pasting" do - before do - component.update!(settings: { workflow: "zip_code" }) - sign_in user, scope: :user - visit decidim_budgets.new_zip_code_path - check "By checking this box, I affirm that these stamenets are true, and that I meet the voting eligibility requirements." - end - - context "when not valid clipboard" do - let(:clipboard_content_plain) { "a12_3" } - - it "renders error correctly" do - page.execute_script( - <<~JS - var dt = new DataTransfer(); - dt.setData("text/plain", #{clipboard_content_plain.to_json}); - var element = document.querySelector('input[name="digit1"]'); - element.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt })); - JS - ) - within ".zip-code-errors" do - expect(page).to have_content("Only letters and digits are allowed.") - end - expect(page).to have_selector(".is-invalid-input", count: 5) - end - end - - context "when valid clipboard" do - let(:clipboard_content_plain) { "abcd" } - - before do - fill_in_code("1234", "digit") - end - - it "pastes correctly" do - page.execute_script( - <<~JS - var dt = new DataTransfer(); - dt.setData("text/plain", #{clipboard_content_plain.to_json}); - var element = document.querySelector('input[name="digit3"]'); - element.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt })); - JS - ) - within ".zip-code-errors" do - expect(page).to have_no_content("Only letters and digits are allowed.") - end - expect(page).to have_no_selector(".is-invalid-input") - inputs = page.find_all('input[name^="digit"]') - expect(inputs[0].value).to eq("1") - expect(inputs[1].value).to eq("2") - expect(inputs[2].value).to have_content("a") - expect(inputs[3].value).to have_content("b") - expect(inputs[4].value).to have_content("c") - end - end - end - end - - private - - def fill_in_code(code, element) - code.length.times do |ind| - break if code[ind].blank? - - fill_in "#{element}#{ind + 1}", with: code[ind] - end - end -end diff --git a/decidim-budgets_booth/spec/system/voting_index_page_spec.rb b/decidim-budgets_booth/spec/system/voting_index_page_spec.rb deleted file mode 100644 index 6929487f..00000000 --- a/decidim-budgets_booth/spec/system/voting_index_page_spec.rb +++ /dev/null @@ -1,484 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Voting index page", type: :system do - include_context "with scoped budgets" - - let(:projects_count) { 10 } - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:user) { create(:user, :confirmed, organization: organization) } - let(:first_budget) { budgets.first } - let(:second_budget) { budgets.second } - let(:active_step_id) { component.participatory_space.active_step.id } - - before do - switch_to_host(organization.host) - end - - context "when not signed in" do - before do - component.update(settings: component_settings.merge(workflow: "zip_code")) - visit_budget(first_budget) - end - - it_behaves_like "ensure user sign in" - end - - context "when no user_data" do - before do - component.update(settings: component_settings.merge(workflow: "zip_code")) - sign_in user, scope: :user - visit_budget(first_budget) - end - - it_behaves_like "ensure user data" - end - - context "when not allowed to vote that budget" do - let!(:user_data) { create(:user_data, component: component, user: user) } - - before do - component.update(settings: component_settings.merge(workflow: "zip_code")) - sign_in user, scope: :user - visit_budget(first_budget) - end - - it_behaves_like "not allowable voting" - end - - context "when voted to that budget" do - let!(:user_data) { create(:user_data, component: component, user: user) } - let!(:order) { create(:order, :with_projects, user: user, budget: first_budget) } - - before do - component.update(settings: component_settings.merge(workflow: "zip_code")) - order.update!(checked_out_at: Time.current) - user_data.update!(metadata: { zip_code: "10004" }) - sign_in user, scope: :user - visit_budget(first_budget) - end - - it "redirects the user" do - expect(page).to have_current_path("/") - within_flash_messages do - expect(page).to have_content "You are not allowed to perform this action." - end - end - end - - describe "voting" do - let!(:user_data) { create(:user_data, component: component, user: user) } - - before do - component.update(settings: component_settings.merge(workflow: "zip_code", projects_per_page: 5)) - user_data.update!(metadata: { zip_code: "10004" }) - sign_in user, scope: :user - visit_budget(first_budget) - end - - it_behaves_like "cancel voting" - - it "renders the page correctly" do - expect(page).to have_content("You are now in the voting booth.") - expect(page).to have_content("You decide the #{first_budget.title["en"]} budget") - expect(page).to have_button("Cancel voting") - expect(page).to have_content("TOTAL BUDGET €100,000") - expect(page).to have_content("10 PROJECTS") - expect(page).to have_selector("button", text: "Read more", count: 5) - expect(page).to have_selector("button", text: "Add to your vote", count: 5) - end - - describe "budget summary" do - before do - click_button "Add to your vote", match: :first - end - - it "updates budget summary" do - within ".budget-summary__total" do - expect(page).to have_content("TOTAL BUDGET €100,000") - end - expect(page).to have_content("ASSIGNED: €25,000") - within "#order-selected-projects" do - expect(page).to have_content "1 project selected" - end - within ".progress.budget-progress" do - expect(page).to have_css(".progress-meter-text.progress-meter-text--right", match: :first, text: "25%") - end - within page.all(".budget-list .budget-list__item")[1] do - click_button "Read more" - end - within ".reveal-overlay" do - click_button "Add to your vote" - end - page.find(".close-button").click - expect(page).to have_content("ASSIGNED: €50,000") - within "#order-selected-projects" do - expect(page).to have_content "2 projects selected" - end - within ".progress.budget-progress" do - expect(page).to have_css(".progress-meter-text.progress-meter-text--right", match: :first, text: "50%") - end - click_link "2" - click_button "Add to your vote", match: :first - expect(page).to have_content("ASSIGNED: €75,000") - within "#order-selected-projects" do - expect(page).to have_content "3 projects selected" - end - - within page.all(".budget-list .budget-list__item")[0] do - click_button "Read more" - end - within ".reveal-overlay" do - click_button "Remove from vote" - end - expect(page).to have_content("ASSIGNED: €50,000") - within "#order-selected-projects" do - expect(page).to have_content "2 projects selected" - end - end - end - - it "paginates the projects" do - expect(page).to have_css(".budget-list .budget-list__item", count: 5) - find("li.page", text: "2").click - expect(page).to have_css(".budget-list .budget-list__item", count: 5) - end - - it "adds and removes projects" do - expect(page).to have_button("Add to your vote", count: 5) - click_button("Add to your vote", match: :first) - expect(page).to have_button("Add to your vote", count: 4) - expect(page).to have_button("Remove from vote", count: 1) - - within page.all(".budget-list .budget-list__item")[0] do - header = page.all("button")[0].text - click_button "Read more" - expect(page).to have_content(header) - expect(page).to have_button("Remove from vote") - end - within ".reveal-overlay" do - click_button "Remove from vote" - expect(page).to have_button("Add to your vote", count: 1) - end - end - - describe "filtering projects" do - let!(:categories) { create_list(:category, 3, participatory_space: component.participatory_space) } - let(:current_projects) { first_budget.projects } - - it "allows searching by text" do - project = current_projects.first - within ".filters__search" do - fill_in "filter[search_text_cont]", with: translated(project.title) - - find(".button").click - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - - it "allows filtering by scope" do - project = current_projects.first - project.scope = first_budget.scope - project.save - visit current_path - - within ".filters__section.with_any_scope_check_boxes_tree_filter" do - uncheck "All" - check translated(first_budget.scope.name) - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - - it "allows filtering by category" do - project = current_projects.first - category = categories.first - project.category = category - project.save - - visit current_path - within ".filters__section.with_any_category_check_boxes_tree_filter" do - uncheck "All" - check translated(category.name) - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - end - - describe "#vote_success_content" do - before do - first_budget.update!(total_budget: 26_000) - end - - context "when vote_success_content is not set" do - before do - visit current_path - vote_budget! - end - - it "does not show the success message by default" do - expect(page).to have_no_selector("#thanks-message") - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end - - context "when vote success is set" do - before do - component.update!(settings: component_settings.merge(workflow: "zip_code", vote_success_content: { en: "

Some dummy text

" })) - visit current_path - vote_budget! - end - - it "shows the success message set" do - expect(page).to have_selector("#thanks-message") - within "#thanks-message" do - expect(page).to have_content("Thank you for voting!") - expect(page).to have_selector("p", text: "Some dummy text") - end - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end - end - - describe "vote_complete_content" do - let!(:order) { create(:order, user: user, budget: second_budget) } - - before do - first_budget.update!(total_budget: 26_000) - second_budget.update!(total_budget: 26_000) - order.checked_out_at = Time.current - order.projects << second_budget.projects.first - order.save! - end - - context "when not set" do - before do - visit current_path - vote_budget! - end - - it "does not show the modal" do - expect(page).to have_no_selector("#vote-completed") - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end - - context "when was set" do - before do - component.update!(settings: component_settings.merge(workflow: "zip_code", vote_completed_content: { en: "

Completed voting dummy text

" })) - visit current_path - vote_budget! - end - - it "shows the modal" do - expect(page).to have_selector("#vote-completed") - within "#vote-completed" do - expect(page).to have_content("You successfully completed your votes") - expect(page).to have_content("Completed voting dummy text") - end - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end - end - - describe "redirect after completing votes" do - let!(:order) { create(:order, user: user, budget: second_budget) } - - before do - first_budget.update!(total_budget: 26_000) - second_budget.update!(total_budget: 26_000) - order.checked_out_at = Time.current - order.projects << second_budget.projects.first - order.save! - end - - context "when vote success URL is not set" do - before do - visit current_path - vote_budget! - end - - it "redirects to the budgets path" do - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end - - context "when vote success URL is set" do - include_context "with a survey" - before do - component.update!(settings: component_settings.merge(workflow: "zip_code", vote_completed_content: { en: "

Completed voting dummy text

" }, vote_success_url: main_component_path(surveys_component))) - visit current_path - vote_budget! - end - - it "shows the modal" do - expect(page).to have_current_path(main_component_path(surveys_component)) - expect(page).to have_selector("#vote-completed") - within "#vote-completed" do - expect(page).to have_content("You successfully completed your votes") - expect(page).to have_content("Completed voting dummy text") - end - end - end - - context "when non-zipcode workflow" do - let!(:second_order) { create(:order, user: user, budget: budgets.last) } - let(:third_budget) { budgets.last } - - include_context "with a survey" - before do - third_budget.update!(total_budget: 26_000) - second_order.checked_out_at = Time.current - second_order.projects << third_budget.projects.first - second_order.save! - component.update!(settings: component_settings.merge(workflow: "all", vote_completed_content: { en: "

Completed voting dummy text

" }, vote_success_url: main_component_path(surveys_component))) - visit current_path - non_zipcode_vote_budget! - end - - it "shows the modal" do - expect(page).to have_current_path(main_component_path(surveys_component)) - expect(page).to have_selector("#vote-completed") - within "#vote-completed" do - expect(page).to have_content("You successfully completed your votes") - expect(page).to have_content("Completed voting dummy text") - end - end - end - end - - context "when maximum budget exceeds" do - before do - first_budget.update!(total_budget: 24_999) - visit current_path - end - - it "popups maximum error notice" do - click_button "Add to your vote", match: :first - expect(page).to have_content("Maximum budget exceeded") - click_button "OK" - within all(".budget-list .budget-list__item")[0] do - click_button "Read more" - end - within ".reveal-overlay" do - click_button "Add to your vote" - end - expect(page).to have_content("Maximum budget exceeded") - end - end - - context "when highest cost" do - before { first_budget.projects.second.update!(budget_amount: 30_000) } - - it_behaves_like "ordering projects by selected option", "Highest cost" do - let(:first_project) { first_budget.projects.second } - end - end - - context "when lowest cost" do - before { first_budget.projects.second.update!(budget_amount: 20_000) } - - it_behaves_like "ordering projects by selected option", "Lowest cost" do - let(:first_project) { first_budget.projects.second } - end - end - - context "when casting vote" do - before do - first_budget.update!(total_budget: 26_000) - visit current_path - click_button("Add to your vote", match: :first) - click_button "Vote" - end - - it "renders the info" do - within "#budget-confirm" do - expect(page).to have_content("These are the projects you have chosen to be part of the budget.") - expect(page).to have_selector("li", text: "€25,000", count: 1) - expect(page).to have_button("Confirm") - expect(page).to have_button("Cancel") - click_button("Cancel") - end - expect(page).to have_current_path(decidim_budgets.budget_voting_index_path(first_budget)) - end - end - - describe "#show_full_description_on_listing_page" do - let(:projects_count) { 1 } - let(:project) { first_budget.projects.first } - - before do - project.update!(description: Decidim::Faker::Localized.sentence(word_count: 20)) - end - - context "when not set" do - before do - visit current_path - end - - it "does not shows complete description by default" do - within("#project-#{project.id}-item") do - expect(page).to have_selector("button", text: translated(project.title)) - expect(page).to have_button("Read more") - expect(page).to have_content(/.*\.{3}$/) - end - end - end - - context "when set" do - before do - component.update!(settings: component_settings.merge(workflow: "zip_code", show_full_description_on_listing_page: true)) - visit current_path - end - - it "does not shows complete description by default" do - within("#project-#{project.id}-item") do - expect(page).to have_no_selector("button", text: translated(project.title)) - expect(page).to have_no_button("Read more") - expect(page).to have_no_content(/.*\.{3}$/) - expect(page).to have_content(translated(project.description)) - end - end - end - end - end - - private - - def decidim_budgets - Decidim::EngineRouter.main_proxy(component) - end - - def budget_path(budget) - decidim_budgets.budget_path(budget.id) - end - - def visit_budget(budget) - visit decidim_budgets.budget_voting_index_path(budget) - end - - def vote_budget! - click_button("Add to your vote", match: :first) - click_button "Vote" - click_button "Confirm" - end - - def non_zipcode_vote_budget! - click_button("Add to your vote", match: :first) - click_button "I understand how to vote" - click_button "I am ready" - click_button "Confirm" - end -end From 23b44e22e43dcbd68d8c5de6054fcb8e1037107b Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 27 Nov 2024 13:30:29 +0100 Subject: [PATCH 10/93] feat: update views and cells --- .../app/cells/decidim/budgets/project_g/show.erb | 1 - .../app/cells/decidim/budgets/project_g_cell.rb | 2 +- .../budgets_booth/projects_helper_extensions.rb | 4 ++++ .../views/decidim/budgets/projects/_projects.html.erb | 10 ++++++++++ .../layouts/decidim/budgets/_voting_menubar.html.erb | 8 +++++--- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb index 43691691..5189f94d 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb @@ -9,7 +9,6 @@
<%= content_tag title_tag, title, class: title_class %> - <%= translated_attribute(project.title) %>
<%= description.truncate_words(20) %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb index ebc08c0e..fb3e235a 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb @@ -20,7 +20,7 @@ def show end def title - present(model).title(html_escape: true) + decidim_escape_translated(model.title).html_safe end def metadata_cell = "decidim/budgets/project_metadata" diff --git a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb index 03f014e3..2e5b6a24 100644 --- a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb +++ b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb @@ -86,6 +86,10 @@ def projects_container_class(view_mode) def card_size_for_view_mode(view_mode) view_mode == "grid" ? :g : :l end + + def budget_title + decidim_escape_translated(budget.title).html_safe + end end end end diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb index 8464fefd..209f595a 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects.html.erb @@ -1,3 +1,13 @@ +
+
+ <%= render partial: "addition_selector" %> +
+ +
+ <%= render partial: "order" %> +
+
+
<%= render partial: "project", collection: projects, as: :project, locals: { card_size: card_size_for_view_mode(@view_mode) } %>
diff --git a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb index bbf5c448..8c79a570 100644 --- a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb +++ b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_menubar.html.erb @@ -13,11 +13,13 @@ <%= t('.cancel_voting') %> <% end %> <% end %> - - -

<%= translated_attribute(projects.first.budget.title) %>

+ - + <% if projects %> +

<%= budget_title %>

+ <% end %> <% if controller.action_name == "show" %> - - <%= link_to "Back to projects", budget_projects_path %> + <%= link_to t('layouts.decidim.budgets.voting_menubar.back_to_projects'), budget_projects_path %> <% end %>
From 7975b6ea5b2e2424b4b583a19caab00f6628bc62 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 27 Nov 2024 13:32:37 +0100 Subject: [PATCH 11/93] feat: update script addition depending on env --- .../budgets_booth/complete_voting_popup.rb | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index e2f5d83d..00189c25 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -26,11 +26,19 @@ def completed_vote_snippets HTML ) - # snippets.add(:head, helpers.javascript_pack_tag("decidim_handle_voting_complete")) - snippets.add(:head, <<~HTML - - HTML - ) + snippets.add(:head, add_javascript_file) + end + + def add_javascript_file + if Rails.env.test? + <<~HTML + + HTML + else + <<~HTML + + HTML + end end end end From 205a43927dda9ff9df3920e57d400daf19dc1ad6 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 27 Nov 2024 13:34:20 +0100 Subject: [PATCH 12/93] test: add new test files --- .../decidim/budgets/project_g_cell_spec.rb | 53 ++ decidim-budgets_booth/spec/factories.rb | 2 + .../spec/system/explore_budgets_spec.rb | 148 ++++ .../spec/system/explore_projects_spec.rb | 186 ++++ .../spec/system/orders_spec.rb | 813 ++++++++++++++++++ .../spec/system/sorting_projects_spec.rb | 124 +++ 6 files changed, 1326 insertions(+) create mode 100644 decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb create mode 100644 decidim-budgets_booth/spec/system/explore_budgets_spec.rb create mode 100644 decidim-budgets_booth/spec/system/explore_projects_spec.rb create mode 100644 decidim-budgets_booth/spec/system/orders_spec.rb create mode 100644 decidim-budgets_booth/spec/system/sorting_projects_spec.rb diff --git a/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb b/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb new file mode 100644 index 00000000..4d1d320a --- /dev/null +++ b/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim::Budgets + describe ProjectGCell, type: :cell do + controller Decidim::Budgets::ProjectsController + + subject(:cell_html) { my_cell.call } + + + let(:my_cell) { cell("decidim/budgets/project_g", project, card_size: :g) } + let!(:organization) { create(:organization) } + let!(:budgets_component) { create(:budgets_component, organization:) } + let(:budget) { create(:budget, component: budgets_component) } + let(:slug) { budgets_component.participatory_space.slug } + let(:process_id) { budgets_component.participatory_space.id } + let!(:project) { create(:project, budget:, component: budgets_component) } + + before do + allow(controller).to receive(:current_component).and_return(budgets_component) + # avoid rendering project_vote_button that we don't test here + allow(my_cell).to receive(:cell).and_return("") + end + + describe "show" do + it "renders the project item with appropriate id" do + expect(subject).to have_css("#project-#{project.id}-item") + end + + it "renders the project title" do + expect(subject.text).to include(translated_attribute(project.title)) + end + + context "when the project has an image" do + let!(:attachment) { create(:attachment, attached_to: project) } + + it "renders the project with an image" do + expect(subject).to have_css("img[src*='city']") + end + end + + context "when the project has no image" do + before { allow(project).to receive(:attachments).and_return([]) } + + it "renders a placeholder image" do + expect(subject).to have_css(".card__project-placeholder-g") + end + end + end + end +end + diff --git a/decidim-budgets_booth/spec/factories.rb b/decidim-budgets_booth/spec/factories.rb index 50648265..c007b36d 100644 --- a/decidim-budgets_booth/spec/factories.rb +++ b/decidim-budgets_booth/spec/factories.rb @@ -3,4 +3,6 @@ require "decidim/core/test/factories" require "decidim/budgets/test/factories" require "decidim/surveys/test/factories" +require "decidim/proposals/test/factories" require "decidim/budgets_booth/test/factories" + diff --git a/decidim-budgets_booth/spec/system/explore_budgets_spec.rb b/decidim-budgets_booth/spec/system/explore_budgets_spec.rb new file mode 100644 index 00000000..c326f510 --- /dev/null +++ b/decidim-budgets_booth/spec/system/explore_budgets_spec.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Explore Budgets", :slow do + include ActionView::Helpers::NumberHelper + + include_context "with a component" + let(:manifest_name) { "budgets" } + + let!(:component) do + create(:budgets_component, + :with_vote_threshold_percent, + manifest:, + participatory_space: participatory_process) + end + + context "with no budgets" do + it "shows an empty page with a message" do + visit_component + + expect(page).to have_content("There are no budgets yet") + end + end + + context "with only one budget" do + let!(:budgets) { create_list(:budget, 1, component:) } + + it "redirects to the only budget details" do + visit_component + + expect(page).to have_content("Projects for") + expect(page).to have_content(translated(budgets.first.title)) + end + end + + context "with many budgets" do + let!(:budgets) do + 1.upto(6).to_a.map { |x| create(:budget, component:, weight: x, total_budget: x * 10_000_000, description: { en: "This is budget #{x}" }) } + end + + before do + visit_component + end + + it "shows the component name in the sidebar" do + within("aside") do + expect(page).to have_content(translated(component.name)) + end + end + + it "lists all the budgets" do + expect(page).to have_css(".card--list__item", count: 6) + + budgets.each do |budget| + expect(page).to have_content(translated(budget.title)) + expect(page).to have_content(number_to_currency(budget.total_budget, unit: Decidim.currency_unit, precision: 0)) + end + expect(page).to have_no_content("Remove vote") + expect(page).to have_content("0 projects") + end + + describe "budget list item" do + let!(:component) do + create(:budgets_component, + :with_vote_threshold_percent, + manifest:, + participatory_space: participatory_process, + settings: { landing_page_content: description }) + end + let(:description) { { en: "Short description", ca: "Descripció curta", es: "Descripción corta" } } + let(:budget) { budgets.first } + let(:item) { page.find("#budgets .card--list__item", match: :first) } + let!(:projects) { create_list(:project, 3, budget:, budget_amount: 10_000_000) } + + before do + login_as user, scope: :user + end + + it_behaves_like "has embedded video in description", :description + + it "has a clickable title" do + expect(item).to have_link(translated(budget.title), href: budget_path(budget)) + end + + context "when an item is bookmarked" do + let!(:order) { create(:order, user:, budget:) } + let!(:line_item) { create(:line_item, order:, project: projects.first) } + + it "shows a finish voting link" do + visit_component + + expect(item).to have_link("Finish voting", href: budget_path(budget)) + end + + it "shows the projects count and it has no remove vote link" do + visit_component + + expect(page).to have_no_content("Remove vote") + expect(item).to have_content("3 projects") + end + end + + context "when an item is voted" do + let(:item) { page.find("#voted-budgets .card--list__item:first-child") } + + let!(:order) do + order = create(:order, user:, budget:) + order.projects = [projects.first] + order.checked_out_at = Time.current + order.save! + order + end + + it "shows the check icon" do + visit_component + + expect(item).to have_css("div.card__highlight-text svg.fill-success") + expect(item).to have_link("See projects", href: budget_path(budget)) + end + + it "shows the projects count" do + expect(page).to have_content("0 projects") + end + + it "has a link to remove vote" do + visit_component + + expect(item).to have_content("delete your vote") + within item do + accept_confirm { click_on "delete your vote" } + expect(Decidim::Budgets::Order.where(budget:)).to be_blank + end + end + end + end + end + + context "when directly accessing from URL with an invalid budget id" do + it_behaves_like "a 404 page" do + let(:target_path) { Decidim::EngineRouter.main_proxy(component).budget_path(99_999_999) } + end + end + + def budget_path(budget) + Decidim::EngineRouter.main_proxy(component).budget_path(budget.id) + end +end diff --git a/decidim-budgets_booth/spec/system/explore_projects_spec.rb b/decidim-budgets_booth/spec/system/explore_projects_spec.rb new file mode 100644 index 00000000..515b1d22 --- /dev/null +++ b/decidim-budgets_booth/spec/system/explore_projects_spec.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Explore projects", :slow do + include_context "with a component" + let(:manifest_name) { "budgets" } + let(:budget) { create(:budget, component: component) } + let(:projects_count) { 5 } + let!(:projects) do + create_list(:project, projects_count, budget: budget) + end + let!(:project) { projects.first } + let(:categories) { create_list(:category, 3, participatory_space: component.participatory_space) } + + describe "show" do + let(:description) { { en: "Short description", ca: "Descripció curta", es: "Descripción corta" } } + let(:project) { create(:project, budget: budget, description: description) } + + before do + visit_budget + find("a[id=project-#{project.id}-item]").click + end + + # no footer in custom budgets_booth, so no cookie settings + # it_behaves_like "has embedded video in description", :description + + it "has a link to go back to index page" do + expect(page).to have_link("Back to projects") + end + end + + describe "index" do + context "when there are no projects" do + let!(:projects) { nil } + let(:project) { nil } + + it "shows an empty page with a message" do + visit_budget + expect(page).to have_content("There are no projects yet") + end + end + + it "shows all resources for the given component with grid view by default" do + visit_budget + within "#projects" do + expect(page).to have_css(".card__grid", count: projects_count) + end + + projects.each do |project| + expect(page).to have_content(translated(project.title)) + end + end + + it "switches to list views and back to grid view" do + visit_budget + find("a[title='List mode']").click + within "#projects" do + expect(page).to have_css(".card__list", count: projects_count) + end + + find("a[title='Grid mode']").click + within "#projects" do + expect(page).to have_css(".card__grid", count: projects_count) + end + end + + context "when filtering" do + it "allows searching by text" do + visit_budget + within "aside form.new_filter" do + fill_in "filter[search_text_cont]", with: translated(project.title) + + within "div.filter-search" do + click_on + end + end + + within "#projects" do + expect(page).to have_css(".card__grid", count: 1) + expect(page).to have_content(translated(project.title)) + end + end + + it "updates the current URL with the text filter" do + create(:project, budget: budget, title: { en: "Foobar project" }) + create(:project, budget: budget, title: { en: "Another project" }) + visit_budget + + within "aside form.new_filter" do + fill_in("filter[search_text_cont]", with: "foobar") + within "div.filter-search" do + click_on + end + end + + expect(page).to have_no_content("Another project") + expect(page).to have_content("Foobar project") + + filter_params = CGI.parse(URI.parse(page.current_url).query) + expect(filter_params["filter[search_text_cont]"]).to eq(["foobar"]) + end + + it "allows filtering by scope" do + scope = create(:scope, organization: organization) + project.scope = scope + project.save + + visit_budget + + within "#panel-dropdown-menu-scope" do + click_filter_item translated(scope.name) + end + + within "#projects" do + expect(page).to have_css(".card__grid", count: 1) + expect(page).to have_content(translated(project.title)) + end + end + + it "allows filtering by category" do + category = categories.first + project.category = category + project.save + + visit_budget + + within "#panel-dropdown-menu-category" do + click_filter_item decidim_escape_translated(category.name) + end + + within "#projects" do + expect(page).to have_css(".card__grid", count: 1) + expect(page).to have_content(translated(project.title)) + end + end + + context "and votes are finished" do + let!(:component) do + create(:budgets_component, + :with_voting_finished, + manifest: manifest, + participatory_space: participatory_process) + end + + it "allows filtering by status" do + project.selected_at = Time.current + project.save + + visit_budget + + within "#panel-dropdown-menu-status" do + click_filter_item "Selected" + end + + within "#projects" do + expect(page).to have_css(".card__grid", count: 1) + expect(page).to have_content(translated(project.title)) + end + end + end + end + + context "when directly accessing from URL with an invalid budget id" do + it_behaves_like "a 404 page" do + let(:target_path) { decidim_budgets.budget_projects_path(99_999_999) } + end + end + + context "when directly accessing from URL with an invalid project id" do + it_behaves_like "a 404 page" do + let(:target_path) { decidim_budgets.budget_project_path(budget, 99_999_999) } + end + end + end + + private + + def decidim_budgets + Decidim::EngineRouter.main_proxy(component) + end + + def visit_budget + page.visit decidim_budgets.budget_projects_path(budget) + end +end diff --git a/decidim-budgets_booth/spec/system/orders_spec.rb b/decidim-budgets_booth/spec/system/orders_spec.rb new file mode 100644 index 00000000..7e1851d4 --- /dev/null +++ b/decidim-budgets_booth/spec/system/orders_spec.rb @@ -0,0 +1,813 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Orders" do + include_context "with a component" + let(:manifest_name) { "budgets" } + + let(:organization) { create(:organization, available_authorizations: %w(dummy_authorization_handler)) } + let!(:user) { create(:user, :confirmed, organization:) } + let(:project) { projects.first } + + let!(:component) do + create(:budgets_component, + :with_vote_threshold_percent, + manifest:, + participatory_space: participatory_process) + end + let(:budget) { create(:budget, component:) } + + context "when the user is not logged in" do + let!(:projects) { create_list(:project, 1, budget:, budget_amount: 25_000_000) } + + it "is given the option to sign in" do + visit_budget + + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_css("#loginModal", visible: :visible) + end + end + + context "when the user is logged in" do + let!(:projects) { create_list(:project, 3, budget:, budget_amount: 25_000_000) } + + before do + login_as user, scope: :user + end + + context "when visiting budget" do + before do + visit_budget + end + + it "shows a filter to select added projects" do + within(".budget__list--header") do + expect(page).to have_text("Added") + end + end + + context "when voting by percentage threshold" do + it "displays description messages" do + within ".budget-summary", match: :first do + expect(page).to have_content("Start adding projects. Assign at least €70,000,000 to the projects you want and vote according to your preferences to define the budget.") + end + end + end + + context "when voting by minimum projects number" do + let!(:component) do + create(:budgets_component, + :with_minimum_budget_projects, + manifest:, + participatory_space: participatory_process) + end + + it "displays description messages" do + within ".budget-summary", match: :first do + expect(page).to have_content("Start adding projects. Select at least 3 projects you want and vote according to your preferences to define the budget.") + end + end + end + + context "when voting by maximum projects number" do + let!(:component) do + create(:budgets_component, + :with_budget_projects_range, + vote_minimum_budget_projects_number: 0, + manifest:, + participatory_space: participatory_process) + end + + it "displays description messages" do + within ".budget-summary", match: :first do + expect(page).to have_content("Start adding projects. Select up to 6 projects you want and vote according to your preferences to define the budget.") + end + end + end + + context "when voting by minimum and maximum projects number" do + let!(:component) do + create(:budgets_component, + :with_budget_projects_range, + manifest:, + participatory_space: participatory_process) + end + + it "displays description messages" do + within ".budget-summary", match: :first do + expect(page).to have_content("Start adding projects. Select at least 3 and up to 6 projects you want and vote according to your preferences to define the budget.") + end + end + end + + context "when the total budget is zero" do + let(:budget) { create(:budget, total_budget: 0, component:) } + + it "displays total budget" do + within ".budget-summary", match: :first do + expect(page).to have_content("€0\nBudget") + end + end + end + end + + context "and has not a pending order" do + before do + visit_budget + end + + context "when voting by percentage threshold" do + it "adds a project to the current order" do + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_text "Remove from vote", count: 1 + + within ".budget-summary__progressbar-marks", match: :first do + expect(page).to have_content(/€25,000,000\sAssigned/) + end + within ".budget__list--header" do + expect(page).to have_content(/Added\s1/) + end + + within "#order-progress .budget-summary__content", match: :first do + expect(page).to have_css ".budget-summary__progressbar--meter", style: "width: 25%" + expect(page).to have_button(disabled: true, text: "Vote budget") + end + end + + it "displays total budget" do + expect(page).to have_css(".budget-summary__progressbar-marks_right", text: "€100,000,000") + end + end + + context "when voting by minimum projects number" do + let!(:component) do + create(:budgets_component, + :with_minimum_budget_projects, + manifest:, + participatory_space: participatory_process) + end + + it "adds a project to the current order" do + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_text "Remove from vote", count: 1 + + within ".budget-summary__progressbar-marks", match: :first do + expect(page).to have_content(/€25,000,000\sAssigned/) + end + within ".budget__list--header" do + expect(page).to have_content(/Added\s1/) + end + + within "#order-progress .budget-summary__content", match: :first do + expect(page).to have_css ".budget-summary__progressbar--meter", style: "width: 25%" + expect(page).to have_button(disabled: true, text: "Vote budget") + end + end + + it "displays total budget" do + expect(page).to have_css(".budget-summary__progressbar-marks_right", text: "€100,000,000") + end + end + + context "when voting by maximum projects number" do + let!(:component) do + create(:budgets_component, + :with_budget_projects_range, + vote_minimum_budget_projects_number: 0, + manifest:, + participatory_space: participatory_process) + end + + it "adds a project to the current order" do + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_text "Remove from vote", count: 1 + + within ".budget-summary__progressbar-marks", match: :first do + expect(page).to have_content "1 / 6" + end + within ".budget__list--header" do + expect(page).to have_content(/Added\s1/) + end + + within "#order-progress .budget-summary__content", match: :first do + expect(page).to have_css ".budget-summary__progressbar--meter", style: "width: 16%" + expect(page).to have_button(text: "Vote budget") + end + end + + it "displays total budget" do + expect(page).to have_css(".budget-summary__progressbar-marks_right", text: "6") + end + end + + context "when voting by minimum and maximum projects number" do + let!(:component) do + create(:budgets_component, + :with_budget_projects_range, + manifest:, + participatory_space: participatory_process) + end + + it "adds a project to the current order" do + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_text "Remove from vote", count: 1 + within ".budget-summary__progressbar-marks", match: :first do + expect(page).to have_content "1 / 6" + end + within ".budget__list--header" do + expect(page).to have_content(/Added\s1/) + end + + within "#order-progress .budget-summary__content", match: :first do + expect(page).to have_css ".budget-summary__progressbar--meter", style: "width: 16%" + expect(page).to have_button(disabled: true, text: "Vote budget") + end + end + + it "displays total budget" do + expect(page).to have_css(".budget-summary__progressbar-marks_right", text: "6") + end + end + end + + context "and is not authorized" do + before do + permissions = { + vote: { + authorization_handlers: { + "dummy_authorization_handler" => {} + } + } + } + + component.update!(permissions:) + end + + it "shows a modal dialog" do + visit_budget + + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_content("Authorization required") + end + end + + context "and has pending order" do + let!(:order) { create(:order, user:, budget:) } + let!(:line_item) { create(:line_item, order:, project:) } + + it "removes a project from the current order" do + visit_budget + + within ".budget-summary__progressbar-marks", match: :first do + expect(page).to have_content(/€25,000,000\sAssigned/) + end + within ".budget__list--header" do + expect(page).to have_content(/Added\s1/) + end + + within "#project-#{project.id}-item" do + page.find(".budget-list__action").click + end + + within ".budget-summary__progressbar-marks", match: :first do + expect(page).to have_content(/€0\sAssigned/) + end + within ".budget__list--header" do + expect(page).to have_content(/Added\s0/) + end + expect(page).to have_css ".budget-summary__progressbar--meter", style: "width: 0%" + expect(page).to have_no_css ".budget-list__data--added" + end + + it "is alerted when trying to leave the component before completing" do + budget_projects_path = Decidim::EngineRouter.main_proxy(component).budget_projects_path(budget) + + visit_budget + + expect(page).to have_content "€25,000,000" + + page.find(".menu-bar__exit-link").click + + expect(page).to have_content "You have not yet voted" + + click_on "Return to voting" + + expect(page).to have_no_content("You have not yet voted") + expect(page).to have_current_path budget_projects_path + end + + # no logout in custom budget booth + + # it "is alerted but can sign out before completing" do + # visit_budget + + # within_user_menu do + # click_on("Log out") + # end + + # expect(page).to have_content "You have not yet voted" + + # page.find_by_id("exit-notification-link").click + # expect(page).to have_content("Logged out successfully") + #end + + context "and try to vote a project that exceed the total budget" do + let!(:expensive_project) { create(:project, budget:, budget_amount: 250_000_000) } + + it "cannot add the project" do + visit_budget + + within "#project-#{expensive_project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_css("#budget-excess", visible: :visible) + end + end + + context "and in project show page cannot exceed the budget" do + let!(:expensive_project) { create(:project, budget:, budget_amount: 250_000_000) } + + it "cannot add the project" do + page.visit Decidim::EngineRouter.main_proxy(component).budget_project_path(budget, expensive_project) + + click_on "Add to your vote" + + expect(page).to have_css("#budget-excess", visible: :visible) + end + end + + context "and add another project exceeding vote threshold" do + let!(:other_project) { create(:project, budget:, budget_amount: 50_000_000) } + + it "can complete the checkout process" do + visit_budget + + within "#project-#{other_project.id}-item" do + page.find(".budget-list__action").click + end + + expect(page).to have_text "Remove from vote", count: 2 + + within "#order-progress .budget-summary__content", match: :first do + page.find(".button", match: :first).click + end + + expect(page).to have_css("#budget-confirm", visible: :visible) + + within "#budget-confirm" do + page.find(".button", text: "Confirm").click + end + + within "#order-progress .budget-summary__content", match: :first do + expect(page).to have_css(".button", text: "delete your vote") + end + end + end + + context "when the voting rule is set to threshold percent" do + before do + visit_budget + end + + it "shows the rule description" do + within ".budget-summary", match: :first do + expect(page).to have_content("Assign at least €70,000,000 to the projects you want and vote") + end + end + + context "when the order total budget does not exceed the threshold" do + it "cannot vote" do + within "#order-progress", match: :first do + expect(page).to have_button("Vote", disabled: true) + end + end + end + + context "when the order total budget exceeds the threshold" do + let(:projects) { create_list(:project, 2, budget:, budget_amount: 36_000_000) } + let(:order_percent) { create(:order, user:, budget:) } + + before do + order.destroy! + order_percent.projects << projects + order_percent.save! + visit_budget + end + + it "can vote" do + within "#order-progress", match: :first do + expect(page).to have_button("Vote", disabled: false) + end + end + + context "when user has voted" do + let(:router) { Decidim::EngineRouter.main_proxy(component) } + let(:another_user) { create(:user, :confirmed, organization:) } + + before do + find("[data-dialog-open='budget-confirm']", match: :first).click + click_on "Confirm" + end + + it "shows private-only activity log entry" do + page.visit decidim.profile_activity_path(nickname: user.nickname) + expect(page).to have_content("New budgeting vote at #{translated(budget.title)}") + expect(page).to have_link(translated(budget.title), href: router.budget_path(budget)) + end + + it "does not show activity log entry to another user" do + relogin_as another_user, scope: :user + page.visit decidim.profile_activity_path(nickname: user.nickname) + expect(page).to have_content(user.name) + expect(page).to have_current_path "/profiles/#{user.nickname}/activity" + expect(page).to have_no_content("New budgeting vote at") + expect(page).to have_no_link(translated(budget.title)) + end + end + end + end + + context "when the voting rule is set to minimum projects" do + before do + order.destroy! + end + + let(:component) do + create(:budgets_component, + :with_minimum_budget_projects, + manifest:, + participatory_space: participatory_process) + end + + let!(:order_min) { create(:order, user:, budget:) } + + it "shows the rule description" do + visit_budget + + within ".budget-summary", match: :first do + expect(page).to have_content("Select at least 3 projects you want and vote") + end + end + + context "when the order total budget does not reach the minimum" do + it "cannot vote" do + visit_budget + + within "#order-progress", match: :first do + expect(page).to have_button("Vote", disabled: true) + end + end + end + + context "when the order total budget exceeds the minimum" do + before do + order_min.projects = projects + order_min.save! + end + + it "can vote" do + visit_budget + + within "#order-progress", match: :first do + expect(page).to have_button("Vote", disabled: false) + end + end + end + end + + context "when maximum budget to vote on is set to 1 and vote_completed_content is set" do + let!(:component) do + create(:budgets_component, + manifest:, + participatory_space: participatory_process, + settings: { maximum_budgets_to_vote_on: 1, vote_completed_content: "You have completed your votes" } + ) + end + let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } + let(:budget_two) { create(:budget, component:) } + let!(:projects_two) { create_list(:project, 3, budget: budget_two, budget_amount: 25_000_000) } + + it "can only vote for one budget and display the vote-conpleted modal" do + visit_budget + #confirm the pending order + within ".budget-summary__progressbox-buttons" do + page.find('button').click + end + expect(page).to have_css("#budget-confirm", visible: :visible) + + within "#budget-confirm" do + page.find(".button", text: "Confirm").click + end + + # after voting complete, redirected with vote-conpleted modal + expect(page).to have_content("You have completed your votes") + + within "#vote-completed" do + page.find(".button", text: "Continue").click + end + + expect(page).to have_content("You have voted on the maximum budgets allowed.") + + # can't access projects from second budget + within "#budgets" do + within ".budget__card__highlight-vote" do + expect(page).to have_button('See projects', disabled: true) + end + end + end + end + + context "and vote_success_url is defined" do + let!(:component) do + create(:budgets_component, + manifest:, + participatory_space: participatory_process, + settings: { vote_success_url: "/processes" } + ) + end + let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } + + it "redirects to vote_success_url when order is confirmed" do + visit_budget + # confirm the pending order + within ".budget-summary__progressbox-buttons" do + page.find('button').click + end + expect(page).to have_css("#budget-confirm", visible: :visible) + + within "#budget-confirm" do + page.find(".button", text: "Confirm").click + end + # check we are in processes index + expect(page).to have_css("h1", text: "Processes") + end + end + + context "and vote_cancel_url is defined" do + let!(:component) do + create(:budgets_component, + manifest:, + participatory_space: participatory_process, + settings: { vote_cancel_url: "/processes" } + ) + end + + it "redirects to vote_cancel_url when order is cancelled" do + visit_budget + # exit voting booth with pending order + within "#menu-bar-custom" do + page.find('.menu-bar__exit-link').click + end + # click on exit button in modal + within "#exit-notification-content" do + page.find('#exit-notification-link').click + end + # check we are in processes index + expect(page).to have_css("h1", text: "Processes") + end + end + + context "and vote_success_content is defined" do + let!(:component) do + create(:budgets_component, + manifest:, + participatory_space: participatory_process, + settings: { maximum_budgets_to_vote_on: 5, vote_success_content: "Thanks for voting to that great budget" } + ) + end + let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } + let(:budget_two) { create(:budget, component:) } + let!(:projects_two) { create_list(:project, 3, budget: budget_two, budget_amount: 25_000_000) } + + it "displays a modal with vote_success_content text after voting for one budget" do + visit_budget + # confirm the pending order + within ".budget-summary__progressbox-buttons" do + page.find('button').click + end + expect(page).to have_css("#budget-confirm", visible: :visible) + + within "#budget-confirm" do + page.find(".button", text: "Confirm").click + end + + # check we have the modal with the message + expect(page).to have_css("#thanks-message") + expect(page).to have_content("Thanks for voting to that great budget") + end + end + end + + context "and has a finished order" do + let!(:order) do + order = create(:order, user:, budget:) + order.projects = projects + order.checked_out_at = Time.current + order.save! + order + end + + it "can cancel the order" do + visit_budget + + within ".budget-summary__content", match: :first do + accept_confirm { page.find(".cancel-order", match: :first).click } + end + + expect(page).to have_content("successfully") + + within "#order-progress .budget-summary__content", match: :first do + expect(page).to have_button(disabled: true) + end + + within ".budget-summary__content", match: :first do + expect(page).to have_no_css(".button", text: "delete your vote") + end + end + + it "is not alerted when trying to leave the component" do + visit_budget + + expect(page).to have_content("Budget vote completed") + + page.find(".menu-bar__exit-link").click + + expect(page).to have_current_path decidim.root_path + end + end + + context "and votes are disabled" do + let!(:component) do + create(:budgets_component, + :with_votes_disabled, + manifest:, + participatory_space: participatory_process) + end + + it "cannot create new orders" do + visit_budget + + expect(page).to have_no_button(class: "budget-list__action") + end + end + + #context "and show votes are enabled" do + # let!(:component) do + # create(:budgets_component, + # :with_show_votes_enabled, + # manifest:, + # participatory_space: participatory_process) + # end + + # let!(:order) do + # order = create(:order, user:, budget:) + # order.projects = projects + # order.checked_out_at = Time.current + # order.save! + # order + # end + + #it "displays the number of votes for a project" do + # visit_budget + + # within "#project-#{project.id}-item .card__grid" do + # expect(page).to have_css(".project-votes", text: "1 vote") + # end + # end + #end + + context "and votes are finished" do + let!(:component) do + create(:budgets_component, + :with_voting_finished, + manifest:, + participatory_space: participatory_process) + end + let!(:projects) { create_list(:project, 2, :selected, budget:, budget_amount: 25_000_000) } + + it "renders selected projects" do + visit_budget + + expect(page).to have_css(".card__list-metadata .success", count: 2) + end + + it "does not show a filter to select added projects" do + visit_budget + + within(".budget__list--header") do + expect(page).to have_no_text("Added") + end + end + end + end + + describe "index" do + it "respects the projects_per_page setting when under total projects" do + component.update!(settings: { projects_per_page: 1 }) + + create_list(:project, 2, budget:) + + visit_budget + + expect(page).to have_css("a[id^=project-]", count: 1) + end + + it "respects the projects_per_page setting when it matches total projects" do + component.update!(settings: { projects_per_page: 2 }) + + create_list(:project, 2, budget:) + + visit_budget + + expect(page).to have_css("a[id^=project-]", count: 2) + end + + it "respects the projects_per_page setting when over total projects" do + component.update!(settings: { projects_per_page: 3 }) + + create_list(:project, 2, budget:) + + visit_budget + + expect(page).to have_css("a[id^=project-]", count: 2) + end + end + + describe "show" do + let!(:project) { create(:project, budget:, budget_amount: 25_000_000) } + + before do + visit resource_locator([budget, project]).path + end + + it_behaves_like "has attachments tabs" do + let(:attached_to) { project } + end + + it "shows the component" do + expect(page).to have_i18n_content(project.title, strip_tags: true) + expect(page).to have_i18n_content(project.description, strip_tags: true) + end + + context "with linked proposals" do + let(:proposal_component) do + create(:component, manifest_name: :proposals, participatory_space: project.component.participatory_space) + end + let(:proposals) { create_list(:proposal, 3, component: proposal_component) } + + before do + project.link_resources(proposals, "included_proposals") + end + + it "shows related proposals" do + visit_budget + find("a[id=project-#{project.id}-item]").click + + proposals.each do |proposal| + expect(page).to have_content(translated(proposal.title)) + expect(page).to have_content(proposal.creator_author.name) + expect(page).to have_content(proposal.endorsements.size) + end + end + + context "with votes enabled" do + let(:proposal_component) do + create(:proposal_component, :with_votes_enabled, participatory_space: project.component.participatory_space) + end + + let(:proposals) { create_list(:proposal, 1, :with_votes, component: proposal_component) } + + it "does not show the amount of votes" do + visit_budget + find("a[id=project-#{project.id}-item]").click + + expect(page).to have_no_css(".card__list-metadata", text: "5") + end + end + end + end + + def visit_budget + page.visit Decidim::EngineRouter.main_proxy(component).budget_projects_path(budget) + end +end diff --git a/decidim-budgets_booth/spec/system/sorting_projects_spec.rb b/decidim-budgets_booth/spec/system/sorting_projects_spec.rb new file mode 100644 index 00000000..04c4d0dd --- /dev/null +++ b/decidim-budgets_booth/spec/system/sorting_projects_spec.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Sorting projects" do + include_context "with a component" + let(:manifest_name) { "budgets" } + + let(:organization) { create(:organization) } + let!(:user) { create(:user, :confirmed, organization:) } + let(:project) { projects.first } + + let!(:component) do + create(:budgets_component, + :with_vote_threshold_percent, + manifest:, + participatory_space: participatory_process) + end + + let(:budget) { create(:budget, component:) } + let!(:project1) { create(:project, budget:, budget_amount: 25_000_000) } + let!(:project2) { create(:project, budget:, budget_amount: 50_000_000) } + + before do + login_as user, scope: :user + visit_budget + end + + shared_examples "ordering projects by selected option" do |selected_option| + before do + visit_budget + within ".order-by" do + expect(page).to have_css("div.order-by a", text: "Random order") + page.find("a", text: "Random order").click + click_on(selected_option) + end + end + + it "lists the projects ordered by selected option" do + within "#projects div[data-collection-sort-controls]" do + expect(page).to have_no_css("a.underline.font-bold", text: "Random order") + expect(page).to have_css("a.underline.font-bold", text: selected_option) + end + + expect(page).to have_css("#projects .card__grid-grid .card__grid:first-child h3", text: translated(first_project.title)) + expect(page).to have_css("#projects .card__grid-grid .card__grid:last-child h3", text: translated(last_project.title)) + end + end + + context "when ordering by highest cost" do + it_behaves_like "ordering projects by selected option", "Highest cost" do + let(:first_project) { project2 } + let(:last_project) { project1 } + end + end + + context "when ordering by lowest cost" do + it_behaves_like "ordering projects by selected option", "Lowest cost" do + let(:first_project) { project1 } + let(:last_project) { project2 } + end + end + + describe "when the voting is finished" do + let!(:component) do + create( + :budgets_component, + :with_voting_finished, + manifest:, + participatory_space: participatory_process + ) + end + let!(:project1) { create(:project, :selected, budget:, budget_amount: 25_000_000) } + let!(:project2) { create(:project, :selected, budget:, budget_amount: 77_000_000) } + + context "when ordering by most votes" do + before do + order = build(:order, budget:) + create(:line_item, order:, project: project2) + order = Decidim::Budgets::Order.last + order.checked_out_at = Time.zone.now + order.save + end + + it "automatically sorts by votes" do + visit_budget + + within "#projects div[data-collection-sort-controls]" do + expect(page).to have_css("a.underline.font-bold", text: "Most voted") + end + + expect(page).to have_css("#projects .card__grid-grid .card__grid:first-child h3", text: translated(project2.title)) + expect(page).to have_css("#projects .card__grid-grid .card__grid:last-child h3", text: translated(project1.title)) + end + + it "automatically sorts by votes and respect the pagination" do + component.update!(settings: { projects_per_page: 1 }) + + visit_budget + + within "#projects div.order-by" do + expect(page).to have_css("a.underline.font-bold", text: "Most voted") + end + + # project2 on first page + expect(page).to have_content(translated(project2.title)) + expect(page).to have_no_content(translated(project1.title)) + + within "#projects [data-pagination]" do + expect(page).to have_content("2") + page.find("a", text: "2").click + end + + # project1 on second page + expect(page).to have_no_content(translated(project2.title)) + expect(page).to have_content(translated(project1.title)) + end + end + end + + def visit_budget + page.visit Decidim::EngineRouter.main_proxy(component).budget_projects_path(budget) + end +end From dc4f1bd1227234fbcbd15597bf3937120bb35cd8 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 27 Nov 2024 13:35:15 +0100 Subject: [PATCH 13/93] feat: update project index --- .../app/views/decidim/budgets/projects/index.html.erb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb index eda578d1..0037f76d 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb @@ -1,6 +1,6 @@ <% add_decidim_meta_tags( description: translated_attribute(budget.description), - title: t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)), + title: t("decidim.budgets.projects.projects_for", name: budget_title), url: budget_url(budget), resource: budget) %> @@ -12,7 +12,7 @@ <%= cell("decidim/budgets/budget_information_modal", budget) %> <% content_for :aside do %> -

<%= t("decidim.budgets.projects.projects_for", name: translated_attribute(budget.title)) %>

+

<%= t("decidim.budgets.projects.projects_for", name: budget_title) %>

<%= render layout: "decidim/shared/filters", locals: { filter_sections: , search_variable: :search_text_cont, skip_to_id: "projects" } do %> <%= hidden_field_tag :order, order, id: nil, class: "order_filter" %> @@ -28,10 +28,7 @@ <%= cell("decidim/budgets/limit_announcement", budget) %>
-

Projects for Vote

-
- <%= render partial: "order" %> -
+

<%= t '.title' %>

- -
- <%= render partial: "project", collection: projects, as: :project, locals: { card_size: card_size_for_view_mode(@view_mode) } %> +
+ <%= render partial: "projects_list", locals: { project: } %>
<%= decidim_paginate projects %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects_list.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects_list.html.erb new file mode 100644 index 00000000..38d19846 --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_projects_list.html.erb @@ -0,0 +1,5 @@ +
+ <% projects.each do |project| %> + <%= render partial: "project", locals: { project:, card_size: card_size_for_view_mode(@view_mode) } %> + <% end %> +
diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb index 0037f76d..6055017d 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb @@ -5,7 +5,6 @@ resource: budget) %> <%= append_javascript_pack_tag "decidim_budgets" %> -<%= append_javascript_pack_tag "decidim_budgets_booth_voting" %> <%= append_stylesheet_pack_tag "decidim_budgets" %> <%= render partial: "budget_summary", locals: { include_heading: true, project_item: false, responsive: true } %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.js.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.js.erb index ce72155a..2312447f 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.js.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.js.erb @@ -1,11 +1,11 @@ -var $projects = $('#projects'); +var $projects = $('#projects .budget-list'); +var $order = $('.budget__list--header [data-collection-sort-controls]'); var $projectsCount = $('#projects-count'); var $orderFilterInput = $('.order_filter'); -$projects.html('<%= j(render partial: "projects").strip.html_safe %>'); +$projects.html('<%= j(render partial: "projects_list").strip.html_safe %>'); +$order.html('<%= j(render partial: "order").strip.html_safe %>'); $projectsCount.html('<%= j(render partial: "count").strip.html_safe %>'); $orderFilterInput.val('<%= order %>'); -var $dropdownMenu = $('.dropdown.menu', $projects); -$dropdownMenu.foundation(); -$projects.foundation(); +document.dispatchEvent(new CustomEvent("ajax:loaded", { detail: $projects[0] })); diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb index 2831c12d..b0df7d5c 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb @@ -62,11 +62,12 @@ def ensure_not_voted end # maximum_budgets_to_vote_on is being set by the admin. the default is zero, which means users can - # vote in all available budgets. to check that user has voted to all available budgets, we should - # consider this settings as well. + # vote in all available budgets. To check that user has voted to all available budgets, we should + # consider this settings as well. If budget component workflow is random or one, available budgets + # will be equal to 1 def voted_all_budgets? default_limit = current_component.settings.maximum_budgets_to_vote_on || 0 - available_budgets = budgets.count + available_budgets = ["random", "one"].include?(current_component.settings.workflow) ? 1 : budgets.count vote_limit = if default_limit.zero? available_budgets else @@ -76,13 +77,13 @@ def voted_all_budgets? voted.count >= vote_limit end - # This configuration option can be set in component settings, the dfault url when the user has voted on all budgets + # This configuration option can be set in component settings, the default url when the user has voted on all budgets # is budgets path def success_redirect_path component_settings.try(:vote_success_url).presence || decidim_budgets.budgets_path end - # This configuration option can be set in component settings, the dfault url when the user cancels voting is the root path. + # This configuration option can be set in component settings, the default url when the user cancels voting is the root path. def cancel_redirect_path component_settings.try(:vote_cancel_url).presence || decidim.root_path end From 242d4b65e42b835a34a889d58ac2198368838434 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 09:29:58 +0100 Subject: [PATCH 22/93] fix: update entrypoints in assets.rb file --- decidim-budgets_booth/config/assets.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/decidim-budgets_booth/config/assets.rb b/decidim-budgets_booth/config/assets.rb index 78aa5647..78bde688 100644 --- a/decidim-budgets_booth/config/assets.rb +++ b/decidim-budgets_booth/config/assets.rb @@ -4,7 +4,6 @@ Decidim::Webpacker.register_path("#{base_path}/app/packs", prepend: true) Decidim::Webpacker.register_entrypoints( - decidim_budgets_booth_voting: "#{base_path}/app/packs/entrypoints/decidim_budgets_booth_voting.js", decidim_budgets_booth_budgets: "#{base_path}/app/packs/entrypoints/decidim_budgets_booth_budgets.js", decidim_handle_voting_complete: "#{base_path}/app/packs/entrypoints/decidim_handle_voting_complete.js" ) From d60dc7f25913dc37ec521cb73dec866606a8cb3d Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 09:31:54 +0100 Subject: [PATCH 23/93] feat: update design in project index page --- .../cells/decidim/budgets/project_g/show.erb | 7 +- .../budgets/project_vote_button/show.erb | 4 +- .../decidim/budgets_booth/budgets_booth.scss | 24 +++- .../budgets/line_items/update_budget.js.erb | 2 + .../_order_progress_summary_content.html.erb | 122 ++++++++++++++++++ .../projects/_order_progress_text.html.erb | 17 +++ .../decidim/budgets/projects/index.html.erb | 4 +- 7 files changed, 168 insertions(+), 12 deletions(-) create mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb create mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb index e57c7993..fd54e2f2 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb @@ -1,9 +1,8 @@ -<%= link_to resource_path, class: classes[:default], id: resource_id do %> +<% project_card = resource_added? ? "card__grid card-grid-selected" : classes[:default] %> +<%= link_to resource_path, class: project_card, id: resource_id do %>
<% if has_image? %> <%= image_tag resource_image_path, alt: alt_title %> - <% else %> - <%= external_icon "media/images/decidim_budgets.svg", class: "card__project-placeholder-g" %> <% end %>
@@ -20,10 +19,10 @@
<% end %>
+ <%= cell("decidim/budgets/project_vote_button", project, show_only_added:, view_mode:) %> <%= budget_to_currency(project.budget_amount) %> - <%= cell("decidim/budgets/project_vote_button", project, show_only_added:, view_mode:) %>
<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb index 4d81ba81..e412227e 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb @@ -1,9 +1,10 @@ +<% button_type = resource_added? ? "button__transparent-secondary" : "button__secondary" %> <%= action_authorized_button_to( "vote", budget_order_line_item_path(model.budget, project_id: model, show_only_added: options[:show_only_added], view_mode: options[:view_mode]), method: vote_button_method, remote: true, - class: "button #{scale_up} budget-list__action project__vote-button button__secondary customized-budget display-block project-#{project.id}-vote-button ", + class: "button #{scale_up} budget-list__action project__vote-button #{button_type} customized-budget display-block project-#{project.id}-vote-button ", data: { add: !resource_added?, disable: true, @@ -17,4 +18,3 @@ ) do %> <%= resource_added? ? t("remove_from_vote", scope: "decidim.budgets.project_vote_button") :t("add_to_vote", scope: "decidim.budgets.project_vote_button") %> <% end %> - diff --git a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss index c88c6ee0..1e69ab8b 100644 --- a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss +++ b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss @@ -193,15 +193,18 @@ $active-item-color: black; } //new .budget__card__grid-project { - display:flex; - justify-content:space-between; - align-items:center; + display: flex; + flex-direction: row; + align-items: center; + gap: 1rem; } -@media (max-width: 1366px) { + +@media (min-width: 769px) and (max-width: 1040px) { .budget__card__grid-project { - flex-direction: column; + flex-direction: column-reverse; } } + .card__list > .budget__card__list-project{ display:flex; flex-direction: column; @@ -367,3 +370,14 @@ $active-item-color: black; width: 100%; height: 100%; } +.card__grid-img { + background-color: #F3F4F6; +} +#budget-booth-body .view-layout__links { + display: flex; + align-items: center; + gap: 1rem; +} +.card-grid-selected { + --tw-ring-color: var(--tertiary); +} diff --git a/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb b/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb index 6738cb47..8bb6bcc0 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/line_items/update_budget.js.erb @@ -3,10 +3,12 @@ var $orderProgress = document.querySelectorAll('[id^=order-progress] .budget-sum var $projectItem = $('#project-<%= project.id %>-item'); var $projectVoteButton = $('.project-<%= project.id %>-vote-button'); var $budgetConfirm = $('#budget-confirm'); +var $orderProgressText = $('.order_progress_text'); $orderProgress.forEach((orderProgress) => { var $orderTotalBudget = $(orderProgress).find("[id^=order-total-budget]"); $orderTotalBudget.html('<%= j(render partial: "decidim/budgets/projects/order_total_budget").strip.html_safe %>'); + $orderProgressText.html('<%= j(render partial: "decidim/budgets/projects/order_progress_text").strip.html_safe %>'); if(orderProgress.dataset.orderProgressResponsive) { morphdom(orderProgress, '<%= j(render partial: "decidim/budgets/projects/order_progress_summary_content", locals: { include_heading: true, responsive: true }).strip.html_safe %>'); diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb new file mode 100644 index 00000000..01cabb22 --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb @@ -0,0 +1,122 @@ +
+
+ <% if include_heading && controller.action_name == "show" %> + <% if current_order_checked_out? %> + <%= t("title", scope: "decidim.budgets.projects.budget_summary.checked_out") %> +
+ + <%= t("name", scope: "decidim.components.budgets") %> + + / + <%= translated_attribute(budget.title) %> +

+ <%= t("description", scope: "decidim.budgets.projects.budget_summary.checked_out") %> +

+
+ <% else %> +

+ <%= current_rule_description %> +

+ <% end %> + <% end %> +
+
" aria-valuenow="<%= current_order_budget_percent %>" aria-valuetext="<%= current_order_budget_percent %> %" aria-valuemin="0" aria-valuemax="100"> +
+
+
+
+
+ + " class="budget-summary__progressbar-legend-strong"> + <%= render partial: "decidim/budgets/projects/order_total_budget" %> + + <%= t("assigned", scope: "decidim.budgets.projects.order_progress") %> + + <% if current_order.minimum_budget > 0 %> + + + <%= budget_to_currency(current_order.minimum_budget) %> + + <%= t("minimum", scope: "decidim.budgets.projects.order_progress") %> + + <% end %> + <%= render partial: "decidim/budgets/projects/order_progress_progressbar_marks_right" %> +
+
+
+
+ <% if !current_order_checked_out? && voting_open? %> + + <% end %> + <% if include_heading && current_order_checked_out? %> + <%= link_to budget_order_path(return_to: "budget"), method: :delete, class: "button button__lg button__secondary cancel-order w-full", data: { confirm: t("are_you_sure", scope: "decidim.budgets.projects.budget_confirm") } do %> + <%= t("cancel_order", scope: "decidim.budgets.projects.budget_summary") %> + <%= icon "delete-bin-line" %> + <% end %> + <% end %> +
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + <%= t("assigned", scope: "decidim.budgets.projects.order_progress") %> + " class="budget-summary__progressbar-legend-strong"> + <%= render partial: "decidim/budgets/projects/order_total_budget" %> + + + <% if current_order.minimum_budget > 0 %> + + <%= t("minimum", scope: "decidim.budgets.projects.order_progress") %> + + <%= budget_to_currency(current_order.minimum_budget) %> + + + <% end %> + <%= render partial: "decidim/budgets/projects/order_progress_progressbar_marks_right" %> +
+
+ +
+
+
+ +
+ + +
diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb new file mode 100644 index 00000000..491f2e07 --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb @@ -0,0 +1,17 @@ +<% if current_order_checked_out? %> + <%= t("title", scope: "decidim.budgets.projects.budget_summary.checked_out") %> +
+ + <%= t("name", scope: "decidim.components.budgets") %> + + / + <%= translated_attribute(budget.title) %> +

+ <%= t("description", scope: "decidim.budgets.projects.budget_summary.checked_out") %> +

+
+<% else %> +

+ <%= current_rule_description %> +

+<% end %> diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb index 6055017d..e22c7215 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/index.html.erb @@ -12,7 +12,9 @@ <% content_for :aside do %>

<%= t("decidim.budgets.projects.projects_for", name: budget_title) %>

- +
+ <%= render partial: "order_progress_text" %> +
<%= render layout: "decidim/shared/filters", locals: { filter_sections: , search_variable: :search_text_cont, skip_to_id: "projects" } do %> <%= hidden_field_tag :order, order, id: nil, class: "order_filter" %> <% end %> From 27b8d92762df86199d30345809cabf867b2f1098 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 09:32:39 +0100 Subject: [PATCH 24/93] feat: update voting button text --- decidim-budgets_booth/config/locales/en.yml | 2 +- decidim-budgets_booth/config/locales/fr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index a3c318c0..76ef73f0 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -17,7 +17,7 @@ en: total_budget: 'Total budget: ' project_vote_button: add_to_vote: Add to your vote - remove_from_vote: Remove from vote + remove_from_vote: Added to vote projects: cancel_voting_modal: continue: Continue voting diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 78816711..06918134 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -17,7 +17,7 @@ fr: total_budget: 'Budget total : ' project_vote_button: add_to_vote: Ajouter au vote - remove_from_vote: Supprimer du vote + remove_from_vote: Ajouté au vote projects: cancel_voting_modal: continue: Continuer le vote From b4f7d03f01715e4902bbe3b0b34e18de724357e3 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 11:55:21 +0100 Subject: [PATCH 25/93] feat: update custom modals to feat decidim style --- .../budgets_booth/vote_completed/show.erb | 31 +++++++------- .../budgets_booth/handle_thanks_session.js | 14 ++++++- .../budgets_booth/handle_voting_completion.js | 24 ++++++++--- .../voting/_thanks_message_modal.html.erb | 40 ++++++++----------- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb index e533c40f..445575f8 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets_booth/vote_completed/show.erb @@ -1,20 +1,19 @@ -
-
-

<%= t("title", scope: "decidim.budgets.voting.vote_completed_modal") %>

- -
+<%= decidim_modal id: "vote-completed" do %> +
+ <%= icon "delete-bin-line" %> +

<%= t("title", scope: "decidim.budgets.voting.vote_completed_modal") %>

-
- <%= vote_completed_content %> +
+ <%= vote_completed_content %> +
-
-
- -
+
+ +
-
+<% end %> diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js index 37075533..22a16254 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js @@ -1,9 +1,21 @@ $(() => { const $modal = $("#thanks-message"); + const $buttonConfirm = $("[data-confirm-ok]", $modal); + const $buttonCancel = $("[data-confirm-cancel]", $modal); + const $buttonClose = $("[data-dialog-closable]", $modal); console.log(`bool: ${Boolean($modal)}`) console.log(`session: ${$modal.attr("data-session") === "true"}`) if (Boolean($modal) && $modal.attr("data-session") === "true") { - $modal.foundation("open"); + $modal.attr("aria-hidden", false) } + $buttonConfirm.on("click", (ev)=> { + $modal.attr("aria-hidden", true) + }) + $buttonCancel.on("click", (ev)=> { + $modal.attr("aria-hidden", true) + }) + $buttonClose.on("click", (ev)=> { + $modal.attr("aria-hidden", true) + }) }); diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js index 2913064c..d4cbcdb6 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js @@ -9,12 +9,24 @@ const initVoteCompleteElement = () => { const reveal = wrapper.querySelector("div"); document.body.append(reveal); - - // With foundation we still have to use jQuery. - // The purpose is to open the reveal after Foundation has initialized the - // reveal element which happens with the Decidim's default JS. This code is - // run before that. - $(reveal).on("init.zf.reveal", () => $(reveal).foundation("open")); } initVoteCompleteElement(); +$(() => { + const $modal = $("#vote-completed"); + const $buttonConfirm = $("[data-confirm-ok]", $modal); + const $buttonCancel = $("[data-confirm-cancel]", $modal); + const $buttonClose = $("[data-dialog-closable]", $modal); + + $modal.attr("aria-hidden", false); + + $buttonConfirm.on("click", (ev)=> { + $modal.attr("aria-hidden", true) + }) + $buttonCancel.on("click", (ev)=> { + $modal.attr("aria-hidden", true) + }) + $buttonClose.on("click", (ev)=> { + $modal.attr("aria-hidden", true) + }) +}); diff --git a/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb index 32e7e206..1bd7a92a 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/voting/_thanks_message_modal.html.erb @@ -1,29 +1,21 @@ -
-
-

<%= t(".title") %>

- -
- <% unless current_workflow.try(:hide_image_in_popup?) %> -
-
-
- <%= render partial: "decidim/budgets/partials/svgs/icon-ballot-box", formats: [:svg] %> -
-
+<%= decidim_modal id: "thanks-message", data: { session: thanks_popup? } do %> +
+ <%= icon "delete-bin-line" %> +

<%= t(".title") %>

+ +
+ <%= vote_success_content %>
- <% end %> -
- <%= vote_success_content %>
-
-
- -
+ +
+ +
-
+<% end %> From b569cc5df6cf93c45e9990e919db5d14eda00284 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 13:13:36 +0100 Subject: [PATCH 26/93] refactor: js files --- .../src/decidim/budgets_booth/handle_thanks_session.js | 9 ++++----- .../decidim/budgets_booth/handle_voting_completion.js | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js index 22a16254..050f57da 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_thanks_session.js @@ -3,18 +3,17 @@ $(() => { const $buttonConfirm = $("[data-confirm-ok]", $modal); const $buttonCancel = $("[data-confirm-cancel]", $modal); const $buttonClose = $("[data-dialog-closable]", $modal); - console.log(`bool: ${Boolean($modal)}`) - console.log(`session: ${$modal.attr("data-session") === "true"}`) + if (Boolean($modal) && $modal.attr("data-session") === "true") { $modal.attr("aria-hidden", false) } - $buttonConfirm.on("click", (ev)=> { + $buttonConfirm.on("click", () => { $modal.attr("aria-hidden", true) }) - $buttonCancel.on("click", (ev)=> { + $buttonCancel.on("click", () => { $modal.attr("aria-hidden", true) }) - $buttonClose.on("click", (ev)=> { + $buttonClose.on("click", () => { $modal.attr("aria-hidden", true) }) }); diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js index d4cbcdb6..d4893e1f 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets_booth/handle_voting_completion.js @@ -20,13 +20,13 @@ $(() => { $modal.attr("aria-hidden", false); - $buttonConfirm.on("click", (ev)=> { + $buttonConfirm.on("click", () => { $modal.attr("aria-hidden", true) }) - $buttonCancel.on("click", (ev)=> { + $buttonCancel.on("click", () => { $modal.attr("aria-hidden", true) }) - $buttonClose.on("click", (ev)=> { + $buttonClose.on("click", () => { $modal.attr("aria-hidden", true) }) }); From e1dd9b1f3d765b0042df7d7cd3234ce616cfd09f Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 14:00:26 +0100 Subject: [PATCH 27/93] fix: update js file --- .../app/packs/src/decidim/budgets/exit_handler.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/decidim-budgets_booth/app/packs/src/decidim/budgets/exit_handler.js b/decidim-budgets_booth/app/packs/src/decidim/budgets/exit_handler.js index 0cd5d3de..da9f7383 100644 --- a/decidim-budgets_booth/app/packs/src/decidim/budgets/exit_handler.js +++ b/decidim-budgets_booth/app/packs/src/decidim/budgets/exit_handler.js @@ -46,16 +46,7 @@ const allowExitFrom = ($el) => { return false; } -$(function(){ - const $link = $('.menu-bar__exit-link'); - if ($link.attr("href").substring(0, 4) == "http"){ - return; - } else if ($link.attr("href")[0] == "/") { - $link.attr("href", window.location.origin + $link.attr("href")); - } else { - $link.attr("href", window.location.origin + "/" + $link.attr("href")); - } -}); + $(() => { const $exitNotification = $("#exit-notification"); const $exitLink = $("#exit-notification-link"); From 9ae76045a8d2afc7b82fcbc905911db323547a06 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 14:01:25 +0100 Subject: [PATCH 28/93] feat: remove filter-help text from filters in project index --- .../views/decidim/shared/_filters.html.erb | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 decidim-budgets_booth/app/views/decidim/shared/_filters.html.erb diff --git a/decidim-budgets_booth/app/views/decidim/shared/_filters.html.erb b/decidim-budgets_booth/app/views/decidim/shared/_filters.html.erb new file mode 100644 index 00000000..381e03c7 --- /dev/null +++ b/decidim-budgets_booth/app/views/decidim/shared/_filters.html.erb @@ -0,0 +1,44 @@ +<% filter_sections = [] unless local_assigns.has_key?(:filter_sections) %> +<% search_label = t("decidim.searches.filters.search") unless local_assigns.has_key?(:search_label) %> + +<% if filter_sections.present? || local_assigns.has_key?(:search_variable) %> + <%= filter_form_for filter, url_for, class: "new_filter self-stretch", data: { filters: "", component: "accordion" } do |form| %> + + + + + + <% end %> +<% end %> From 1f1c82d02721d5171b9d2444e5331a7d81a0984c Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 14:15:14 +0100 Subject: [PATCH 29/93] feat: update readme --- decidim-budgets_booth/README.md | 63 +++------------------------------ 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/decidim-budgets_booth/README.md b/decidim-budgets_booth/README.md index f2e67afa..ea79ab05 100644 --- a/decidim-budgets_booth/README.md +++ b/decidim-budgets_booth/README.md @@ -7,12 +7,6 @@ their vote has not been cast. The idea is to "lock" the user inside a voting booth during the voting process and make it extremely clear for them that if they exit the voting booth, they have not yet cast their vote. -The module also introduces a new budgeting workflow called "ZIP code". This -workflow allows limiting the budgets available for the user based on their ZIP -code, providing them only those budgets they are eligible to vote at. For more -information and how to set this up, please refer to the -[ZIP code voting documentation](docs/ZIP_CODE_VOTING.md). - ## Usage This module is built on top of the `decidim-budgets` module and adds extra @@ -20,30 +14,15 @@ feature/capabilities to it. After installing this module, the normal budgeting component will automatically provide the voting booth capabilities meaning if you do not want these capabilities, you should uninstall this module. -For enabling the "ZIP code voting" feature, you have a new workflow available -for the budgets component named "ZIP code" which shows up at the configuration -page as follows: - -![ZIP code workflow](docs/zip-code-workflow.png) -This workflow enables the following features to the budget voting experience: +This module enables the following features to the budget voting experience: -- Capability for enabling/disabling "ZIP code" workflow from components - configuration. -- Capability for the user to provide their ZIP code when entering the voting - booth. - * Users may change their zip code only if they have not voted yet, or if they - have deleted all of their votes. - Defining cancel and after finishing voting redirection destinations. * Useful for asking for feedback, for example, after completing voting. - Introducing a new configuration for maximum number of budgets, in which users can vote. - Adding after voting and after completing voting message, configurable from admin panel. -- Capability of showing/hiding voting instruction, when the user starts to vote. -- Capability of showing images in the after voting popup. -- Capability of adding images to the budgets from back office, to be displayed - at the budgets listing page. ## Installation @@ -63,53 +42,21 @@ bundle ### Admin configuration -To configure this module correctly, you need to first configure the ZIP codes -correctly. Please refer to the -[ZIP code voting documentation](docs/ZIP_CODE_VOTING.md) for more information on -how to set it up. Next, you can configure the following options from your -budgets component configurations: - -- **Vote based on ZIP code**: allows participants to vote on budgets matching - their entered ZIP code. - * Selecting this option enables ZIP code workflow. - * Any other workflow will work as Decidim would normally work but with the - voting booth feature enabled. +You can configure the following options from your budgets component configurations: + - **Popup text after each vote**: the content of the popup which is being shown after each voting. - **Popup text after voting in all available budgets**: the content of the popup which is being shown after user voted in all available budgets. -- **Terms and conditions to be shown when user wants to enter their ZIP code**: - set of terms and conditions you ask the users to agree on when they are - entering their ZIP code. - * This message is shown in ZIP code entering view when using the ZIP code - voting. - * Otherwise, this message will show up when the user is about to confirm their - vote. - **URL to redirect user after voting on all available budgets**: Defines where user is redirected after completing their vote. * By default, the user is redirected back to the budgets list. - **URL to redirect user when canceling voting**: Defines where the user is redirected if they decide to cancel the voting process. * By default, the user is redirected to the root path. -- **Show full project descriptions on the listing page and disable the details - popup**: This option shows the complete project descriptions on the projects - listing page while voting. If this setting is disabled, the descriptions will - show up as "teasers" and the whole details are opened within a modal window. - -### Hard coded configuration +- **Maximum number of budgets that user can vote on**: Defines how many budgets a user can vote on. + * By default, the value is 0, which means user can vote on all available budgets. -You can set the number of digits for the ZIP codes which may differ in different -countries. The default is set to 5, which is the case for those countries -considered when this module was developed. If you need set this to a different -number, you can use the following code within an initializer to change this -setting: - -```ruby -Decidim::BudgetsBooth.configure do |config| - # Change this value to the number of characters in the ZIP codes within the country where this instances is used at. - config.zip_code_length = 5 -end -``` ## Testing From 152b3f6f0a20c788d2e4213bb3c668eabe8d2c9b Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 14:23:33 +0100 Subject: [PATCH 30/93] feat: update readme --- decidim-budgets_booth/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/decidim-budgets_booth/README.md b/decidim-budgets_booth/README.md index ea79ab05..a058fe90 100644 --- a/decidim-budgets_booth/README.md +++ b/decidim-budgets_booth/README.md @@ -7,6 +7,10 @@ their vote has not been cast. The idea is to "lock" the user inside a voting booth during the voting process and make it extremely clear for them that if they exit the voting booth, they have not yet cast their vote. +This module also provides design improvements on the projects index view, like +the possibility in this view to switch between grid mode and list mode +(default is grid mode). + ## Usage This module is built on top of the `decidim-budgets` module and adds extra From 6de00a12d89cc1570492e0233ad8939ddc4867bc Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 19 Dec 2024 17:26:43 +0100 Subject: [PATCH 31/93] feat: delete no more used files --- .../projects/_cancel_voting_modal.html.erb | 19 ----- decidim-budgets_booth/docs/ZIP_CODE_VOTING.md | 72 ------------------ .../docs/zip-code-workflow.png | Bin 256265 -> 0 bytes 3 files changed, 91 deletions(-) delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/projects/_cancel_voting_modal.html.erb delete mode 100644 decidim-budgets_booth/docs/ZIP_CODE_VOTING.md delete mode 100644 decidim-budgets_booth/docs/zip-code-workflow.png diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_cancel_voting_modal.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_cancel_voting_modal.html.erb deleted file mode 100644 index f3b4dcbf..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_cancel_voting_modal.html.erb +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/decidim-budgets_booth/docs/ZIP_CODE_VOTING.md b/decidim-budgets_booth/docs/ZIP_CODE_VOTING.md deleted file mode 100644 index 9df9a5bc..00000000 --- a/decidim-budgets_booth/docs/ZIP_CODE_VOTING.md +++ /dev/null @@ -1,72 +0,0 @@ -# ZIP code voting - -The ZIP code voting feature provides a custom workflow for budgeting for creating scopes to represent ZIP code areas. In order to use the feature, the administrator must add the proper scopes and scope types, and configure the budgets component to use these scopes. - -## Enabling ZIP code voting - -After installing this module, you should be able to enable/disable this feature from the admin panel. To enable ZIP code workflow, you need to select the "scopes enabled" from your budget's component settings for which you want to enable this feature. Also, you need to select the custom workflow "Vote based on ZIP code: allows participants to vote on budgets matching their entered ZIP code." that is designed for this feature. - -## Adding scope types - -The administrator needs to create the following scope types: - -- Area -- Area - Borough -- Area - Neighborhood -- Area - Postal - -## Adding scopes - -To create scopes, you need to follow the following procedure: - -1. Create the parent scope which wraps up all other scopes. The parent scope should have the scope type of "Area" and the code equal to "Area". - -| **name** | **code** | **scope_type** | -| :---: | :---: | :---: | -| New York City | NY | Area | - - -2. Inside the parent scope (Area), create the boroughs that exist in the area. Each borough should have the scope type of "Area - Borough". For example, to create the Bronx sub-scope inside the parent scope, we will create the following scope: - -| **name** | **code** | **scope type** | -| -------- | ----------- | ----------------- | -| Bronx | NY_BRONX | Area - Borough | - -3. Inside each borough, add all existing neighborhoods. Each neighborhood should have the scope type of "Area - Neighborhood". For example, to create the West Bronx sub-scope inside the Bronx scope, we will create the following scope: - -| **name** | **code** | **scope type** | -| -------- | --------------- | ---------------------- | -| West Bronx | NY_BRONX_WEST | Area - Neighborhood | - -4. Finally, inside each neighborhood, add the ZIP codes that the particular area has. Each ZIP code should have the scope type of "Area - Postal". For example, to create the 10465 sub-scope inside the West Bronx scope, we will create the following scope: - -| **name** | **code** | **scope type** | -| -------- | --------------------- | ---------------- | -| 10465 | NY_BRONX_WEST_10465 | Area - Postal | - -Note that each scope should have a unique code, which can be used to reference the scope in other parts of the system. If you need to duplicate the same ZIP code under multiple neighborhoods, you can do that by using unique code for each of ZIP codes within the neighborhoods. - -Note that the ZIP codes need to be always defined at the deepest level of this structure. With the example structure you cannot, for example, add ZIP codes directly under the boroughs because you have one more hierarchy level of under that. Maximum depth for the scopes is three as in the example given above (Borough -> Neighborhood -> Postal) but you may also define less levels as long as the ZIP codes are always found at the deepest level within the hierarchy. - -If you need to add ZIP codes that do not belong to any neighborhood in the given example, you can create a neighborhood named "!General" where you add such ZIP codes. This needs to be done in order to maintain the correct levels in the hierarchy. The logic is expecting to find the ZIP codes always at the deepest level, so if you would add them directly under the boroughs, they would not be considered ZIP codes. - -### Example usage - -Here is a visualization example of how to use the zip-code module to create scopes for New York City: - -```yaml -- name: New York City - code: NY - scope_type: Area - - name: Bronx - code: NY_BRONX - scope_type: Area - Borough - - name: West Bronx - code: NY_BRONX_WEST - scope_type: Area - Neighborhood - - name: 10465 - code: NY_BRONX_WEST_10465 - scope_type: Area - Postal - ``` - -In the example above, we created a scope for New York City with the code NY. Inside the NY scope, we created a scope for the Bronx borough with the code NY_BRONX. Inside the NY_BRONX scope, we created a scope for the West Bronx neighborhood with the code NY_BRONX_WEST. Finally, inside the NY_BRONX_WEST scope, we created a scope for the ZIP code 10465 with the code NY_BRONX_WEST_10465. diff --git a/decidim-budgets_booth/docs/zip-code-workflow.png b/decidim-budgets_booth/docs/zip-code-workflow.png deleted file mode 100644 index c7615371a69e64de8526d34525c3249dd1095351..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256265 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

%x(4Ms!EDCs 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≈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 NJk)srzi<2E{{vNLOh^C# From 15d0a6c1064177eb8a7c5d87a0f97fb12bca5eaa Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 20 Dec 2024 17:01:35 +0100 Subject: [PATCH 32/93] feat: delete no more used files --- .../budgets/admin/create_budget_spec.rb | 56 ------------------- .../budgets/admin/update_budget_spec.rb | 53 ------------------ 2 files changed, 109 deletions(-) delete mode 100644 decidim-budgets_booth/spec/commands/decidim/budgets/admin/create_budget_spec.rb delete mode 100644 decidim-budgets_booth/spec/commands/decidim/budgets/admin/update_budget_spec.rb diff --git a/decidim-budgets_booth/spec/commands/decidim/budgets/admin/create_budget_spec.rb b/decidim-budgets_booth/spec/commands/decidim/budgets/admin/create_budget_spec.rb deleted file mode 100644 index d80d2e2a..00000000 --- a/decidim-budgets_booth/spec/commands/decidim/budgets/admin/create_budget_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Budgets::Admin::CreateBudget do - include ::Decidim::BudgetsBooth::CreateBudgetExtensions - subject { described_class.new(form) } - - let(:organization) { create :organization, available_locales: [:en, :ca, :es], default_locale: :en } - let(:participatory_process) { create :participatory_process, organization: organization } - let!(:current_component) { create :component, participatory_space: participatory_process, manifest_name: "budgets" } - let(:user) { create :user, :admin, :confirmed, organization: organization } - let(:scope) { create :scope, organization: organization } - let(:main_image) do - ActiveStorage::Blob.create_and_upload!( - io: File.open(Decidim::Dev.asset("city.jpeg")), - filename: "city.jpeg", - content_type: "image/jpeg" - ) - end - - let(:form) do - double( - invalid?: invalid, - weight: 0, - title: { en: "title" }, - description: { en: "description" }, - total_budget: 100_000_000, - scope: scope, - current_user: user, - main_image: main_image, - current_component: current_component, - current_organization: organization - ) - end - - let(:invalid) { false } - - let(:budget) { Decidim::Budgets::Budget.last } - - context "when image is attached" do - it "adds main image to the budget" do - subject.call - expect(budget.main_image.blob).to be_a(ActiveStorage::Blob) - end - end - - context "when image is not attached" do - let(:main_image) { nil } - - it "does not add main image to the budget" do - subject.call - expect(budget.main_image.blob).to be_nil - end - end -end diff --git a/decidim-budgets_booth/spec/commands/decidim/budgets/admin/update_budget_spec.rb b/decidim-budgets_booth/spec/commands/decidim/budgets/admin/update_budget_spec.rb deleted file mode 100644 index f900088a..00000000 --- a/decidim-budgets_booth/spec/commands/decidim/budgets/admin/update_budget_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Budgets::Admin::UpdateBudget do - include ::Decidim::BudgetsBooth::UpdateBudgetExtensions - subject { described_class.new(form, budget) } - - let(:budget) { create :budget } - let(:scope) { create :scope, organization: budget.organization } - let(:user) { create :user, :admin, :confirmed, organization: budget.organization } - let(:main_image) do - ActiveStorage::Blob.create_and_upload!( - io: File.open(Decidim::Dev.asset("city.jpeg")), - filename: "city.jpeg", - content_type: "image/jpeg" - ) - end - - let(:form) do - double( - invalid?: invalid, - weight: 0, - title: { en: "title" }, - description: { en: "description" }, - total_budget: 100_000_000, - scope: scope, - current_user: user, - main_image: main_image, - current_component: budget.component, - current_organization: budget.organization - ) - end - - let(:invalid) { false } - - context "when image is attached" do - it "adds main image to the budget" do - expect(budget.main_image.blob).to be_nil - subject.call - expect(budget.main_image.blob).to be_a(ActiveStorage::Blob) - end - end - - context "when image is not attached" do - let(:main_image) { nil } - - it "does not add main image to the budget" do - subject.call - expect(budget.main_image.blob).to be_nil - end - end -end From db4cfa8ae73ae31cc50442af53e71fb3bb991b6f Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 20 Dec 2024 17:06:19 +0100 Subject: [PATCH 33/93] feat: update method name in rubocop_ruby file --- .rubocop_ruby.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop_ruby.yml b/.rubocop_ruby.yml index 6af95162..fbfa843e 100644 --- a/.rubocop_ruby.yml +++ b/.rubocop_ruby.yml @@ -260,7 +260,7 @@ Style/BlockDelimiters: - let! - subject - watch - IgnoredMethods: + AllowedMethods: # Methods that can be either procedural or functional and cannot be # categorised from their usage alone, e.g. # @@ -981,7 +981,7 @@ Style/SymbolArray: Style/SymbolProc: # A list of method names to be ignored by the check. # The names should be fairly unique, otherwise you'll end up ignoring lots of code. - IgnoredMethods: + AllowedMethods: - respond_to - define_method From cac2902ac94473ac14769382b9ff4aae885d7ac8 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 20 Dec 2024 17:10:57 +0100 Subject: [PATCH 34/93] feat: update tests after design modifications --- .../decidim/budgets/project_g_cell_spec.rb | 4 +-- .../orders_controller_extensions_spec.rb | 5 ++- decidim-budgets_booth/spec/factories.rb | 1 - .../projects_helper_extensions_spec.rb | 11 +++---- .../budgets_booth/voting_support_spec.rb | 20 +++++------- .../spec/system/explore_budgets_spec.rb | 8 +---- .../spec/system/orders_spec.rb | 31 ++++++++++--------- 7 files changed, 36 insertions(+), 44 deletions(-) diff --git a/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb b/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb index 4d1d320a..f8122009 100644 --- a/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb +++ b/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb @@ -43,8 +43,8 @@ module Decidim::Budgets context "when the project has no image" do before { allow(project).to receive(:attachments).and_return([]) } - it "renders a placeholder image" do - expect(subject).to have_css(".card__project-placeholder-g") + it "renders the project without image" do + expect(subject).not_to have_css("img") end end end diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb index c690c160..550cd446 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb @@ -32,10 +32,13 @@ describe "#checkout" do context "when command call returns ok" do + before do + component.update!(settings: { workflow: "all" }) + end it "sets thanks session and redirects the user" do post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - expect(response).to redirect_to(decidim_budgets.budgets_path) expect(session[:booth_thanks_message]).to be(true) + expect(response).to redirect_to(decidim_budgets.budgets_path) end it "enqueues job" do diff --git a/decidim-budgets_booth/spec/factories.rb b/decidim-budgets_booth/spec/factories.rb index c007b36d..b347689f 100644 --- a/decidim-budgets_booth/spec/factories.rb +++ b/decidim-budgets_booth/spec/factories.rb @@ -5,4 +5,3 @@ require "decidim/surveys/test/factories" require "decidim/proposals/test/factories" require "decidim/budgets_booth/test/factories" - diff --git a/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb b/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb index 8244fc0e..46077ac5 100644 --- a/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb +++ b/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb @@ -6,13 +6,13 @@ describe "#current_phase" do let(:organization) { create(:organization) } let(:participatory_process) { create(:participatory_process, organization: organization) } - let!(:step1) do + let!(:step_one) do create(:participatory_process_step, active: true, end_date: Time.zone.now.to_date, participatory_process: participatory_process) end - let!(:step2) do + let!(:step_two) do create(:participatory_process_step, active: false, end_date: 1.month.from_now.to_date, @@ -20,17 +20,16 @@ end before do - allow(helper).to receive(:current_organization).and_return(organization) - allow(helper).to receive(:params).and_return({ participatory_process_slug: participatory_process.slug }) + allow(helper).to receive_messages(current_organization: organization, params: { participatory_process_slug: participatory_process.slug }) end it "returns the title of the active step in the current participatory process" do - expect(helper.current_phase).to eq(step1.title) + expect(helper.current_phase).to eq(step_one.title) end context "when there is no active step in the current participatory process" do before do - step1.update(active: false) + step_one.update(active: false) end it "returns nil" do diff --git a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb index c419f2da..c29ac910 100644 --- a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb +++ b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb @@ -27,7 +27,7 @@ def current_component end def current_workflow - Decidim::Budgets::Workflows::One.new(current_component, current_user) + Decidim::Budgets::Workflows::All.new(current_component, current_user) end def voting_open? @@ -39,7 +39,7 @@ def voting_open? let(:component) do create( :budgets_component, - settings: component_settings.merge(workflow: "one"), + settings: component_settings.merge(workflow: "all"), step_settings: step_settings, organization: organization ) @@ -60,10 +60,8 @@ def voting_open? include_context "with scoped budgets" before do - allow(dummy).to receive(:component).and_return(component) - allow(dummy).to receive(:user).and_return(user) - allow(dummy).to receive(:organization).and_return(organization) - allow(dummy).to receive(:current_settings).and_return(component.current_settings) + component.update!(settings: component_settings.merge(workflow: "all")) + allow(dummy).to receive_messages(component: component, user: user, organization: organization, current_settings: component.current_settings) end describe "#voting_enabled?" do @@ -81,9 +79,7 @@ def voting_open? context "when voted" do before do - order.projects << projects.first - order.checked_out_at = Time.current - order.save! + vote_this(order, projects.first) end it "returns true" do @@ -120,7 +116,7 @@ def voting_open? context "when maximum_budgets_to_vote_on is set" do context "when voted the limit" do before do - component.update!(settings: component_settings.merge(workflow: "one", maximum_budgets_to_vote_on: 1)) + component.update!(settings: component_settings.merge(maximum_budgets_to_vote_on: 1)) vote_this(order, projects.first) end @@ -145,7 +141,7 @@ def voting_open? context "when maximum_budgets_to_vote_on is set" do before do - component.update(settings: component_settings.merge(workflow: "one", maximum_budgets_to_vote_on: 1)) + component.update(settings: component_settings.merge(maximum_budgets_to_vote_on: 1)) vote_this(order, projects.first) end @@ -162,7 +158,7 @@ def voting_open? let(:votes) { "disabled" } before do - component.update!(settings: component_settings.merge(workflow: "one", maximum_budgets_to_vote_on: 1), step_settings: step_settings) + component.update!(settings: component_settings.merge(maximum_budgets_to_vote_on: 1), step_settings: step_settings) vote_this(order, projects.first) allow(dummy).to receive(:current_settings).and_return(component.current_settings) diff --git a/decidim-budgets_booth/spec/system/explore_budgets_spec.rb b/decidim-budgets_booth/spec/system/explore_budgets_spec.rb index c326f510..781cea40 100644 --- a/decidim-budgets_booth/spec/system/explore_budgets_spec.rb +++ b/decidim-budgets_booth/spec/system/explore_budgets_spec.rb @@ -61,13 +61,7 @@ end describe "budget list item" do - let!(:component) do - create(:budgets_component, - :with_vote_threshold_percent, - manifest:, - participatory_space: participatory_process, - settings: { landing_page_content: description }) - end + let!(:component){ create(:budgets_component, :with_vote_threshold_percent, manifest:, participatory_space: participatory_process, settings: { landing_page_content: description }) } let(:description) { { en: "Short description", ca: "Descripció curta", es: "Descripción corta" } } let(:budget) { budgets.first } let(:item) { page.find("#budgets .card--list__item", match: :first) } diff --git a/decidim-budgets_booth/spec/system/orders_spec.rb b/decidim-budgets_booth/spec/system/orders_spec.rb index 7e1851d4..08749922 100644 --- a/decidim-budgets_booth/spec/system/orders_spec.rb +++ b/decidim-budgets_booth/spec/system/orders_spec.rb @@ -52,7 +52,7 @@ context "when voting by percentage threshold" do it "displays description messages" do - within ".budget-summary", match: :first do + within ".layout-2col__aside", match: :first do expect(page).to have_content("Start adding projects. Assign at least €70,000,000 to the projects you want and vote according to your preferences to define the budget.") end end @@ -67,7 +67,8 @@ end it "displays description messages" do - within ".budget-summary", match: :first do + # text has been moved above filters in project index page + within ".layout-2col__aside", match: :first do expect(page).to have_content("Start adding projects. Select at least 3 projects you want and vote according to your preferences to define the budget.") end end @@ -83,7 +84,7 @@ end it "displays description messages" do - within ".budget-summary", match: :first do + within ".layout-2col__aside", match: :first do expect(page).to have_content("Start adding projects. Select up to 6 projects you want and vote according to your preferences to define the budget.") end end @@ -98,7 +99,7 @@ end it "displays description messages" do - within ".budget-summary", match: :first do + within ".layout-2col__aside", match: :first do expect(page).to have_content("Start adding projects. Select at least 3 and up to 6 projects you want and vote according to your preferences to define the budget.") end end @@ -109,7 +110,7 @@ it "displays total budget" do within ".budget-summary", match: :first do - expect(page).to have_content("€0\nBudget") + expect(page).to have_content("€0\nAssigned") end end end @@ -126,7 +127,7 @@ page.find(".budget-list__action").click end - expect(page).to have_text "Remove from vote", count: 1 + expect(page).to have_text "Added to vote", count: 1 within ".budget-summary__progressbar-marks", match: :first do expect(page).to have_content(/€25,000,000\sAssigned/) @@ -159,7 +160,7 @@ page.find(".budget-list__action").click end - expect(page).to have_text "Remove from vote", count: 1 + expect(page).to have_text "Added to vote", count: 1 within ".budget-summary__progressbar-marks", match: :first do expect(page).to have_content(/€25,000,000\sAssigned/) @@ -193,7 +194,7 @@ page.find(".budget-list__action").click end - expect(page).to have_text "Remove from vote", count: 1 + expect(page).to have_text "Added to vote", count: 1 within ".budget-summary__progressbar-marks", match: :first do expect(page).to have_content "1 / 6" @@ -226,7 +227,7 @@ page.find(".budget-list__action").click end - expect(page).to have_text "Remove from vote", count: 1 + expect(page).to have_text "Added to vote", count: 1 within ".budget-summary__progressbar-marks", match: :first do expect(page).to have_content "1 / 6" end @@ -366,7 +367,7 @@ page.find(".budget-list__action").click end - expect(page).to have_text "Remove from vote", count: 2 + expect(page).to have_text "Added to vote", count: 2 within "#order-progress .budget-summary__content", match: :first do page.find(".button", match: :first).click @@ -390,7 +391,7 @@ end it "shows the rule description" do - within ".budget-summary", match: :first do + within ".layout-2col__aside", match: :first do expect(page).to have_content("Assign at least €70,000,000 to the projects you want and vote") end end @@ -464,7 +465,7 @@ it "shows the rule description" do visit_budget - within ".budget-summary", match: :first do + within ".layout-2col__aside", match: :first do expect(page).to have_content("Select at least 3 projects you want and vote") end end @@ -474,7 +475,7 @@ visit_budget within "#order-progress", match: :first do - expect(page).to have_button("Vote", disabled: true) + expect(page).to have_button("Vote budget", disabled: true) end end end @@ -592,7 +593,7 @@ create(:budgets_component, manifest:, participatory_space: participatory_process, - settings: { maximum_budgets_to_vote_on: 5, vote_success_content: "Thanks for voting to that great budget" } + settings: { workflow: "all", maximum_budgets_to_vote_on: 5, vote_success_content: "Thanks for voting to that great budget" } ) end let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } @@ -708,7 +709,7 @@ it "renders selected projects" do visit_budget - expect(page).to have_css(".card__list-metadata .success", count: 2) + expect(page).to have_css(".card__list-metadata", count: 2) end it "does not show a filter to select added projects" do From a813c2cb28d798bb359f3c985b5e9f04e6367590 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 20 Dec 2024 17:23:19 +0100 Subject: [PATCH 35/93] feat: add i18n_spec file --- decidim-budgets_booth/spec/i18n_spec.rb | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 decidim-budgets_booth/spec/i18n_spec.rb diff --git a/decidim-budgets_booth/spec/i18n_spec.rb b/decidim-budgets_booth/spec/i18n_spec.rb new file mode 100644 index 00000000..47a3896f --- /dev/null +++ b/decidim-budgets_booth/spec/i18n_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "i18n/tasks" + +describe "I18n sanity" do + let(:locales) do + ENV["ENFORCED_LOCALES"].presence || "en, fr" + end + + let(:i18n) { I18n::Tasks::BaseTask.new(locales: locales.split(",")) } + let(:missing_keys) { i18n.missing_keys } + let(:unused_keys) { i18n.unused_keys } + let(:non_normalized_paths) { i18n.non_normalized_paths } + let(:inconsistent_interpolations) { i18n.inconsistent_interpolations } + + it "does not have missing keys" do + expect(missing_keys).to be_empty, + "Missing #{missing_keys.leaves.count} i18n keys, please run `ENFORCED_LOCALES=#{locales} bundle exec i18n-tasks missing --locales #{locales}' to show them" + end + + it "does not have unused keys" do + expect(unused_keys).to be_empty, + "#{unused_keys.leaves.count} unused i18n keys, please run `bundle exec i18n-tasks unused --locales #{locales}' to show them" + end + + unless ENV["SKIP_NORMALIZATION"] + it "is normalized" do + error_message = "The following files need to be normalized:\n" \ + "#{non_normalized_paths.map { |path| " #{path}" }.join("\n")}\n" \ + "Please run `bundle exec i18n-tasks normalize --locales #{locales}` to fix them" + + expect(non_normalized_paths).to be_empty, error_message + end + end + + it "does not have inconsistent interpolations" do + error_message = "#{inconsistent_interpolations.leaves.count} i18n keys have inconsistent interpolations.\n" \ + "Please run `bundle exec i18n-tasks check-consistent-interpolations --locales #{locales}` to show them" + expect(inconsistent_interpolations).to be_empty, error_message + end +end From 6f17d76dcb8ecf0aa8866c75c68cde8e6cd95e45 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 20 Dec 2024 17:24:28 +0100 Subject: [PATCH 36/93] feat: updates linked to i18n checks --- decidim-budgets_booth/config/i18n-tasks.yml | 12 +++++++ decidim-budgets_booth/config/locales/en.yml | 31 +++++++----------- decidim-budgets_booth/config/locales/fr.yml | 36 +++++++++------------ 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/decidim-budgets_booth/config/i18n-tasks.yml b/decidim-budgets_booth/config/i18n-tasks.yml index c2de4651..55905802 100644 --- a/decidim-budgets_booth/config/i18n-tasks.yml +++ b/decidim-budgets_booth/config/i18n-tasks.yml @@ -29,3 +29,15 @@ ignore_missing: - decidim.budgets.projects.project_budget_button.add - decidim.budgets.projects.project_budget_button.added_descriptive - decidim.budgets.projects.projects_for + - decidim.budgets.budget_information_modal.more_information + - decidim.budgets.projects.budget_confirm.are_you_sure + - decidim.budgets.projects.budget_summary.* + - decidim.budgets.projects.order_progress.assigned + - decidim.budgets.projects.order_progress.budget + - decidim.budgets.projects.order_progress.minimum + - decidim.searches.filters.search + - decidim.searches.filters_small_view.filter + - decidim.searches.filters_small_view.filter_and_search + - decidim.shared.confirm_modal.cancel + - decidim.shared.filter_form_help.* + - decidim.components.budgets.name diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 76ef73f0..0b278503 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -2,12 +2,12 @@ en: decidim: budgets: - budgets: - index: - not_allowed: You are not allowed to perform this action. budgets_list: - voted_on_all_allowed: You have voted on %{links}. You have voted on the maximum budgets allowed. + voted_on_all_allowed: You have voted on %{links}. You have voted on the maximum + budgets allowed. orders: + checkout: + error: There was a problem processing your vote. modal: assigned: 'Assigned: ' close: Close window @@ -19,13 +19,6 @@ en: add_to_vote: Add to your vote remove_from_vote: Added to vote projects: - cancel_voting_modal: - continue: Continue voting - description: If you cancel your vote, it will not be count for the final - result. In order to get your vote heard, please go back to cast your vote. - exit: I don't want to vote right now - label: Exit voting - title: Are you sure you don't want to cast your vote? index: projects_for: Projects for order_progress: @@ -41,14 +34,11 @@ en: show: budget: Budget voting: - general: - not_open_warning: Voting is not allowed. thanks_message_modal: continue: Continue default_text: Thank you for your participation title: Thank you for voting! vote_completed_modal: - close: Close continue: Continue title: You successfully completed your votes voted_summary_modal: @@ -58,15 +48,16 @@ en: title: Your vote voting_notification_event: notification_casted: Your vote has been casted - notification_title: You have successfully cast your vote for the budget %{budget_name} + notification_title: You have successfully cast your vote for the budget + %{budget_name} components: budgets: settings: global: maximum_budgets_to_vote_on: Maximum number of budgets that user can vote on (default is 0, which means user can vote on all available budgets) - vote_cancel_url: URL to redirect user when canceling voting (default - to the root path) + vote_cancel_url: URL to redirect user when canceling voting (default to + the root path) vote_completed_content: Popup text after voting in all available budgets vote_success_content: Popup text after each vote vote_success_url: URL to redirect user after voting on all available budgets @@ -74,11 +65,11 @@ en: layouts: decidim: budgets: - voting_notification: - notification: You are now in the voting booth. voting_menubar: - cancel_voting: Exit voting booth back_to_projects: Back to projects + cancel_voting: Exit voting booth + voting_notification: + notification: You are now in the voting booth. shared: layout_two_col: title: Projects for vote diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 06918134..368e3b8e 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -2,12 +2,12 @@ fr: decidim: budgets: - budgets: - index: - not_allowed: Vous n'êtes pas autorisé à effectuer cette action. budgets_list: - voted_on_all_allowed: Vous avez voté sur %{links}. Vous avez voté pour le maximum de budgets autorisé. + voted_on_all_allowed: Vous avez voté sur %{links}. Vous avez voté pour le + maximum de budgets autorisé. orders: + checkout: + error: Une erreur s'est produite lors du traitement de votre vote. modal: assigned: 'Attribuer: ' close: Fermer la fenêtre @@ -19,12 +19,6 @@ fr: add_to_vote: Ajouter au vote remove_from_vote: Ajouté au vote projects: - cancel_voting_modal: - continue: Continuer le vote - description: Si vous annulez votre vote, cela ne sera pas pris en compte pour le résultat final. Afin de faire compter votre vote, veuillez revenir en arrière pour le finaliser et le confirmer. - exit: Je ne veux pas voter pour le moment - label: Quitter le vote - title: Êtes-vous certain de vouloir annuler votre vote ? index: projects_for: Projets pour order_progress: @@ -40,14 +34,11 @@ fr: show: budget: Budget voting: - general: - not_open_warning: Le vote n'est pas autorisé. thanks_message_modal: continue: Continuer default_text: Merci pour votre participation title: Merci pour votre vote! vote_completed_modal: - close: Fermer continue: Continuer title: Vous avez complété vos votes avec succès voted_summary_modal: @@ -62,19 +53,24 @@ fr: budgets: settings: global: - maximum_budgets_to_vote_on: Nombre maximum de budgets sur lesquels l'utilisateur peut voter (par défaut à 0, ce qui signifie que l'utilisateur peut voter sur tous les budgets disponibles) - vote_cancel_url: URL de redirection de l'utilisateur lors de l'annulation du vote (par défaut vers la racine) - vote_completed_content: Texte de la modale après avoir voté pour tous les budgets disponibles + maximum_budgets_to_vote_on: Nombre maximum de budgets sur lesquels l'utilisateur + peut voter (par défaut à 0, ce qui signifie que l'utilisateur peut voter + sur tous les budgets disponibles) + vote_cancel_url: URL de redirection de l'utilisateur lors de l'annulation + du vote (par défaut vers la racine) + vote_completed_content: Texte de la modale après avoir voté pour tous + les budgets disponibles vote_success_content: Modale après chaque vote - vote_success_url: URL de redirection de l'utilisateur après avoir voté pour tous les budgets disponibles (par défaut vers la liste des budgets) + vote_success_url: URL de redirection de l'utilisateur après avoir voté + pour tous les budgets disponibles (par défaut vers la liste des budgets) layouts: decidim: budgets: - voting_notification: - notification: Vous êtes dans la cabine de vote. voting_menubar: - cancel_voting: Abandonner le vote back_to_projects: Retour aux projets + cancel_voting: Abandonner le vote + voting_notification: + notification: Vous êtes dans la cabine de vote. shared: layout_two_col: title: Projets à voter From 2944c13cf30d066b9e77b115b8756c8116b20172 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:20:00 +0100 Subject: [PATCH 37/93] feat: delete no more used files --- .../decidim/budgets/line_items_helper.rb | 11 --- .../helpers/decidim/budgets/voting_helper.rb | 11 --- .../budgets_booth/main_image_uploader.rb | 12 --- .../voting/_voted_summary_modal.html.erb | 25 ----- .../spec/shared/cancel_voting_examples.rb | 44 --------- .../spec/shared/ensure_user_data_examples.rb | 10 -- .../shared/ensure_user_sign_in_examples.rb | 10 -- .../ensure_zip_code_workflow_examples.rb | 10 -- .../shared/filtering_projects_examples.rb | 91 ------------------- .../spec/shared/non_voting_views_examples.rb | 29 ------ .../shared/not_allowable_voting_examples.rb | 10 -- .../render_new_zip_code_page_examples.rb | 11 --- 12 files changed, 274 deletions(-) delete mode 100644 decidim-budgets_booth/app/helpers/decidim/budgets/line_items_helper.rb delete mode 100644 decidim-budgets_booth/app/helpers/decidim/budgets/voting_helper.rb delete mode 100644 decidim-budgets_booth/app/uploaders/decidim/budgets_booth/main_image_uploader.rb delete mode 100644 decidim-budgets_booth/app/views/decidim/budgets/voting/_voted_summary_modal.html.erb delete mode 100644 decidim-budgets_booth/spec/shared/cancel_voting_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/ensure_user_data_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/ensure_user_sign_in_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/ensure_zip_code_workflow_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/filtering_projects_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/non_voting_views_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/not_allowable_voting_examples.rb delete mode 100644 decidim-budgets_booth/spec/shared/render_new_zip_code_page_examples.rb diff --git a/decidim-budgets_booth/app/helpers/decidim/budgets/line_items_helper.rb b/decidim-budgets_booth/app/helpers/decidim/budgets/line_items_helper.rb deleted file mode 100644 index ae7f05d7..00000000 --- a/decidim-budgets_booth/app/helpers/decidim/budgets/line_items_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - module LineItemsHelper - def voting_mode? - true - end - end - end -end diff --git a/decidim-budgets_booth/app/helpers/decidim/budgets/voting_helper.rb b/decidim-budgets_booth/app/helpers/decidim/budgets/voting_helper.rb deleted file mode 100644 index c7d21770..00000000 --- a/decidim-budgets_booth/app/helpers/decidim/budgets/voting_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Budgets - module VotingHelper - def voting_mode? - true - end - end - end -end diff --git a/decidim-budgets_booth/app/uploaders/decidim/budgets_booth/main_image_uploader.rb b/decidim-budgets_booth/app/uploaders/decidim/budgets_booth/main_image_uploader.rb deleted file mode 100644 index b729f456..00000000 --- a/decidim-budgets_booth/app/uploaders/decidim/budgets_booth/main_image_uploader.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module BudgetsBooth - # This class deals with uploading hero images to budgets. - class MainImageUploader < RecordImageUploader - set_variants do - { default: { resize_to_fit: [700, 300] } } - end - end - end -end diff --git a/decidim-budgets_booth/app/views/decidim/budgets/voting/_voted_summary_modal.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/voting/_voted_summary_modal.html.erb deleted file mode 100644 index a8de0939..00000000 --- a/decidim-budgets_booth/app/views/decidim/budgets/voting/_voted_summary_modal.html.erb +++ /dev/null @@ -1,25 +0,0 @@ -

diff --git a/decidim-budgets_booth/spec/shared/cancel_voting_examples.rb b/decidim-budgets_booth/spec/shared/cancel_voting_examples.rb deleted file mode 100644 index 785e766a..00000000 --- a/decidim-budgets_booth/spec/shared/cancel_voting_examples.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -shared_examples "cancel voting" do - before do - visit current_path - end - - it "redirects the user to root" do - click_button "Cancel voting" - within ".reveal" do - expect(page).to have_content "Are you sure you don't want to cast your vote?" - expect(page).to have_css("button.button.expanded", text: "Continue voting") - expect(page).to have_css("a.button.hollow.expanded", text: "I don't want to vote right now") - click_button "Continue voting" - end - click_button "Cancel voting" - within ".reveal" do - click_link "I don't want to vote right now" - end - expect(page).to have_current_path("/") - end - - context "when vote_cancel_url is set to a specific location" do - before do - component.update!(settings: component_settings.merge(workflow: "zip_code", vote_cancel_url: decidim_budgets.budgets_path)) - visit current_path - end - - it "redirects to the correct location" do - click_button "Cancel voting" - within ".reveal" do - expect(page).to have_content "Are you sure you don't want to cast your vote?" - expect(page).to have_css("button.button.expanded", text: "Continue voting") - expect(page).to have_css("a.button.hollow.expanded", text: "I don't want to vote right now") - click_button "Continue voting" - end - click_button "Cancel voting" - within ".reveal" do - click_link "I don't want to vote right now" - end - expect(page).to have_current_path(decidim_budgets.budgets_path) - end - end -end diff --git a/decidim-budgets_booth/spec/shared/ensure_user_data_examples.rb b/decidim-budgets_booth/spec/shared/ensure_user_data_examples.rb deleted file mode 100644 index 711e328e..00000000 --- a/decidim-budgets_booth/spec/shared/ensure_user_data_examples.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -shared_examples "ensure user data" do - it "redirects the user" do - expect(page).to have_current_path("/") - within_flash_messages do - expect(page).to have_content "You are not authorized to perform this action" - end - end -end diff --git a/decidim-budgets_booth/spec/shared/ensure_user_sign_in_examples.rb b/decidim-budgets_booth/spec/shared/ensure_user_sign_in_examples.rb deleted file mode 100644 index 57871cd0..00000000 --- a/decidim-budgets_booth/spec/shared/ensure_user_sign_in_examples.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -shared_examples "ensure user sign in" do - it "redirects user to the login page" do - expect(page).to have_current_path(decidim.new_user_session_path) - within_flash_messages do - expect(page).to have_content "You need to login first." - end - end -end diff --git a/decidim-budgets_booth/spec/shared/ensure_zip_code_workflow_examples.rb b/decidim-budgets_booth/spec/shared/ensure_zip_code_workflow_examples.rb deleted file mode 100644 index 4a0c7f62..00000000 --- a/decidim-budgets_booth/spec/shared/ensure_zip_code_workflow_examples.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -shared_examples "ensure zip code workflow" do - it "redirects user to root path" do - expect(page).to have_current_path "/" - within_flash_messages do - expect(page).to have_content "You are not allowed to perform this action." - end - end -end diff --git a/decidim-budgets_booth/spec/shared/filtering_projects_examples.rb b/decidim-budgets_booth/spec/shared/filtering_projects_examples.rb deleted file mode 100644 index b2f631a8..00000000 --- a/decidim-budgets_booth/spec/shared/filtering_projects_examples.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -shared_examples "filtering projects" do - let!(:project) { projects.first } - let!(:categories) { create_list(:category, 3, participatory_space: current_component.participatory_space) } - context "when filtering" do - it "allows searching by text" do - within ".filters__search" do - fill_in "filter[search_text_cont]", with: translated(project.title) - - find(".button").click - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - - it "allows filtering by scope" do - scope = create(:scope, organization: current_component.organization) - project.scope = scope - project.save - - visit_budget - - within ".filters__section.with_any_scope_check_boxes_tree_filter" do - uncheck "All" - check translated(scope.name) - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - - it "allows filtering by category" do - category = categories.first - project.category = category - project.save - - visit_budget - within ".filters__section.with_any_category_check_boxes_tree_filter" do - uncheck "All" - check translated(category.name) - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - - it "works with 'back to list' link" do - category = categories.first - project.category = category - project.save - - visit_budget - - within ".filters__section.with_any_category_check_boxes_tree_filter" do - uncheck "All" - check translated(category.name) - end - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - - find("a", text: "Read more", match: :first).click - click_link "View all projects" - - within "#projects" do - expect(page).to have_css(".budget-list__item", count: 1) - expect(page).to have_content(translated(project.title)) - end - end - end - - private - - def decidim_budgets - Decidim::EngineRouter.main_proxy(component) - end - - def visit_budget - page.visit decidim_budgets.budget_projects_path(budget) - end -end diff --git a/decidim-budgets_booth/spec/shared/non_voting_views_examples.rb b/decidim-budgets_booth/spec/shared/non_voting_views_examples.rb deleted file mode 100644 index 6155fc7d..00000000 --- a/decidim-budgets_booth/spec/shared/non_voting_views_examples.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -shared_examples "non-voting view" do - let(:projects_title) { projects.map { |p| p.title["en"] } } - let(:projects_budgets) { ["€25,000", "€50,000"] } - - it "changes the views in the index page" do - expect(page).to have_content "Welcome to the vote!" - expect(page).to have_content "START VOTING" - within ".budget-list__text.card__text", match: :first do - link_text = page.find("a", match: :first).text - expect(projects_title).to include(link_text) - end - within ".budget-list__data", match: :first do - project_budget = page.find("span.budget-list__data__number").text - expect(projects_budgets).to include(project_budget) - end - expect(page).to have_no_content("Add to your vote") - within ".budget-list__text.card__text", match: :first do - click_link "Read more" - end - expect(page).to have_content("Want to vote this project?") - expect(page).to have_content("Start voting") - expect(projects_budgets).to include(find(".definition-data__number").text) - expect(page).to have_content("View all projects") - click_link "View all projects" - expect(page).to have_css(".budget-list__item", count: projects.count) - end -end diff --git a/decidim-budgets_booth/spec/shared/not_allowable_voting_examples.rb b/decidim-budgets_booth/spec/shared/not_allowable_voting_examples.rb deleted file mode 100644 index 3830de77..00000000 --- a/decidim-budgets_booth/spec/shared/not_allowable_voting_examples.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -shared_examples "not allowable voting" do - it "redirects the user" do - expect(page).to have_current_path("/") - within_flash_messages do - expect(page).to have_content "You are not authorized to perform this action" - end - end -end diff --git a/decidim-budgets_booth/spec/shared/render_new_zip_code_page_examples.rb b/decidim-budgets_booth/spec/shared/render_new_zip_code_page_examples.rb deleted file mode 100644 index bdce6235..00000000 --- a/decidim-budgets_booth/spec/shared/render_new_zip_code_page_examples.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -shared_examples "rendering new zip code page" do |zip_code_length| - it "renders new zip code page correctly" do - expect(page).to have_current_path(decidim_budgets.new_zip_code_path) - expect(page).to have_no_selector(".flash") - expect(page).to have_content("Welcome to the") - expect(page).to have_content("Please provide your ZIP code to find your Participatory Budgeting ballots.") - expect(page).to have_css('input[type="text"]', count: zip_code_length) - end -end From bb0948358a9d1100d52dee0501bd7f2b723b164f Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:33:10 +0100 Subject: [PATCH 38/93] refactor: rubocop updates --- .../app/cells/decidim/budgets/project_cell.rb | 2 +- .../app/events/decidim/budgets_booth/order_created_event.rb | 6 +++--- decidim-budgets_booth/lib/decidim/budgets_booth.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb b/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb index b570920c..e3a60819 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_cell.rb @@ -17,7 +17,7 @@ def card_size case @options[:size] when :s "decidim/budgets/project_s" - when :g #added + when :g # added "decidim/budgets/project_g" else "decidim/budgets/project_l" diff --git a/decidim-budgets_booth/app/events/decidim/budgets_booth/order_created_event.rb b/decidim-budgets_booth/app/events/decidim/budgets_booth/order_created_event.rb index 8896ba8b..3849a096 100644 --- a/decidim-budgets_booth/app/events/decidim/budgets_booth/order_created_event.rb +++ b/decidim-budgets_booth/app/events/decidim/budgets_booth/order_created_event.rb @@ -6,14 +6,14 @@ class OrderCreatedEvent < Decidim::Events::BaseEvent include Decidim::Events::NotificationEvent def self.model_name - ActiveModel::Name.new(self, nil, I18n.t('decidim.budgets.voting.voting_notification_event.notification_casted')) + ActiveModel::Name.new(self, nil, I18n.t("decidim.budgets.voting.voting_notification_event.notification_casted")) end def notification_title I18n.t( - 'decidim.budgets.voting.voting_notification_event.notification_title', + "decidim.budgets.voting.voting_notification_event.notification_title", budget_name: resource_title - ) + ) end private diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth.rb b/decidim-budgets_booth/lib/decidim/budgets_booth.rb index c3edeeeb..72ea59cc 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "decidim/budgets_booth/engine" -#require "decidim/budgets_booth/workflows" +# require "decidim/budgets_booth/workflows" module Decidim # This namespace holds the logic of the `BudgetsBooth` component. This component From 06dc0687c892e869f721a6d22e2686edb4955472 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:34:40 +0100 Subject: [PATCH 39/93] feat: clean files in controller folder --- .../budgets_controller_extensions.rb | 23 ------------------- .../budgets_booth/complete_voting_popup.rb | 4 ++-- .../orders_controller_extensions.rb | 2 +- .../projects_controller_extensions.rb | 14 ++--------- 4 files changed, 5 insertions(+), 38 deletions(-) diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb index c6316ecb..d5a99620 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb @@ -8,34 +8,11 @@ module BudgetsControllerExtensions included do layout :determine_layout - #before_action :ensure_authenticated, if: :open_and_voting_booth_forced? - #before_action :ensure_user_zip_code, if: :open_and_voting_booth_forced? - #before_action :ensure_multiple_budgets, unless: :open_and_voting_booth_forced? - - #def index - # we need to redefine this action to avoid redirect in case of single budget - #end private def determine_layout "layouts/decidim/application" - #return layout unless voting_booth_forced? - - #return layout unless voting_enabled? - - #return layout if voted_all_budgets? - - #"decidim/budgets/voting_layout" - end - - #def open_and_voting_booth_forced? - # voting_booth_forced? && voting_open? - #end - - def layout - "layouts/decidim/application" - #current_participatory_space_manifest.context(current_participatory_space_context).layout end end end diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index 00189c25..2cffd142 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -32,11 +32,11 @@ def completed_vote_snippets def add_javascript_file if Rails.env.test? <<~HTML - + HTML else <<~HTML - + HTML end end diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb index c18d9bee..ede5f6e4 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb @@ -20,7 +20,7 @@ def checkout end on(:invalid) do - flash.now[:alert] = I18n.t("error", scope: "decidim.budgets.orders.checkout") + flash.now[:alert] = I18n.t("orders.checkout.error", scope: "decidim") redirect_to decidim_budgets.budgets_path end end diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb index 5a60052b..c5398dc3 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb @@ -7,30 +7,21 @@ module ProjectsControllerExtensions include VotingSupport included do - before_action :set_view_mode, only: :index # added - layout :determine_layout # added + before_action :set_view_mode, only: :index + layout :determine_layout def index raise ActionController::RoutingError, "Not Found" unless budget - - #raise ActionController::RoutingError, "Not Found" unless allow_access? end def show raise ActionController::RoutingError, "Not Found" unless budget raise ActionController::RoutingError, "Not Found" unless project - #raise ActionController::RoutingError, "Not Found" unless allow_access? end end private - #def allow_access? - # return false if voting_booth_forced? && voting_enabled? && !voted_this?(budget) - # - # true - #end - #added def determine_layout "decidim/budgets/voting_layout" end @@ -41,7 +32,6 @@ def set_view_mode end def default_view_mode - #@default_view_mode ||= current_component.settings.attachments_allowed? ? "grid" : "list" @default_view_mode = "grid" end end From af47a73deb3c2f551f3a2c195e09b78687961927 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:35:37 +0100 Subject: [PATCH 40/93] feat: updat helper and tests --- .../projects_helper_extensions.rb | 37 +--------- .../projects_helper_extensions_spec.rb | 74 ++++++++++--------- 2 files changed, 43 insertions(+), 68 deletions(-) diff --git a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb index 2e5b6a24..f388db61 100644 --- a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb +++ b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb @@ -6,11 +6,7 @@ module BudgetsBooth module ProjectsHelperExtensions include VotingSupport - delegate :progress?, :budgets, :user_zip_code, to: :current_workflow - - def voting_mode? - false - end + delegate :progress?, :budgets, to: :current_workflow def thanks_popup? session[:booth_thanks_message] == true @@ -32,49 +28,20 @@ def i18n_scope "decidim.budgets.projects.pre_voting_budget_summary.pre_vote" end - def vote_text - key = if current_workflow.vote_allowed?(budget) && progress?(budget) - :finish_voting - else - :start_voting - end - - t(key, scope: i18n_scope) - end - - def description_text - key = if current_workflow.vote_allowed?(budget) && progress?(budget) - :finish_description - else - :start_description - end - t(key, scope: i18n_scope) - end - def budgets_count Decidim::Budgets::Budget.where(component: current_component).count end - def current_phase - process = Decidim::ParticipatoryProcesses::OrganizationParticipatoryProcesses - .new(current_organization).query.find_by(slug: params[:participatory_process_slug]) - process&.active_step&.title - end - def voting_booth_forced? current_workflow.try(:voting_booth_forced?) end - #def voting_terms - # translated_attribute(component_settings.try(:voting_terms)).presence - #end - def toggle_view_mode_link(current_mode, target_mode, title, params) path = budget_projects_path(params.permit(:order, filter: {}).merge({ view_mode: target_mode })) icon_name = target_mode == "grid" ? "layout-grid-fill" : "list-check" icon_class = "view-icon--disabled" unless current_mode == target_mode - link_to path, remote: true, title: do + link_to path, remote: true, title: title do icon(icon_name, class: icon_class, role: "img", "aria-hidden": true) end end diff --git a/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb b/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb index 46077ac5..05a7316f 100644 --- a/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb +++ b/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb @@ -3,49 +3,57 @@ require "spec_helper" describe Decidim::BudgetsBooth::ProjectsHelperExtensions, type: :helper do - describe "#current_phase" do - let(:organization) { create(:organization) } - let(:participatory_process) { create(:participatory_process, organization: organization) } - let!(:step_one) do - create(:participatory_process_step, - active: true, - end_date: Time.zone.now.to_date, - participatory_process: participatory_process) - end - let!(:step_two) do - create(:participatory_process_step, - active: false, - end_date: 1.month.from_now.to_date, - participatory_process: participatory_process) - end + let(:organization) { create(:organization) } + let(:participatory_process) { create(:participatory_process, organization: organization) } + let!(:step_one) do + create(:participatory_process_step, + active: true, + end_date: Time.zone.now.to_date, + participatory_process: participatory_process) + end + let!(:step_two) do + create(:participatory_process_step, + active: false, + end_date: 1.month.from_now.to_date, + participatory_process: participatory_process) + end - before do - allow(helper).to receive_messages(current_organization: organization, params: { participatory_process_slug: participatory_process.slug }) - end + before do + allow(helper).to receive_messages(current_organization: organization, params: { participatory_process_slug: participatory_process.slug }) + end - it "returns the title of the active step in the current participatory process" do - expect(helper.current_phase).to eq(step_one.title) - end + describe "#projects_container_class" do + context "when view mode is grid" do + let(:view_mode) { "grid" } - context "when there is no active step in the current participatory process" do - before do - step_one.update(active: false) + it "returns the grid class" do + expect(helper.projects_container_class(view_mode)).to eq("card__grid-grid") end + end + + context "when view mode is list" do + let(:view_mode) { "list" } - it "returns nil" do - expect(helper.current_phase).to be_nil + it "returns the list class" do + expect(helper.projects_container_class(view_mode)).to eq("card__list-list") end end + end - context "when the current participatory process cannot be found" do - before do - # rubocop:disable RSpec/AnyInstance - allow_any_instance_of(Decidim::ParticipatoryProcessStep).to receive(:title).and_return(nil) - # rubocop:enable RSpec/AnyInstance + describe "#card_size_for_view_mode" do + context "when view mode is grid" do + let(:view_mode) { "grid" } + + it "returns the grid symbol" do + expect(helper.card_size_for_view_mode(view_mode)).to eq(:g) end + end + + context "when view mode is list" do + let(:view_mode) { "list" } - it "returns nil" do - expect(helper.current_phase).to be_nil + it "returns the list symbol" do + expect(helper.card_size_for_view_mode(view_mode)).to eq(:l) end end end From 5e9694dd1f7235f98345728940fa5d7fcc889f4c Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:36:06 +0100 Subject: [PATCH 41/93] feat: clean css file --- .../decidim/budgets_booth/budgets_booth.scss | 195 +----------------- 1 file changed, 3 insertions(+), 192 deletions(-) diff --git a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss index 1e69ab8b..bdf3941e 100644 --- a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss +++ b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss @@ -1,197 +1,5 @@ /* css for decidim_budgets_booth */ -$passive-item-color: #919191; -$active-item-color: black; -#voting-help, -#thanks-message{ - .reveal__header{ - border: hidden; - - .subtitle{ - font-size: 1.2rem; - } - } - - .voting-help-item{ - //@include breakpoint(medium down){ - // margin: 1rem 0; - //} - - .circle{ - &.active{ - fill: $active-item-color; - border: 4px solid $active-item-color; - - svg{ - fill: $active-item-color; - } - } - - display: block; - position: relative; - border: 2px solid $passive-item-color; - border-radius: 50%; - width: 150px; - height: 150px; - left: 10px; - - //@include breakpoint(medium down){ - // left: 20%; - //} - - svg{ - display: block; - position: relative; - fill: $passive-item-color; - top: 23px; - left: 22px; - width: 100px; - height: 100px; - } - } - - .help-description{ - margin-top: .5rem; - font-size: 1.2rem; - - span{ - &.strong{ - font-weight: 800; - } - } - - &.active{ - color: $active-item-color; - } - - color: $passive-item-color; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - } - } - - .card{ - &.card--secondary{ - .filters__section:first-child{ - display: none; - - //@include breakpoint(medium){ - // display: block; - //} - } - } - } -} - -.card--list__icon{ - margin-right: 0; -} - -.budget-summary__progressbox--fixed{ - padding: .5rem 2rem 1rem; - - //@include breakpoint(mediumlarge){ - // padding: 1rem 4rem; - //} -} - -.spaced-bottom{ - margin-bottom: .3rem; -} - -.budget-list{ - &__item{ - //@include breakpoint(medium down){ - // margin-bottom: 2rem; - // display: block; - //} - } - - &__data{ - justify-content: center; - } -} - -.flex-column{ - flex-direction: column; - - //@include breakpoint(medium down){ - // flex-direction: column; - //} -} - -.card{ - &.budget-summary{ - display: flex; - flex-direction: column; - - a{ - margin: 1rem 0 0; - } - } -} - -.customized-budget{ - margin: auto; -} - -.font-customizer{ - h2, - h3{ - font-size: 1.1rem; - } -} - -.voted-budget{ - filter: grayscale(100%); -} - -.flex-digits{ - display: flex; - justify-content: space-between; - - .flex-digits-input{ - display: flex; - flex: 0 0 auto; - - input{ - margin: 0 auto; - height: 2.5rem; - width: 2.5rem; - text-align: center; - - //@include breakpoint(smallmedium up){ - // height: 3rem; - // width: 3rem; - //} - } - } -} - -.zip-code-errors{ - .form-error{ - margin-top: 1rem; - } -} - -.booth-zipcode{ - &.thumbnail{ - padding-right: 4px !important; - padding-left: 4px !important; - } - - &.maximum-width{ - max-width: 430px; - } -} - -#affirm-checkbox{ - margin-top: 1rem; - font-weight: bold; -} -//new .budget__card__grid-project { display: flex; flex-direction: row; @@ -381,3 +189,6 @@ $active-item-color: black; .card-grid-selected { --tw-ring-color: var(--tertiary); } +.budget__list--header { + align-items: center; +} From c9aa67c9506c56087abd6dfa4840215ce25d43b1 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:36:42 +0100 Subject: [PATCH 42/93] feat: update locale files --- decidim-budgets_booth/config/locales/en.yml | 5 ----- decidim-budgets_booth/config/locales/fr.yml | 5 ----- 2 files changed, 10 deletions(-) diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 0b278503..1a9e83cc 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -41,11 +41,6 @@ en: vote_completed_modal: continue: Continue title: You successfully completed your votes - voted_summary_modal: - continue: Continue - label: Close - list_description: These are the projects you picked. - title: Your vote voting_notification_event: notification_casted: Your vote has been casted notification_title: You have successfully cast your vote for the budget diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 368e3b8e..cbb118fe 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -41,11 +41,6 @@ fr: vote_completed_modal: continue: Continuer title: Vous avez complété vos votes avec succès - voted_summary_modal: - continue: Continuer - label: Fermer - list_description: Voici les projets que vous avez sélectionnés. - title: Votre vote voting_notification_event: notification_casted: Votre vote a été enregistré notification_title: Vous avez voté avec succès pour le budget %{budget_name} From 19d277eab3d2852857f6e85f211c20614206386c Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:38:59 +0100 Subject: [PATCH 43/93] feat: clean voting_support file and update tests --- .../decidim/budgets_booth/voting_support.rb | 60 +-------------- .../budgets_booth/voting_support_spec.rb | 74 +++++++------------ 2 files changed, 28 insertions(+), 106 deletions(-) diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb index b0df7d5c..ebeb9ebc 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb @@ -9,65 +9,21 @@ def voting_booth_forced? current_workflow.try(:voting_booth_forced?) end - def voting_enabled? - current_component.current_settings.votes == "enabled" - end - - def ensure_authenticated - return true if current_user - - flash[:warning] = t("login_before_access", scope: "decidim.budgets.budgets.index") - redirect_to decidim.new_user_session_path - end - - def ensure_user_zip_code - return true if current_user.try(:budgets_user_data).present? - - redirect_to decidim_budgets.new_zip_code_path - end - - def ensure_multiple_budgets - budget = budgets.first - return true if budgets.count > 1 || budgets.count.zero? - - return redirect_to decidim_budgets.budget_voting_index_path(budget) if voting_booth_forced? - - redirect_to decidim_budgets.budget_projects_path(budget) - end - def decidim_budgets @decidim_budgets ||= Decidim::EngineRouter.main_proxy(current_component) end - def voted_any? - current_user && voted.any? - end - def status(budget) @status ||= current_workflow.status(budget) end - def ensure_voting_booth_forced - return true if voting_booth_forced? - - flash[:warning] = t("not_allowed", scope: "decidim.budgets.budgets.index") - redirect_to decidim.root_path - end - - def ensure_not_voted - return true unless voted_any? - - flash[:warning] = t("change_zip_code_after_vote", scope: "decidim.budgets.user_data.new") - redirect_to decidim.root_path - end - # maximum_budgets_to_vote_on is being set by the admin. the default is zero, which means users can # vote in all available budgets. To check that user has voted to all available budgets, we should # consider this settings as well. If budget component workflow is random or one, available budgets # will be equal to 1 def voted_all_budgets? default_limit = current_component.settings.maximum_budgets_to_vote_on || 0 - available_budgets = ["random", "one"].include?(current_component.settings.workflow) ? 1 : budgets.count + available_budgets = %w(random one).include?(current_component.settings.workflow) ? 1 : budgets.count vote_limit = if default_limit.zero? available_budgets else @@ -87,20 +43,6 @@ def success_redirect_path def cancel_redirect_path component_settings.try(:vote_cancel_url).presence || decidim.root_path end - - def hide_unvoted?(budget) - return false unless voting_open? - - return false if voted_this?(budget) - - return false unless voted_all_budgets? - - true - end - - def voted_this?(budget) - current_workflow.status(budget) == :voted - end end end end diff --git a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb index c29ac910..d3938b56 100644 --- a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb +++ b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb @@ -64,30 +64,6 @@ def voting_open? allow(dummy).to receive_messages(component: component, user: user, organization: organization, current_settings: component.current_settings) end - describe "#voting_enabled?" do - it "is enabled by default" do - expect(subject).to be_voting_enabled - end - end - - describe "#voted_any?" do - context "when user exist but not voted" do - it "returns false" do - expect(subject).not_to be_voted_any - end - end - - context "when voted" do - before do - vote_this(order, projects.first) - end - - it "returns true" do - expect(subject.voted_any?).to be(true) - end - end - end - describe "#voted_all_budgets?" do context "when maximum_budgets_to_vote_on is not set" do context "when not voted all of the budgets" do @@ -127,46 +103,50 @@ def voting_open? end end - describe "#hide_unvoted?" do - context "when maximum_budgets_to_vote_on is not set" do + describe "#success_redirect_path" do + context "when vote_succes_url is defined" do before do - vote_this(order, projects.first) + component.update!(settings: component_settings.merge(vote_success_url: "http://budget.org")) + allow(dummy).to receive(:component_settings).and_return(component.settings) end - it "does not hide any budgets" do - expect(subject.hide_unvoted?(budgets.first)).to be(false) - expect(subject.hide_unvoted?(budgets.second)).to be(false) + it "returns vote_success_url" do + expect(subject.success_redirect_path).to eq(component.settings.vote_success_url) end end - context "when maximum_budgets_to_vote_on is set" do + context "when vote_succes_url is not defined" do before do - component.update(settings: component_settings.merge(maximum_budgets_to_vote_on: 1)) - vote_this(order, projects.first) + component.update!(settings: component_settings.merge(vote_success_url: nil)) + allow(dummy).to receive(:component_settings).and_return(component.settings) end - it "does not hide voted budgets" do - expect(subject.hide_unvoted?(budgets.first)).to be(false) + it "returns budgets_path" do + expect(subject.success_redirect_path).to eq(Decidim::EngineRouter.main_proxy(component).budgets_path) end + end + end - it "hides unvoted budgets" do - expect(subject.hide_unvoted?(budgets.second)).to be(true) + describe "#cancel_redirect_path" do + context "when vote_cancel_url is defined" do + before do + component.update!(settings: component_settings.merge(vote_cancel_url: "http://budget.org")) + allow(dummy).to receive(:component_settings).and_return(component.settings) end - end - context "when voting is not open" do - let(:votes) { "disabled" } + it "returns vote_cancel_url" do + expect(subject.cancel_redirect_path).to eq(component.settings.vote_cancel_url) + end + end + context "when vote_cancel_url is not defined" do before do - component.update!(settings: component_settings.merge(maximum_budgets_to_vote_on: 1), step_settings: step_settings) - vote_this(order, projects.first) - - allow(dummy).to receive(:current_settings).and_return(component.current_settings) + component.update!(settings: component_settings.merge(vote_cancel_url: nil)) + allow(dummy).to receive_messages(component_settings: component.settings, decidim: Decidim::EngineRouter.main_proxy(component)) end - it "does not hide unvoted budgets, even when the maximum is reached" do - expect(subject.hide_unvoted?(budgets.first)).to be(false) - expect(subject.hide_unvoted?(budgets.second)).to be(false) + it "returns budgets_path" do + expect(subject.cancel_redirect_path).to eq(Decidim::EngineRouter.main_proxy(component).root_path) end end end From d6c5065de6fb2dbc34ffc149e5ec4d3279a2608c Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:39:28 +0100 Subject: [PATCH 44/93] feat: clean engine file --- decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb index 8beeb87b..43d140c8 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb @@ -69,7 +69,6 @@ class Engine < ::Rails::Engine Decidim::Budgets::ProjectsController.include( Decidim::BudgetsBooth::ProjectsControllerExtensions ) - end end @@ -80,10 +79,8 @@ class Engine < ::Rails::Engine settings.attribute :maximum_budgets_to_vote_on, type: :integer, default: 0 settings.attribute :vote_success_content, type: :text, translated: true, editor: true settings.attribute :vote_completed_content, type: :text, translated: true, editor: true - #settings.attribute :voting_terms, type: :text, translated: true, editor: true settings.attribute :vote_success_url, type: :string settings.attribute :vote_cancel_url, type: :string - #settings.attribute :show_full_description_on_listing_page, type: :boolean, default: false end end end From 14401e5143870ca734bf74f4cd9c76ca6b165907 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 26 Dec 2024 16:40:09 +0100 Subject: [PATCH 45/93] refactor: i18n spec file with rubocop --- decidim-budgets_booth/spec/i18n_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/decidim-budgets_booth/spec/i18n_spec.rb b/decidim-budgets_booth/spec/i18n_spec.rb index 47a3896f..b6473c36 100644 --- a/decidim-budgets_booth/spec/i18n_spec.rb +++ b/decidim-budgets_booth/spec/i18n_spec.rb @@ -26,8 +26,8 @@ unless ENV["SKIP_NORMALIZATION"] it "is normalized" do error_message = "The following files need to be normalized:\n" \ - "#{non_normalized_paths.map { |path| " #{path}" }.join("\n")}\n" \ - "Please run `bundle exec i18n-tasks normalize --locales #{locales}` to fix them" + "#{non_normalized_paths.map { |path| " #{path}" }.join("\n")}\n" \ + "Please run `bundle exec i18n-tasks normalize --locales #{locales}` to fix them" expect(non_normalized_paths).to be_empty, error_message end @@ -35,7 +35,7 @@ it "does not have inconsistent interpolations" do error_message = "#{inconsistent_interpolations.leaves.count} i18n keys have inconsistent interpolations.\n" \ - "Please run `bundle exec i18n-tasks check-consistent-interpolations --locales #{locales}` to show them" + "Please run `bundle exec i18n-tasks check-consistent-interpolations --locales #{locales}` to show them" expect(inconsistent_interpolations).to be_empty, error_message end end From 3c8deb22ebe9c5968d54642311b19da92f35b23b Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 09:10:40 +0100 Subject: [PATCH 46/93] feat: update gemfile --- Gemfile | 6 +++--- Gemfile.lock | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index bf9de6a3..81a40010 100644 --- a/Gemfile +++ b/Gemfile @@ -17,9 +17,9 @@ gem "decidim-ptp", path: "." gem "bootsnap", "~> 1.4" -gem "puma", ">= 6.3.1" - gem "faker", "~> 3.2" +gem "puma", ">= 6.3.1" +gem "uri", "~> 1.0.2" group :development, :test do gem "byebug", "~> 11.0", platform: :mri @@ -40,6 +40,6 @@ group :development do gem "letter_opener_web", "~> 2.0" gem "listen", "~> 3.1" gem "spring" - #gem "spring-watcher-listen", "~> 2.0" + # gem "spring-watcher-listen", "~> 2.0" gem "web-console", "~> 4.2" end diff --git a/Gemfile.lock b/Gemfile.lock index 7c4ad973..8decf53a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -772,7 +772,7 @@ GEM unaccent (0.4.0) unicode-display_width (2.6.0) uniform_notifier (1.16.0) - uri (0.13.1) + uri (1.0.2) valid_email2 (4.0.6) activemodel (>= 3.2) mail (~> 2.5) @@ -830,6 +830,7 @@ DEPENDENCIES puma (>= 6.3.1) rubocop-faker spring + uri (~> 1.0.2) web-console (~> 4.2) RUBY VERSION From 6f5a76a443ea05b45be55108ae38763b5b036bf2 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 10:30:41 +0100 Subject: [PATCH 47/93] feat: update platform in gemfile.lock --- Gemfile.lock | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 8decf53a..44740842 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -387,6 +387,7 @@ GEM faraday-net_http (3.3.0) net-http ffi (1.17.0-x86_64-darwin) + ffi (1.17.0-x86_64-linux-gnu) file_validators (3.0.0) activemodel (>= 3.2) mime-types (>= 1.0) @@ -518,6 +519,8 @@ GEM nio4r (2.7.3) nokogiri (1.16.7-x86_64-darwin) racc (~> 1.4) + nokogiri (1.16.7-x86_64-linux) + racc (~> 1.4) oauth (1.1.0) oauth-tty (~> 1.0, >= 1.0.1) snaky_hash (~> 2.0) @@ -814,6 +817,7 @@ GEM PLATFORMS x86_64-darwin-23 + x86_64-linux DEPENDENCIES bootsnap (~> 1.4) From c1c4efb090e0b36c7c86c06b2bd5ce8d27339e72 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 11:10:18 +0100 Subject: [PATCH 48/93] fix: update shared_context --- .../spec/shared/shared_context.rb | 52 ------------------- 1 file changed, 52 deletions(-) diff --git a/decidim-budgets_booth/spec/shared/shared_context.rb b/decidim-budgets_booth/spec/shared/shared_context.rb index e4ab64a8..a3c42041 100644 --- a/decidim-budgets_booth/spec/shared/shared_context.rb +++ b/decidim-budgets_booth/spec/shared/shared_context.rb @@ -3,34 +3,6 @@ shared_context "with scopes" do let(:parent_scope) { create(:scope, organization: organization) } let!(:subscopes) { create_list(:scope, 3, parent: parent_scope, organization: organization) } - let!(:first_postals) do - [].tap do |postals| - 5.times do |i| - code = (10_000 + i).to_s - postals << create(:scope, name: { en: code }, code: "FIRST_#{code}", parent: subscopes[0], organization: organization) - end - end - end - let!(:second_postals) do - [].tap do |postals| - 7.times do |i| - code = (10_010 + i).to_s - postals << create(:scope, name: { en: code }, code: "SECOND_#{code}", parent: subscopes[1], organization: organization) - end - end - end - let!(:third_postals) do - [].tap do |postals| - 8.times do |i| - code = (10_020 + i).to_s - postals << create(:scope, name: { en: code }, code: "THIRD_#{code}", parent: subscopes[2], organization: organization) - end - end - end -end - -shared_context "with user data" do - let!(:user_data) { create(:user_data, component: component, user: user) } end shared_context "with scoped budgets" do @@ -47,24 +19,10 @@ before do # We update the description to be less than the truncation limit. To test the truncation, we update those in tests. - attach_images(budgets) budgets[0].update!(scope: parent_scope, description: { en: "

Eius officiis expedita. 55

" }) budgets[1].update!(scope: subscopes[0], description: { en: "

Eius officiis expedita. 56

" }) budgets[2].update!(scope: subscopes[1]) end - - private - - def attach_images(budgets) - city_files = ["city.jpeg", "city2.jpeg", "city3.jpeg"] - budgets.each_with_index do |budget, ind| - budget.update(main_image: ActiveStorage::Blob.create_and_upload!( - io: File.open(Decidim::Dev.asset(city_files[ind])), - filename: city_files[ind], - content_type: "image/jpeg" - )) - end - end end shared_context "with single scoped budget" do @@ -82,16 +40,6 @@ def attach_images(budgets) end end -shared_context "with zip_code workflow" do - let!(:component) do - create( - :budgets_component, - settings: component_settings.merge(workflow: "zip_code"), - organization: organization - ) - end -end - shared_context "with a survey" do let!(:participatory_space) { component.participatory_space } let!(:surveys_component) { create(:surveys_component, :published, participatory_space: participatory_space) } From ce5b0a0160670cc8d6746a09908755224074eee5 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 11:42:47 +0100 Subject: [PATCH 49/93] update locales files --- decidim-budgets_booth/config/locales/en.yml | 5 +++-- decidim-budgets_booth/config/locales/fr.yml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 1a9e83cc..9e877788 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -1,13 +1,14 @@ --- en: decidim: + orders: + checkout: + error: There was a problem processing your vote. budgets: budgets_list: voted_on_all_allowed: You have voted on %{links}. You have voted on the maximum budgets allowed. orders: - checkout: - error: There was a problem processing your vote. modal: assigned: 'Assigned: ' close: Close window diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index cbb118fe..030fce8d 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -1,13 +1,14 @@ --- fr: decidim: + orders: + checkout: + error: Une erreur s'est produite lors du traitement de votre vote. budgets: budgets_list: voted_on_all_allowed: Vous avez voté sur %{links}. Vous avez voté pour le maximum de budgets autorisé. orders: - checkout: - error: Une erreur s'est produite lors du traitement de votre vote. modal: assigned: 'Attribuer: ' close: Fermer la fenêtre From 34e6df1e6d9d874cacb50f690c7300b81e90744f Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 12:04:57 +0100 Subject: [PATCH 50/93] refactor: with i18n normalize --- decidim-budgets_booth/config/locales/en.yml | 6 +++--- decidim-budgets_booth/config/locales/fr.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 9e877788..74296a0e 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -1,9 +1,6 @@ --- en: decidim: - orders: - checkout: - error: There was a problem processing your vote. budgets: budgets_list: voted_on_all_allowed: You have voted on %{links}. You have voted on the maximum @@ -58,6 +55,9 @@ en: vote_success_content: Popup text after each vote vote_success_url: URL to redirect user after voting on all available budgets (default is budgets list) + orders: + checkout: + error: There was a problem processing your vote. layouts: decidim: budgets: diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 030fce8d..9d9b1b8b 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -1,9 +1,6 @@ --- fr: decidim: - orders: - checkout: - error: Une erreur s'est produite lors du traitement de votre vote. budgets: budgets_list: voted_on_all_allowed: Vous avez voté sur %{links}. Vous avez voté pour le @@ -59,6 +56,9 @@ fr: vote_success_content: Modale après chaque vote vote_success_url: URL de redirection de l'utilisateur après avoir voté pour tous les budgets disponibles (par défaut vers la liste des budgets) + orders: + checkout: + error: Une erreur s'est produite lors du traitement de votre vote. layouts: decidim: budgets: From 5ad557dbba0bd7122c9457956fb1cdcfe96af87b Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 14:04:34 +0100 Subject: [PATCH 51/93] fix: modify add_javascript_file method to fix CI --- .../decidim/budgets_booth/complete_voting_popup.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index 2cffd142..a50599eb 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -31,9 +31,15 @@ def completed_vote_snippets def add_javascript_file if Rails.env.test? - <<~HTML - - HTML + if File.exist?(Rails.root.join("public", "packs-test", "js", "decidim_handle_voting_complete.js")) + <<~HTML + + HTML + else + <<~HTML + + HTML + end else <<~HTML From 9e6d98960f910c3f4894ffe83b3092ab7f812a6c Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 14:50:21 +0100 Subject: [PATCH 52/93] fix: modify CI to list js files in pack-tests --- .github/actions/module-rspec/action.yml | 4 ++++ .../decidim/budgets_booth/complete_voting_popup.rb | 12 +++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 2b52610f..cb55ba36 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -39,6 +39,10 @@ runs: name: Precompile assets working-directory: ./spec/decidim_dummy_app/ shell: "bash" + - run: ls -R public/packs-test/js + name: Debug assets + working-directory: ./spec/decidim_dummy_app/ + shell: "bash" - run: bundle exec rspec name: RSpec working-directory: ${{ inputs.name }} diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index a50599eb..2cffd142 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -31,15 +31,9 @@ def completed_vote_snippets def add_javascript_file if Rails.env.test? - if File.exist?(Rails.root.join("public", "packs-test", "js", "decidim_handle_voting_complete.js")) - <<~HTML - - HTML - else - <<~HTML - - HTML - end + <<~HTML + + HTML else <<~HTML From 0f88a588879b8a73609912fb6583f1dae47cb00e Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 15:36:30 +0100 Subject: [PATCH 53/93] fix: update add_javascript_file method to accessjs file --- .../concerns/decidim/budgets_booth/complete_voting_popup.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index 2cffd142..6b543ced 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -32,7 +32,7 @@ def completed_vote_snippets def add_javascript_file if Rails.env.test? <<~HTML - + HTML else <<~HTML From 3e8ed537f4c975c9ed3af8c96f37029a6d2cefe2 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 16:36:29 +0100 Subject: [PATCH 54/93] fix: remove list of js files in CI action --- .github/actions/module-rspec/action.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index cb55ba36..2b52610f 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -39,10 +39,6 @@ runs: name: Precompile assets working-directory: ./spec/decidim_dummy_app/ shell: "bash" - - run: ls -R public/packs-test/js - name: Debug assets - working-directory: ./spec/decidim_dummy_app/ - shell: "bash" - run: bundle exec rspec name: RSpec working-directory: ${{ inputs.name }} From 85883fcf0b44b414342352b707ed4725d181e982 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 16:37:47 +0100 Subject: [PATCH 55/93] feat: delete fi locales file --- decidim-budgets_booth/config/locales/fi.yml | 156 -------------------- 1 file changed, 156 deletions(-) delete mode 100644 decidim-budgets_booth/config/locales/fi.yml diff --git a/decidim-budgets_booth/config/locales/fi.yml b/decidim-budgets_booth/config/locales/fi.yml deleted file mode 100644 index b48c3827..00000000 --- a/decidim-budgets_booth/config/locales/fi.yml +++ /dev/null @@ -1,156 +0,0 @@ ---- -fi: - decidim: - budgets: - admin: - budgets: - edit: - images: Kuvat - budget_list_item: - current_phase: 'Käynnissä oleva vaihe: %{phase}' - more_info: Lisätietoja - show_my_vote: Näytä oma ääneni - take_part: Osallistu - budgets: - actions: - cancel_voting: Haluatko varmasti poistua äänestyskopista? - cancel_zip_code: Haluatko varmasti poistua? - index: - cancel_voting: Poistu äänestyksestä - login_before_access: Sinun täytyy kirjautua sisään ensin. - not_allowed: Tiliäsi ei ole vahvistettu tämän toiminnon suorittamiseen. - budgets_header: - based_on_zip_code: Perustuen postinumeroosi - %{zip_code}. - change_it_here: Muuta sitä tästä - not_right_one: Onko postinumero väärin? %{link} - title: 'Sinulle saatavilla olevat äänestykset' - budgets_list: - no_budgets_found: Äänestettäviä budjetteja ei löytynyt postinumerollasi. Voit vaihtaa postinumeroasi, jos se on väärin tai voit yrittää myöhemmin uudestaan. - vote: Näytä - orders: - modal: - assigned: 'Käytetty: ' - close: Sulje ikkuna - description: Olet valinnut nämä hankkeet osaksi budjettia. - ok: OK - title: Äänesi alueella %{budget_title} - total_budget: 'Kokonaisbudjetti: ' - partials: - voting_help_modal: - confirm: Ymmärrän, kuinka äänestän - step1: Valitse hanke - step2: Vahvista äänesi - step3: Anna äänesi - subtitle: Sinun on annettava äänesi, jotta se lasketaan lopullisiin tuloksiin. - title: Et ole vielä antanut ääntäsi. - project_list_item: - ordered_item: Tämä hanke on lisätty ääneesi. - read_more: Lue lisää - project_vote_button: - add_to_vote: Lisää ääneesi - remove_from_vote: Poista äänestäsi - projects: - budget_confirm: - is_this_correct: Onko tämä oikein? - budget_summary: - back_to_budgets: Näytä kaikki budjetit - cancel_voting: Poistu äänestyksestä - choose_budget: Voit päättää budjetista alueella %{budget_title} - choose_description: Valitse sellaiset hankkeet, joista pidät ja anna äänesi sen jälkeen. - cancel_voting_modal: - continue: Jatka äänestystä - description: Jos poistut äänestyksestä, ääntäsi ei lasketa lopulliseen tulokseen. Jos haluat äänesi vaikuttavan lopputulokseen, palaa takaisin äänestämään. - exit: En halua äänestää juuri nyt - label: Poistu äänestyksestä - title: Haluatko varmasti lopettaa äänestyksen? - index: - back_to_budgets: Takaisin kaikkiin budjetteihin - order_progress: - ready: Olen valmis - total_budget: 'Kokonaisbudjetti: ' - vote: Äänestä - pre_voting_budget_summary: - are_you_sure: Haluatko varmasti poistaa äänesi? - cancel_order: poistaa äänesi - pre_vote: - casted_description: Olet aikaisemmin äänestänyt tästä budjetista. Jos haluat nähdä, kuinka äänestit, paina "Tarkasta äänesi" -painiketta. Voit myös %{cancel_link} ja aloittaa alusta. - casted_title: Kiitos äänestäsi - finish_description: Olet jo aloittanut tämän budjetin äänestyksen. Haluaisitko viimeistellä äänesi? - finish_voting: Viimeistele äänestys - result_voted: Tarkasta äänesi - start_description: Voit selata hankkeita tutustuaksesi niihin. Aloittaaksesi äänestyksen, paina "Aloita äänestys" -painiketta. - start_voting: Aloita äänestys - title: Tervetuloa äänestämään! - ready: Olen valmis - project: - you_voted: Äänestit tätä - project_modal: - budget_amount: 'Budjetti: ' - cancel: Peruuta - category: 'Aihepiiri: ' - close_project: Sulje - scope: 'Teema: ' - show: - pre_vote: - continue_voting: Jatka äänestystä - introduction: Haluatko äänestää tätä hanketta? - start_voting: Aloita äänestys - user_data: - error: - only_letters: Vain kirjaimet ja numerot ovat sallittuja. - unknown: Jotain meni pieleen. Yritä uudestaan. - zip_code_empty: Postinumeron muoto ei ole oikein. - zip_code_included: Postinumerollasi ei löytynyt yhtään aluetta, jossa voisit äänestää. Tarkasta, että olet syöttänyt postinumerosi oikein ja yritä uudestaan. - new: - affirm_statements: Vahvistan, että esitetyt ehdot ovat oikein ja täytän äänestämisen vaatimukset. - cancel: Peruuta - change_zip_code_after_vote: Et voi muuttaa postinumeroasi sen jälkeen, kun olet aloittanut äänestyksen. Poista kaikki äänesi ennen postinumeron muuttamista. - description: Syötä postinumerosi löytääksesi sinulle saatavilla olevat äänestykset. - inputs: - one: Ensimmäinen merkki - other: merkki %{count} - must_be_accepted: täytyy olla hyväksytty - submit: Etsi äänestykset - title: Postinumero - voting_ended: Et voi asettaa postinumeroa, kun äänestys ei ole käynnissä. - welcome: Tervetuloa
osallistuvaan budjetointiin %{organization} -alustalla - success: Olet syöttänyt postinumerosi. - voting: - general: - not_open_warning: Äänestäminen ei ole sallittua. - index: - sign_in_first: Sinun täytyy kirjautua sisään äänestääksesi. - thanks_message_modal: - close: Sulje - continue: Jatka - title: Kiitos äänestäsi! - vote_completed_modal: - close: Sulje - continue: Jatka - title: Olet suorittanut äänestyksen - voted_summary_modal: - continue: Jatka - label: Sulje - list_description: Valitsit nämä hankkeet. - title: Äänesi - voting_notification_event: - notification_casted: Äänestys on suoritettu - notification_title: Olet onnistuneesti äänestänyt budjetista %{budget_name} - components: - budgets: - settings: - global: - maximum_budgets_to_vote_on: Budjettien maksimimäärä, joissa käyttäjät voivat äänestää (oletusarvo on 0, mikä tarkoittaa, että käyttäjä voi äänestää kaikissa budjeteissa) - show_full_description_on_listing_page: Näytä hankkeiden kuvaukset kokonaan listaussivulla ja poista lisätietoikkuna käytöstä - vote_cancel_url: URL-osoite, johon käyttäjät ohjataan poistuessa äänestyskopista kesken äänestyksen (oletuksena palvelun etusivu) - vote_completed_content: Ponnahdusikkunan teksti käyttäjän äänestettyä kaikissa budjeteissa - vote_success_content: Ponnahdusikkunan teksti jokaisen äänen jälkeen - vote_success_url: URL-osoite, johon käyttäjä ohjataan äänestettyään kaikissa budjeteissa (oletuksena budjettien listaussivu) - voting_terms: Postinumeron syöttämissivulla näytettävät ehdot - workflow_choices: - zip_code: 'Äänestä postinumeron perusteella: mahdollistaa äänestyksen budjeteissa, jotka täsmäävät käyttäjän postinumeron kanssa.' - layouts: - decidim: - budgets: - voting_notification: - notification: Olet nyt äänestyskopissa. From 23758d4ad2eabdf836c46f3397b8a5adf7cca957 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 16:50:39 +0100 Subject: [PATCH 56/93] ci: update to show missing keys --- .github/actions/module-rspec/action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 2b52610f..9e30b7d4 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -43,6 +43,12 @@ runs: name: RSpec working-directory: ${{ inputs.name }} shell: "bash" + - run: | + echo "Ruby version: $(ruby -v)" + echo "Bundle version: $(bundle -v)" + bundle exec i18n-tasks health + bundle exec i18n-tasks missing --locales en,fr + name: Debug missing keys - uses: codecov/codecov-action@v3 - uses: actions/upload-artifact@v3 if: always() From 3871224c3d1f4c0a82374657f464efafc2a62dc8 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 16:57:24 +0100 Subject: [PATCH 57/93] ci: update CI --- .github/actions/module-rspec/action.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 9e30b7d4..74031031 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -44,8 +44,6 @@ runs: working-directory: ${{ inputs.name }} shell: "bash" - run: | - echo "Ruby version: $(ruby -v)" - echo "Bundle version: $(bundle -v)" bundle exec i18n-tasks health bundle exec i18n-tasks missing --locales en,fr name: Debug missing keys From fd89f0a6b61cd815e2245071333d4e29c6dade1e Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 17:10:11 +0100 Subject: [PATCH 58/93] ci: another update of CI --- .github/actions/module-rspec/action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 74031031..11b5340a 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -45,8 +45,9 @@ runs: shell: "bash" - run: | bundle exec i18n-tasks health - bundle exec i18n-tasks missing --locales en,fr + bundle exec i18n-tasks missing name: Debug missing keys + shell: "bash" - uses: codecov/codecov-action@v3 - uses: actions/upload-artifact@v3 if: always() From 4d04b19dfb376acf5b5126ac5abb6a3fbc90bb71 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 17:17:22 +0100 Subject: [PATCH 59/93] ci: updating again --- .github/actions/module-rspec/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 11b5340a..a3ab2811 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -43,10 +43,10 @@ runs: name: RSpec working-directory: ${{ inputs.name }} shell: "bash" - - run: | - bundle exec i18n-tasks health - bundle exec i18n-tasks missing - name: Debug missing keys + - name: Debug missing keys + run: | + bundle exec i18n-tasks health + bundle exec i18n-tasks missing shell: "bash" - uses: codecov/codecov-action@v3 - uses: actions/upload-artifact@v3 From 7911a80a05e7b08e77c4a4bfd2c50fbd12aae3a6 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 27 Dec 2024 17:29:11 +0100 Subject: [PATCH 60/93] ci: trying another update --- .github/actions/module-rspec/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index a3ab2811..62282781 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -39,15 +39,15 @@ runs: name: Precompile assets working-directory: ./spec/decidim_dummy_app/ shell: "bash" - - run: bundle exec rspec - name: RSpec - working-directory: ${{ inputs.name }} - shell: "bash" - name: Debug missing keys run: | bundle exec i18n-tasks health bundle exec i18n-tasks missing shell: "bash" + - run: bundle exec rspec + name: RSpec + working-directory: ${{ inputs.name }} + shell: "bash" - uses: codecov/codecov-action@v3 - uses: actions/upload-artifact@v3 if: always() From 0d9b094ab80f2525f6bc9598bca26d9320a220e7 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 30 Dec 2024 08:36:50 +0100 Subject: [PATCH 61/93] ci: update to see missing keys --- .github/actions/module-rspec/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 62282781..4c29a36b 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -43,6 +43,7 @@ runs: run: | bundle exec i18n-tasks health bundle exec i18n-tasks missing + working-directory: ./spec/decidim_dummy_app/ shell: "bash" - run: bundle exec rspec name: RSpec From 5d0df00148eb1db6efd94dbf6d4c126c5205dc1c Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 30 Dec 2024 08:50:47 +0100 Subject: [PATCH 62/93] ci: updating again --- .github/actions/module-rspec/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 4c29a36b..d95b6c98 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -43,7 +43,7 @@ runs: run: | bundle exec i18n-tasks health bundle exec i18n-tasks missing - working-directory: ./spec/decidim_dummy_app/ + working-directory: ./ shell: "bash" - run: bundle exec rspec name: RSpec From fe6f5d7173f5f4c2498a4204a85ce51374984200 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 30 Dec 2024 09:10:36 +0100 Subject: [PATCH 63/93] fix: update i18n-task file --- decidim-budgets_booth/config/i18n-tasks.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/decidim-budgets_booth/config/i18n-tasks.yml b/decidim-budgets_booth/config/i18n-tasks.yml index 55905802..d8000397 100644 --- a/decidim-budgets_booth/config/i18n-tasks.yml +++ b/decidim-budgets_booth/config/i18n-tasks.yml @@ -1,7 +1,11 @@ --- +data: + read: + - config/locales/*.yml + - app/**/* base_locale: en -locales: [en] +locales: [en, fr] ignore_unused: - "decidim.components.ptp-budgets.name" From beccfa8d315e2ec2b17a3f24aac2ae4f12ffc781 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 30 Dec 2024 10:04:42 +0100 Subject: [PATCH 64/93] fix: updates to fix 35 missing locales --- .github/actions/module-rspec/action.yml | 6 ------ decidim-budgets_booth/config/i18n-tasks.yml | 4 ---- decidim-budgets_booth/spec/i18n_spec.rb | 2 +- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index d95b6c98..2b52610f 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -39,12 +39,6 @@ runs: name: Precompile assets working-directory: ./spec/decidim_dummy_app/ shell: "bash" - - name: Debug missing keys - run: | - bundle exec i18n-tasks health - bundle exec i18n-tasks missing - working-directory: ./ - shell: "bash" - run: bundle exec rspec name: RSpec working-directory: ${{ inputs.name }} diff --git a/decidim-budgets_booth/config/i18n-tasks.yml b/decidim-budgets_booth/config/i18n-tasks.yml index d8000397..2a1f9576 100644 --- a/decidim-budgets_booth/config/i18n-tasks.yml +++ b/decidim-budgets_booth/config/i18n-tasks.yml @@ -1,8 +1,4 @@ --- -data: - read: - - config/locales/*.yml - - app/**/* base_locale: en locales: [en, fr] diff --git a/decidim-budgets_booth/spec/i18n_spec.rb b/decidim-budgets_booth/spec/i18n_spec.rb index b6473c36..2d0fc3a6 100644 --- a/decidim-budgets_booth/spec/i18n_spec.rb +++ b/decidim-budgets_booth/spec/i18n_spec.rb @@ -4,7 +4,7 @@ describe "I18n sanity" do let(:locales) do - ENV["ENFORCED_LOCALES"].presence || "en, fr" + ENV["ENFORCED_LOCALES"].presence || "en,fr" end let(:i18n) { I18n::Tasks::BaseTask.new(locales: locales.split(",")) } From 4649060adf8ca1b6ab3434fc1c25f93a7df1fb86 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 30 Dec 2024 11:51:42 +0100 Subject: [PATCH 65/93] fix: updates with rubocop --- .rubocop.yml | 3 ++ .rubocop_ruby.yml | 2 ++ .../budgets_booth/complete_voting_popup.rb | 2 +- .../orders_controller_extensions.rb | 2 +- .../projects_controller_extensions.rb | 2 ++ .../projects_helper_extensions.rb | 2 +- .../decidim/budgets/project_g_cell_spec.rb | 2 -- .../budgets_controller_extensions_spec.rb | 30 ++++++++-------- .../orders_controller_extensions_spec.rb | 8 ++--- .../projects_controller_extensions_spec.rb | 14 ++++---- .../projects_helper_extensions_spec.rb | 6 ++-- .../budgets_booth/voting_support_spec.rb | 16 ++++----- .../spec/shared/shared_context.rb | 16 ++++----- .../spec/system/explore_budgets_spec.rb | 2 +- .../spec/system/explore_projects_spec.rb | 14 ++++---- .../spec/system/orders_spec.rb | 36 +++++++++---------- .../spec/system/sorting_projects_spec.rb | 34 +++++++++--------- 17 files changed, 95 insertions(+), 96 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 870c0b9f..c8a24046 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,6 @@ inherit_from: - .rubocop_ruby.yml - .rubocop_rails.yml + +AllCops: + TargetRubyVersion: 3.2 diff --git a/.rubocop_ruby.yml b/.rubocop_ruby.yml index fbfa843e..88c8e7e6 100644 --- a/.rubocop_ruby.yml +++ b/.rubocop_ruby.yml @@ -1237,6 +1237,8 @@ RSpec/DescribeClass: - "**/*/spec/**/*_badge_spec.rb" - decidim-core/spec/lib/global_engines_spec.rb - "**/tasks/**/*" + - decidim-budgets_booth/spec/system/** + - decidim-budgets_booth/spec/i18n_spec.rb RSpec/EmptyExampleGroup: Exclude: diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index 6b543ced..211d0fb0 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -32,7 +32,7 @@ def completed_vote_snippets def add_javascript_file if Rails.env.test? <<~HTML - + HTML else <<~HTML diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb index ede5f6e4..f49af97b 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/orders_controller_extensions.rb @@ -11,7 +11,7 @@ module OrdersControllerExtensions helper_method :budget def checkout - enforce_permission_to :vote, :project, order: current_order, budget: budget, workflow: current_workflow + enforce_permission_to :vote, :project, order: current_order, budget:, workflow: current_workflow Decidim::Budgets::Checkout.call(current_order) do on(:ok) do reset_workflow diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb index c5398dc3..71f8b1a7 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/projects_controller_extensions.rb @@ -7,7 +7,9 @@ module ProjectsControllerExtensions include VotingSupport included do + # rubocop:disable Rails/LexicallyScopedActionFilter before_action :set_view_mode, only: :index + # rubocop:enable Rails/LexicallyScopedActionFilter layout :determine_layout def index diff --git a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb index f388db61..6c80dee7 100644 --- a/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb +++ b/decidim-budgets_booth/app/helpers/concerns/decidim/budgets_booth/projects_helper_extensions.rb @@ -41,7 +41,7 @@ def toggle_view_mode_link(current_mode, target_mode, title, params) icon_name = target_mode == "grid" ? "layout-grid-fill" : "list-check" icon_class = "view-icon--disabled" unless current_mode == target_mode - link_to path, remote: true, title: title do + link_to(path, remote: true, title:) do icon(icon_name, class: icon_class, role: "img", "aria-hidden": true) end end diff --git a/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb b/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb index f8122009..51a16f72 100644 --- a/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb +++ b/decidim-budgets_booth/spec/cells/decidim/budgets/project_g_cell_spec.rb @@ -8,7 +8,6 @@ module Decidim::Budgets subject(:cell_html) { my_cell.call } - let(:my_cell) { cell("decidim/budgets/project_g", project, card_size: :g) } let!(:organization) { create(:organization) } let!(:budgets_component) { create(:budgets_component, organization:) } @@ -50,4 +49,3 @@ module Decidim::Budgets end end end - diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb index 4e666273..c3e05799 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb @@ -15,7 +15,7 @@ module BudgetsBooth let(:organization) { create(:organization) } let(:component) { create(:budgets_component, organization:, settings: component_settings) } let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:component_settings) { { votes: "enabled" } } + let(:component_settings) { { votes: "enabled" } } let!(:budgets) do [].tap do |list| list << create(:budget, component:) @@ -24,31 +24,29 @@ module BudgetsBooth end end - before do request.env["decidim.current_organization"] = organization request.env["decidim.current_participatory_space"] = component.participatory_space request.env["decidim.current_component"] = component end - context "when voting enabled" do - it "renders index with budgets_booth application layout" do - get :index - expect(response).to render_template(:index, layout: "layouts/decidim/application") - end + context "when voting enabled" do + it "renders index with budgets_booth application layout" do + get :index + expect(response).to render_template(:index, layout: "layouts/decidim/application") end + end - context "when voting is not enabled" do - before do - component.update(settings: component_settings.merge(votes: "finished")) - end - - it "renders index with budgets_booth voting_layout" do - get :index - expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") - end + context "when voting is not enabled" do + before do + component.update(settings: component_settings.merge(votes: "finished")) end + it "renders index with budgets_booth voting_layout" do + get :index + expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") + end + end end end end diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb index 550cd446..6ba41a27 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb @@ -14,10 +14,10 @@ let(:user) { create(:user, :confirmed, organization:) } let(:component) { create(:budgets_component, organization:) } let(:projects_count) { 5 } - let!(:budgets) { create_list(:budget, 3, component: component, total_budget: 100_000_000) } + let!(:budgets) { create_list(:budget, 3, component:, total_budget: 100_000_000) } let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 75_000_000) } - let!(:order) { create(:order, user: user, budget: budgets.first) } + let!(:order) { create(:order, user:, budget: budgets.first) } before do request.env["decidim.current_organization"] = organization @@ -26,8 +26,7 @@ request.env["decidim.current_component"] = component order.projects << projects.first order.save! - allow(controller).to receive(:budget).and_return(budgets.first) - allow(controller).to receive(:current_user).and_return(user) + allow(controller).to receive_messages(budget: budgets.first, current_user: user) end describe "#checkout" do @@ -35,6 +34,7 @@ before do component.update!(settings: { workflow: "all" }) end + it "sets thanks session and redirects the user" do post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } expect(session[:booth_thanks_message]).to be(true) diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb index 30e0d0d6..167eecae 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/projects_controller_extensions_spec.rb @@ -17,15 +17,15 @@ module BudgetsBooth let(:component) do create( :budgets_component, - step_settings: step_settings, - participatory_space: participatory_space, - organization: organization + step_settings:, + participatory_space:, + organization: ) end - let(:parent_scope) { create(:scope, organization: organization) } - let(:step_settings) { { active_step_id => { votes: votes } } } + let(:parent_scope) { create(:scope, organization:) } + let(:step_settings) { { active_step_id => { votes: } } } let(:active_step_id) { participatory_space.active_step.id } - let!(:budgets) { create_list(:budget, 3, component: component) } + let!(:budgets) { create_list(:budget, 3, component:) } let(:project) { create(:project, budget: budgets.last) } let(:votes) { "enabled" } let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } @@ -64,7 +64,7 @@ module BudgetsBooth context "when budget and no project" do it "raises error" do expect do - get :show, params: { id: 1000000, budget_id: budgets.last.id } + get :show, params: { id: 1_000_000, budget_id: budgets.last.id } end.to raise_error(ActionController::RoutingError, "Not Found") end end diff --git a/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb b/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb index 05a7316f..a4b4dce2 100644 --- a/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb +++ b/decidim-budgets_booth/spec/helpers/decidim/budgets_booth/projects_helper_extensions_spec.rb @@ -4,18 +4,18 @@ describe Decidim::BudgetsBooth::ProjectsHelperExtensions, type: :helper do let(:organization) { create(:organization) } - let(:participatory_process) { create(:participatory_process, organization: organization) } + let(:participatory_process) { create(:participatory_process, organization:) } let!(:step_one) do create(:participatory_process_step, active: true, end_date: Time.zone.now.to_date, - participatory_process: participatory_process) + participatory_process:) end let!(:step_two) do create(:participatory_process_step, active: false, end_date: 1.month.from_now.to_date, - participatory_process: participatory_process) + participatory_process:) end before do diff --git a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb index d3938b56..26d8349c 100644 --- a/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb +++ b/decidim-budgets_booth/spec/lib/decidim/budgets_booth/voting_support_spec.rb @@ -40,28 +40,28 @@ def voting_open? create( :budgets_component, settings: component_settings.merge(workflow: "all"), - step_settings: step_settings, - organization: organization + step_settings:, + organization: ) end - let(:step_settings) { { active_step_id => { votes: votes } } } + let(:step_settings) { { active_step_id => { votes: } } } let(:votes) { "enabled" } let(:active_step_id) { component.participatory_space.active_step.id } - let!(:user) { create(:user, :confirmed, organization: organization) } + let!(:user) { create(:user, :confirmed, organization:) } let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } let(:projects_count) { 5 } let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 75_000) } let(:second_projects) { create_list(:project, 3, budget: budgets.second, budget_amount: 75_000) } let(:third_projects) { create_list(:project, 3, budget: budgets.third, budget_amount: 75_000) } - let!(:order) { create(:order, user: user, budget: budgets.first) } - let!(:second_order) { create(:order, user: user, budget: budgets.second) } - let!(:third_order) { create(:order, user: user, budget: budgets.third) } + let!(:order) { create(:order, user:, budget: budgets.first) } + let!(:second_order) { create(:order, user:, budget: budgets.second) } + let!(:third_order) { create(:order, user:, budget: budgets.third) } include_context "with scoped budgets" before do component.update!(settings: component_settings.merge(workflow: "all")) - allow(dummy).to receive_messages(component: component, user: user, organization: organization, current_settings: component.current_settings) + allow(dummy).to receive_messages(component:, user:, organization:, current_settings: component.current_settings) end describe "#voted_all_budgets?" do diff --git a/decidim-budgets_booth/spec/shared/shared_context.rb b/decidim-budgets_booth/spec/shared/shared_context.rb index a3c42041..460555d0 100644 --- a/decidim-budgets_booth/spec/shared/shared_context.rb +++ b/decidim-budgets_booth/spec/shared/shared_context.rb @@ -1,18 +1,18 @@ # frozen_string_literal: true shared_context "with scopes" do - let(:parent_scope) { create(:scope, organization: organization) } - let!(:subscopes) { create_list(:scope, 3, parent: parent_scope, organization: organization) } + let(:parent_scope) { create(:scope, organization:) } + let!(:subscopes) { create_list(:scope, 3, parent: parent_scope, organization:) } end shared_context "with scoped budgets" do include_context "with scopes" let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, settings: component_settings, organization: organization) } + let(:component) { create(:budgets_component, settings: component_settings, organization:) } let(:component_settings) { { scopes_enabled: true, scope_id: parent_scope.id } } - let(:budgets) { create_list(:budget, 3, component: component, total_budget: 100_000) } + let(:budgets) { create_list(:budget, 3, component:, total_budget: 100_000) } let!(:first_projects_set) { create_list(:project, projects_count, budget: budgets[0], budget_amount: 25_000) } let!(:second_projects_set) { create_list(:project, projects_count, budget: budgets[1], budget_amount: 25_000) } let!(:last_projects_set) { create_list(:project, projects_count, budget: budgets[2], budget_amount: 25_000) } @@ -29,11 +29,11 @@ include_context "with scopes" let(:organization) { create(:organization) } - let(:component) { create(:budgets_component, settings: component_settings, organization: organization) } + let(:component) { create(:budgets_component, settings: component_settings, organization:) } let(:component_settings) { { scopes_enabled: true, scope_id: parent_scope.id } } - let!(:budget) { create(:budget, component: component, total_budget: 100_000) } - let!(:projects_set) { create_list(:project, 3, budget: budget, budget_amount: 25_000) } + let!(:budget) { create(:budget, component:, total_budget: 100_000) } + let!(:projects_set) { create_list(:project, 3, budget:, budget_amount: 25_000) } before do budget.update!(scope: subscopes[0], description: { en: "

Eius officiis expedita. 55

" }) @@ -42,7 +42,7 @@ shared_context "with a survey" do let!(:participatory_space) { component.participatory_space } - let!(:surveys_component) { create(:surveys_component, :published, participatory_space: participatory_space) } + let!(:surveys_component) { create(:surveys_component, :published, participatory_space:) } let!(:survey) { create(:survey, component: surveys_component) } let!(:questionnaire) { create(:questionnaire, questionnaire_for: survey) } end diff --git a/decidim-budgets_booth/spec/system/explore_budgets_spec.rb b/decidim-budgets_booth/spec/system/explore_budgets_spec.rb index 781cea40..c4a0a566 100644 --- a/decidim-budgets_booth/spec/system/explore_budgets_spec.rb +++ b/decidim-budgets_booth/spec/system/explore_budgets_spec.rb @@ -61,7 +61,7 @@ end describe "budget list item" do - let!(:component){ create(:budgets_component, :with_vote_threshold_percent, manifest:, participatory_space: participatory_process, settings: { landing_page_content: description }) } + let!(:component) { create(:budgets_component, :with_vote_threshold_percent, manifest:, participatory_space: participatory_process, settings: { landing_page_content: description }) } let(:description) { { en: "Short description", ca: "Descripció curta", es: "Descripción corta" } } let(:budget) { budgets.first } let(:item) { page.find("#budgets .card--list__item", match: :first) } diff --git a/decidim-budgets_booth/spec/system/explore_projects_spec.rb b/decidim-budgets_booth/spec/system/explore_projects_spec.rb index 515b1d22..9a258b17 100644 --- a/decidim-budgets_booth/spec/system/explore_projects_spec.rb +++ b/decidim-budgets_booth/spec/system/explore_projects_spec.rb @@ -5,17 +5,17 @@ describe "Explore projects", :slow do include_context "with a component" let(:manifest_name) { "budgets" } - let(:budget) { create(:budget, component: component) } + let(:budget) { create(:budget, component:) } let(:projects_count) { 5 } let!(:projects) do - create_list(:project, projects_count, budget: budget) + create_list(:project, projects_count, budget:) end let!(:project) { projects.first } let(:categories) { create_list(:category, 3, participatory_space: component.participatory_space) } describe "show" do let(:description) { { en: "Short description", ca: "Descripció curta", es: "Descripción corta" } } - let(:project) { create(:project, budget: budget, description: description) } + let(:project) { create(:project, budget:, description:) } before do visit_budget @@ -83,8 +83,8 @@ end it "updates the current URL with the text filter" do - create(:project, budget: budget, title: { en: "Foobar project" }) - create(:project, budget: budget, title: { en: "Another project" }) + create(:project, budget:, title: { en: "Foobar project" }) + create(:project, budget:, title: { en: "Another project" }) visit_budget within "aside form.new_filter" do @@ -102,7 +102,7 @@ end it "allows filtering by scope" do - scope = create(:scope, organization: organization) + scope = create(:scope, organization:) project.scope = scope project.save @@ -139,7 +139,7 @@ let!(:component) do create(:budgets_component, :with_voting_finished, - manifest: manifest, + manifest:, participatory_space: participatory_process) end diff --git a/decidim-budgets_booth/spec/system/orders_spec.rb b/decidim-budgets_booth/spec/system/orders_spec.rb index 08749922..b496c264 100644 --- a/decidim-budgets_booth/spec/system/orders_spec.rb +++ b/decidim-budgets_booth/spec/system/orders_spec.rb @@ -329,7 +329,7 @@ # page.find_by_id("exit-notification-link").click # expect(page).to have_content("Logged out successfully") - #end + # end context "and try to vote a project that exceed the total budget" do let!(:expensive_project) { create(:project, budget:, budget_amount: 250_000_000) } @@ -501,8 +501,7 @@ create(:budgets_component, manifest:, participatory_space: participatory_process, - settings: { maximum_budgets_to_vote_on: 1, vote_completed_content: "You have completed your votes" } - ) + settings: { maximum_budgets_to_vote_on: 1, vote_completed_content: "You have completed your votes" }) end let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } let(:budget_two) { create(:budget, component:) } @@ -510,9 +509,9 @@ it "can only vote for one budget and display the vote-conpleted modal" do visit_budget - #confirm the pending order + # confirm the pending order within ".budget-summary__progressbox-buttons" do - page.find('button').click + page.find("button").click end expect(page).to have_css("#budget-confirm", visible: :visible) @@ -532,7 +531,7 @@ # can't access projects from second budget within "#budgets" do within ".budget__card__highlight-vote" do - expect(page).to have_button('See projects', disabled: true) + expect(page).to have_button("See projects", disabled: true) end end end @@ -543,8 +542,7 @@ create(:budgets_component, manifest:, participatory_space: participatory_process, - settings: { vote_success_url: "/processes" } - ) + settings: { vote_success_url: "/processes" }) end let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } @@ -552,7 +550,7 @@ visit_budget # confirm the pending order within ".budget-summary__progressbox-buttons" do - page.find('button').click + page.find("button").click end expect(page).to have_css("#budget-confirm", visible: :visible) @@ -569,19 +567,18 @@ create(:budgets_component, manifest:, participatory_space: participatory_process, - settings: { vote_cancel_url: "/processes" } - ) + settings: { vote_cancel_url: "/processes" }) end it "redirects to vote_cancel_url when order is cancelled" do visit_budget # exit voting booth with pending order within "#menu-bar-custom" do - page.find('.menu-bar__exit-link').click + page.find(".menu-bar__exit-link").click end # click on exit button in modal within "#exit-notification-content" do - page.find('#exit-notification-link').click + page.find("#exit-notification-link").click end # check we are in processes index expect(page).to have_css("h1", text: "Processes") @@ -593,8 +590,7 @@ create(:budgets_component, manifest:, participatory_space: participatory_process, - settings: { workflow: "all", maximum_budgets_to_vote_on: 5, vote_success_content: "Thanks for voting to that great budget" } - ) + settings: { workflow: "all", maximum_budgets_to_vote_on: 5, vote_success_content: "Thanks for voting to that great budget" }) end let!(:projects) { create_list(:project, 3, budget:, budget_amount: 70_000_000) } let(:budget_two) { create(:budget, component:) } @@ -604,7 +600,7 @@ visit_budget # confirm the pending order within ".budget-summary__progressbox-buttons" do - page.find('button').click + page.find("button").click end expect(page).to have_css("#budget-confirm", visible: :visible) @@ -672,7 +668,7 @@ end end - #context "and show votes are enabled" do + # context "and show votes are enabled" do # let!(:component) do # create(:budgets_component, # :with_show_votes_enabled, @@ -688,14 +684,14 @@ # order # end - #it "displays the number of votes for a project" do - # visit_budget + # it "displays the number of votes for a project" do + # visit_budget # within "#project-#{project.id}-item .card__grid" do # expect(page).to have_css(".project-votes", text: "1 vote") # end # end - #end + # end context "and votes are finished" do let!(:component) do diff --git a/decidim-budgets_booth/spec/system/sorting_projects_spec.rb b/decidim-budgets_booth/spec/system/sorting_projects_spec.rb index 04c4d0dd..af2b335b 100644 --- a/decidim-budgets_booth/spec/system/sorting_projects_spec.rb +++ b/decidim-budgets_booth/spec/system/sorting_projects_spec.rb @@ -18,8 +18,8 @@ end let(:budget) { create(:budget, component:) } - let!(:project1) { create(:project, budget:, budget_amount: 25_000_000) } - let!(:project2) { create(:project, budget:, budget_amount: 50_000_000) } + let!(:project_one) { create(:project, budget:, budget_amount: 25_000_000) } + let!(:project_two) { create(:project, budget:, budget_amount: 50_000_000) } before do login_as user, scope: :user @@ -49,15 +49,15 @@ context "when ordering by highest cost" do it_behaves_like "ordering projects by selected option", "Highest cost" do - let(:first_project) { project2 } - let(:last_project) { project1 } + let(:first_project) { project_two } + let(:last_project) { project_one } end end context "when ordering by lowest cost" do it_behaves_like "ordering projects by selected option", "Lowest cost" do - let(:first_project) { project1 } - let(:last_project) { project2 } + let(:first_project) { project_one } + let(:last_project) { project_two } end end @@ -70,13 +70,13 @@ participatory_space: participatory_process ) end - let!(:project1) { create(:project, :selected, budget:, budget_amount: 25_000_000) } - let!(:project2) { create(:project, :selected, budget:, budget_amount: 77_000_000) } + let!(:project_one) { create(:project, :selected, budget:, budget_amount: 25_000_000) } + let!(:project_two) { create(:project, :selected, budget:, budget_amount: 77_000_000) } context "when ordering by most votes" do before do order = build(:order, budget:) - create(:line_item, order:, project: project2) + create(:line_item, order:, project: project_two) order = Decidim::Budgets::Order.last order.checked_out_at = Time.zone.now order.save @@ -89,8 +89,8 @@ expect(page).to have_css("a.underline.font-bold", text: "Most voted") end - expect(page).to have_css("#projects .card__grid-grid .card__grid:first-child h3", text: translated(project2.title)) - expect(page).to have_css("#projects .card__grid-grid .card__grid:last-child h3", text: translated(project1.title)) + expect(page).to have_css("#projects .card__grid-grid .card__grid:first-child h3", text: translated(project_two.title)) + expect(page).to have_css("#projects .card__grid-grid .card__grid:last-child h3", text: translated(project_one.title)) end it "automatically sorts by votes and respect the pagination" do @@ -102,18 +102,18 @@ expect(page).to have_css("a.underline.font-bold", text: "Most voted") end - # project2 on first page - expect(page).to have_content(translated(project2.title)) - expect(page).to have_no_content(translated(project1.title)) + # project_two on first page + expect(page).to have_content(translated(project_two.title)) + expect(page).to have_no_content(translated(project_one.title)) within "#projects [data-pagination]" do expect(page).to have_content("2") page.find("a", text: "2").click end - # project1 on second page - expect(page).to have_no_content(translated(project2.title)) - expect(page).to have_content(translated(project1.title)) + # project_one on second page + expect(page).to have_no_content(translated(project_two.title)) + expect(page).to have_content(translated(project_one.title)) end end end From 7797825087a742963bb04d960ee1607c9d434307 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 3 Jan 2025 15:59:04 +0100 Subject: [PATCH 66/93] refactor: update style --- .../decidim/budgets_booth/budgets_booth.scss | 12 ++++++++++-- .../layouts/decidim/budgets/_voting_wrapper.html.erb | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss index bdf3941e..1168f63b 100644 --- a/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss +++ b/decidim-budgets_booth/app/packs/stylesheets/decidim/budgets_booth/budgets_booth.scss @@ -1,5 +1,10 @@ /* css for decidim_budgets_booth */ - +.layout-container .projects-content-index { + min-height: calc(100vh - 3.5rem); +} +.projects-content-index .layout-2col__main { + min-height: calc(100vh - 3.5rem); +} .budget__card__grid-project { display: flex; flex-direction: row; @@ -18,6 +23,9 @@ flex-direction: column; place-items: center; } +.card__list-metadata .text-success { + color: #07790d; +} .budget__card__grid-project__amount { margin-bottom: 0.5rem; display: inline-block; @@ -61,11 +69,11 @@ display:flex; flex-direction:column; } - #menu-bar-custom { justify-content: flex-start; padding-left: 2rem; color: white; + height: 3.5rem; } .menu-bar__exit-link { display:flex; diff --git a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb index 1981eda0..92e1890c 100644 --- a/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb +++ b/decidim-budgets_booth/app/views/layouts/decidim/budgets/_voting_wrapper.html.erb @@ -10,7 +10,7 @@ if respond_to?(:current_component) && current_component && can_be_managed?(curre end %> -
+
<%= display_flash_messages %> <%= yield %>
From e9aa7b6125365ccf157c124cfd9f57f87645dafa Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 1 Jul 2025 13:38:58 +0200 Subject: [PATCH 67/93] feat: change redirection when voting completed for a component with one budget --- .../lib/decidim/budgets_booth/voting_support.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb index ebeb9ebc..0d942885 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb @@ -36,7 +36,11 @@ def voted_all_budgets? # This configuration option can be set in component settings, the default url when the user has voted on all budgets # is budgets path def success_redirect_path - component_settings.try(:vote_success_url).presence || decidim_budgets.budgets_path + if budgets.count == 1 + decidim_participatory_processes.participatory_process_path(current_component.participatory_space) + else + component_settings.try(:vote_success_url).presence || decidim_budgets.budgets_path + end end # This configuration option can be set in component settings, the default url when the user cancels voting is the root path. From b3d9d0eb5601cd7da79e8ecd6c903e9e62dd96aa Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 1 Jul 2025 13:39:24 +0200 Subject: [PATCH 68/93] feat: update translation key --- decidim-budgets_booth/config/locales/fr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 9d9b1b8b..189e6a6a 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -64,7 +64,7 @@ fr: budgets: voting_menubar: back_to_projects: Retour aux projets - cancel_voting: Abandonner le vote + cancel_voting: Sortir de la cabine de vote voting_notification: notification: Vous êtes dans la cabine de vote. shared: From 02ea879a11cd0761c07ab011df5a509947a98361 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 1 Jul 2025 15:41:00 +0200 Subject: [PATCH 69/93] test: add test for checkout when only one budget --- .../orders_controller_extensions_spec.rb | 141 +++++++++++------- 1 file changed, 90 insertions(+), 51 deletions(-) diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb index 6ba41a27..54be8e34 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb @@ -9,76 +9,115 @@ routes { Decidim::Budgets::Engine.routes } - include_context "with scoped budgets" - let(:user) { create(:user, :confirmed, organization:) } let(:component) { create(:budgets_component, organization:) } let(:projects_count) { 5 } - let!(:budgets) { create_list(:budget, 3, component:, total_budget: 100_000_000) } - let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } - let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 75_000_000) } - let!(:order) { create(:order, user:, budget: budgets.first) } - - before do - request.env["decidim.current_organization"] = organization - request.env["decidim.current_user"] = user - request.env["decidim.current_participatory_space"] = component.participatory_space - request.env["decidim.current_component"] = component - order.projects << projects.first - order.save! - allow(controller).to receive_messages(budget: budgets.first, current_user: user) - end - describe "#checkout" do - context "when command call returns ok" do - before do - component.update!(settings: { workflow: "all" }) - end + describe "when there are multiple budgets" do + include_context "with scoped budgets" - it "sets thanks session and redirects the user" do - post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - expect(session[:booth_thanks_message]).to be(true) - expect(response).to redirect_to(decidim_budgets.budgets_path) + let!(:budgets) { create_list(:budget, 3, component:, total_budget: 100_000_000) } + let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } + let(:projects) { create_list(:project, 3, budget: budgets.first, budget_amount: 75_000_000) } + let!(:order) { create(:order, user:, budget: budgets.first) } + + before do + request.env["decidim.current_organization"] = organization + request.env["decidim.current_user"] = user + request.env["decidim.current_participatory_space"] = component.participatory_space + request.env["decidim.current_component"] = component + order.projects << projects.first + order.save! + allow(controller).to receive_messages(budget: budgets.first, current_user: user) + end + + describe "#checkout" do + context "when command call returns ok" do + before do + component.update!(settings: { workflow: "all" }) + end + + context "and there are several budgets" do + it "sets thanks session and redirects the user to budgets_path" do + post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + expect(session[:booth_thanks_message]).to be(true) + expect(response).to redirect_to(decidim_budgets.budgets_path) + end + + it "enqueues job" do + expect do + post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + end.to have_enqueued_job(Decidim::EventPublisherJob) + end + end end - it "enqueues job" do - expect do + context "when invalid" do + before do + # make order invalid + projects.first.update!(budget_amount: 25_000_000) + end + + it "redirects the user with flash message" do post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - end.to have_enqueued_job(Decidim::EventPublisherJob) + expect(response).to redirect_to(decidim_budgets.budgets_path) + expect(flash[:alert]).to have_content("There was a problem processing your vote") + end end end - context "when invalid" do - before do - # make order invalid - projects.first.update!(budget_amount: 25_000_000) + describe "#show" do + context "when order does not exist" do + it "renders error" do + expect do + get :show, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + end.to raise_error(ActionController::RoutingError) + end end - it "redirects the user with flash message" do - post :checkout, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - expect(response).to redirect_to(decidim_budgets.budgets_path) - expect(flash[:alert]).to have_content("There was a problem processing your vote") - end - end - end + context "when order exists" do + before do + order.update!(checked_out_at: Time.current) + end - describe "#show" do - context "when order does not exist" do - it "renders error" do - expect do + it "redirects the html requests" do get :show, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - end.to raise_error(ActionController::RoutingError) + expect(response).to redirect_to(decidim_budgets.budgets_path) + end end end + end - context "when order exists" do - before do - order.update!(checked_out_at: Time.current) - end + describe "when there is one budget" do + include_context "with single scoped budget" + + describe "#checkout" do + context "and there is one budget" do + let(:decidim_participatory_processes) { Decidim::EngineRouter.main_proxy(component.participatory_space) } + let!(:order) { create(:order, user:, budget: budget) } + + before do + request.env["decidim.current_organization"] = organization + request.env["decidim.current_user"] = user + request.env["decidim.current_participatory_space"] = component.participatory_space + request.env["decidim.current_component"] = component + projects_set.first.update!(budget_amount: 70_000) + order.projects << projects_set.first + order.save! + allow(controller).to receive_messages(budget: budget, current_user: user) + end + + it "sets thanks session and redirects the user to process_path" do + post :checkout, params: { budget_id: budget.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + expect(session[:booth_vote_completed]).to be(true) + expect(response).to redirect_to(decidim_participatory_processes.participatory_process_path(component.participatory_space)) + end - it "redirects the html requests" do - get :show, params: { budget_id: budgets.first.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - expect(response).to redirect_to(decidim_budgets.budgets_path) + it "enqueues job" do + expect do + post :checkout, params: { budget_id: budget.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + end.to have_enqueued_job(Decidim::EventPublisherJob) + end end end end From e5487507985663083fa8a53c87a2d82ba9f542e4 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 1 Jul 2025 15:45:56 +0200 Subject: [PATCH 70/93] style: update with rubocop --- .../budgets_booth/orders_controller_extensions_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb index 54be8e34..4985d670 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb @@ -94,7 +94,7 @@ describe "#checkout" do context "and there is one budget" do let(:decidim_participatory_processes) { Decidim::EngineRouter.main_proxy(component.participatory_space) } - let!(:order) { create(:order, user:, budget: budget) } + let!(:order) { create(:order, user:, budget:) } before do request.env["decidim.current_organization"] = organization @@ -104,7 +104,7 @@ projects_set.first.update!(budget_amount: 70_000) order.projects << projects_set.first order.save! - allow(controller).to receive_messages(budget: budget, current_user: user) + allow(controller).to receive_messages(budget:, current_user: user) end it "sets thanks session and redirects the user to process_path" do From 258e595ecbc0c7b323f4e016ede0f392e65a1b11 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 14:20:19 +0200 Subject: [PATCH 71/93] fix: update ruby version in budget booth gemspec --- decidim-budgets_booth/decidim-budgets_booth.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decidim-budgets_booth/decidim-budgets_booth.gemspec b/decidim-budgets_booth/decidim-budgets_booth.gemspec index 21d3577b..4ef330a7 100644 --- a/decidim-budgets_booth/decidim-budgets_booth.gemspec +++ b/decidim-budgets_booth/decidim-budgets_booth.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |s| s.email = ["sina.eftekhar@mainiotech.fi"] s.license = "AGPL-3.0" s.homepage = "https://github.com/mainio/decidim-module-ptp" - s.required_ruby_version = ">= 3.0" + s.required_ruby_version = ">= 3.2" s.name = "decidim-budgets_booth" s.summary = "A Decidim budgets module extension to implement a voting booth" From acc1da58fbd32d0ff937871e4aa0715512f620fe Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 14:20:56 +0200 Subject: [PATCH 72/93] ci: fix error on esbuild version --- .github/actions/module-rspec/action.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index e08e9895..159c32f5 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -36,6 +36,11 @@ runs: - run: bundle exec rake test_app name: Create test app shell: "bash" + - run: | + cd spec/decidim_dummy_app + npm install esbuild@0.25.5 --save-dev + name: Fix esbuild version for dummy app + shell: "bash" - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots name: Create the screenshots folder shell: "bash" From 0e300b3f02a2e1c335bcc20983ee3993199c71c1 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 14:32:58 +0200 Subject: [PATCH 73/93] ci: trying to fix esbuild version in test app --- .github/actions/module-rspec/action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index 159c32f5..eca0737a 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -38,7 +38,8 @@ runs: shell: "bash" - run: | cd spec/decidim_dummy_app - npm install esbuild@0.25.5 --save-dev + rm -rf node_modules/esbuild + npm install esbuild@0.25.5 --force name: Fix esbuild version for dummy app shell: "bash" - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots From 3dc005472e666bb60fddc1bdbbafbe49476713b6 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 15:20:45 +0200 Subject: [PATCH 74/93] ci: revert esbuild version --- .github/actions/module-rspec/action.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index eca0737a..e08e9895 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -36,12 +36,6 @@ runs: - run: bundle exec rake test_app name: Create test app shell: "bash" - - run: | - cd spec/decidim_dummy_app - rm -rf node_modules/esbuild - npm install esbuild@0.25.5 --force - name: Fix esbuild version for dummy app - shell: "bash" - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots name: Create the screenshots folder shell: "bash" From 7cb88bd907ade7bdc643ebdfb6467ae53cc76fa1 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 15:22:28 +0200 Subject: [PATCH 75/93] fix: add esbuild and esbuild-loader in package.json --- package-lock.json | 634 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 4 +- yarn.lock | 60 ++++- 3 files changed, 694 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8cc30641..614db44b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,9 @@ "packages": { "": { "dependencies": { - "@decidim/webpacker": "^0.27.2" + "@decidim/webpacker": "^0.27.2", + "esbuild": "^0.19.12", + "esbuild-loader": "^4.0.3" }, "devDependencies": { "@babel/eslint-parser": "^7.16.5", @@ -2101,6 +2103,351 @@ "node": ">=10.0.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -4029,6 +4376,69 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/esbuild-loader": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.3.tgz", + "integrity": "sha512-YpaSRisj7TSg6maKKKG9OJGGm0BZ7EXeov8J8cXEYdugjlAJ0wL7aj2JactoQvPJ113v2Ar204pdJWrZsAQc8Q==", + "dependencies": { + "esbuild": "^0.19.0", + "get-tsconfig": "^4.7.0", + "loader-utils": "^2.0.4", + "webpack-sources": "^1.4.3" + }, + "funding": { + "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" + }, + "peerDependencies": { + "webpack": "^4.40.0 || ^5.0.0" + } + }, + "node_modules/esbuild-loader/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -4992,6 +5402,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8326,6 +8747,14 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -11940,6 +12369,144 @@ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "optional": true + }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -13385,6 +13952,58 @@ "is-symbol": "^1.0.2" } }, + "esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "requires": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "esbuild-loader": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.3.tgz", + "integrity": "sha512-YpaSRisj7TSg6maKKKG9OJGGm0BZ7EXeov8J8cXEYdugjlAJ0wL7aj2JactoQvPJ113v2Ar204pdJWrZsAQc8Q==", + "requires": { + "esbuild": "^0.19.0", + "get-tsconfig": "^4.7.0", + "loader-utils": "^2.0.4", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -14100,6 +14719,14 @@ "get-intrinsic": "^1.1.1" } }, + "get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -16379,6 +17006,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==" + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", diff --git a/package.json b/package.json index e0e36fe6..8e75c18a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "stylelint": "stylelint decidim-*/app/packs/**/*.scss" }, "dependencies": { - "@decidim/webpacker": "^0.27.2" + "@decidim/webpacker": "^0.27.2", + "esbuild": "^0.19.12", + "esbuild-loader": "^4.0.3" }, "devDependencies": { "@babel/eslint-parser": "^7.16.5", diff --git a/yarn.lock b/yarn.lock index a716628d..5e978808 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1230,6 +1230,11 @@ resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" @@ -2555,6 +2560,45 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild-loader@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.3.tgz" + integrity sha512-YpaSRisj7TSg6maKKKG9OJGGm0BZ7EXeov8J8cXEYdugjlAJ0wL7aj2JactoQvPJ113v2Ar204pdJWrZsAQc8Q== + dependencies: + esbuild "^0.19.0" + get-tsconfig "^4.7.0" + loader-utils "^2.0.4" + webpack-sources "^1.4.3" + +esbuild@^0.19.0, esbuild@^0.19.12: + version "0.19.12" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz" + integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.12" + "@esbuild/android-arm" "0.19.12" + "@esbuild/android-arm64" "0.19.12" + "@esbuild/android-x64" "0.19.12" + "@esbuild/darwin-arm64" "0.19.12" + "@esbuild/darwin-x64" "0.19.12" + "@esbuild/freebsd-arm64" "0.19.12" + "@esbuild/freebsd-x64" "0.19.12" + "@esbuild/linux-arm" "0.19.12" + "@esbuild/linux-arm64" "0.19.12" + "@esbuild/linux-ia32" "0.19.12" + "@esbuild/linux-loong64" "0.19.12" + "@esbuild/linux-mips64el" "0.19.12" + "@esbuild/linux-ppc64" "0.19.12" + "@esbuild/linux-riscv64" "0.19.12" + "@esbuild/linux-s390x" "0.19.12" + "@esbuild/linux-x64" "0.19.12" + "@esbuild/netbsd-x64" "0.19.12" + "@esbuild/openbsd-x64" "0.19.12" + "@esbuild/sunos-x64" "0.19.12" + "@esbuild/win32-arm64" "0.19.12" + "@esbuild/win32-ia32" "0.19.12" + "@esbuild/win32-x64" "0.19.12" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -3015,6 +3059,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.7.0: + version "4.10.1" + resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz" + integrity sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ== + dependencies: + resolve-pkg-maps "^1.0.0" + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -3733,7 +3784,7 @@ loader-utils@^1.1.0: emojis-list "^3.0.0" json5 "^1.0.1" -loader-utils@^2.0.0: +loader-utils@^2.0.0, loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -4852,6 +4903,11 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.9.0: version "1.22.2" resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" @@ -5752,7 +5808,7 @@ webpack-sources@^3.2.0, webpack-sources@^3.2.1, webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -"webpack@^4.4.0 || ^5.9.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.2.0, webpack@^5.51.1, webpack@^5.53.0, webpack@>=2, "webpack@4.x.x || 5.x.x": +"webpack@^4.4.0 || ^5.9.0", "webpack@^4.40.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.2.0, webpack@^5.51.1, webpack@^5.53.0, webpack@>=2, "webpack@4.x.x || 5.x.x": version "5.85.0" resolved "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz" integrity sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg== From 07b7f445c553e13b388012a77978beb24d85f196 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 15:45:21 +0200 Subject: [PATCH 76/93] Trigger CI From 7c736e80b271342eb5f23eec561b0e170e875412 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 3 Jul 2025 16:04:30 +0200 Subject: [PATCH 77/93] ci: update node version --- .github/actions/module-rspec/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml index e08e9895..ca8946fa 100644 --- a/.github/actions/module-rspec/action.yml +++ b/.github/actions/module-rspec/action.yml @@ -21,7 +21,7 @@ runs: shell: "bash" - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18.17.1 - name: Get npm cache directory path id: npm-cache-dir-path run: echo "dir=$(npm get cache)-${{ inputs.name }}" >> $GITHUB_OUTPUT From 9e9af8af97ff051ed0fc693e0707b89b119ba40d Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 4 Jul 2025 10:42:27 +0200 Subject: [PATCH 78/93] fix: update success_redirect_paht method --- .../lib/decidim/budgets_booth/voting_support.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb index 0d942885..c58ffe4e 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/voting_support.rb @@ -36,7 +36,7 @@ def voted_all_budgets? # This configuration option can be set in component settings, the default url when the user has voted on all budgets # is budgets path def success_redirect_path - if budgets.count == 1 + if budgets.count == 1 && component_settings.try(:vote_success_url).blank? decidim_participatory_processes.participatory_process_path(current_component.participatory_space) else component_settings.try(:vote_success_url).presence || decidim_budgets.budgets_path From df80de66e530aeb0e4a5dd1033010e4599e0118e Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 4 Jul 2025 10:43:11 +0200 Subject: [PATCH 79/93] test: update orders system test --- decidim-budgets_booth/spec/system/orders_spec.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/decidim-budgets_booth/spec/system/orders_spec.rb b/decidim-budgets_booth/spec/system/orders_spec.rb index b496c264..4d5bd680 100644 --- a/decidim-budgets_booth/spec/system/orders_spec.rb +++ b/decidim-budgets_booth/spec/system/orders_spec.rb @@ -378,10 +378,11 @@ within "#budget-confirm" do page.find(".button", text: "Confirm").click end - - within "#order-progress .budget-summary__content", match: :first do - expect(page).to have_css(".button", text: "delete your vote") - end + # there is only one budget, so we are redirected to process show page (cf success_redirect_path method) + expect(page).to have_css("a", text: translated_attribute(participatory_process.title).to_s) + #within "#order-progress .budget-summary__content", match: :first do + # expect(page).to have_css(".button", text: "delete your vote") + #end end end From d6aee2da0577cb882235be0cbdb42fe5b9e673fe Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 4 Jul 2025 10:56:06 +0200 Subject: [PATCH 80/93] test: update orders controller test --- .../orders_controller_extensions_spec.rb | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb index 4985d670..e0715eb7 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/orders_controller_extensions_spec.rb @@ -107,17 +107,28 @@ allow(controller).to receive_messages(budget:, current_user: user) end - it "sets thanks session and redirects the user to process_path" do - post :checkout, params: { budget_id: budget.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } - expect(session[:booth_vote_completed]).to be(true) - expect(response).to redirect_to(decidim_participatory_processes.participatory_process_path(component.participatory_space)) - end - it "enqueues job" do expect do post :checkout, params: { budget_id: budget.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } end.to have_enqueued_job(Decidim::EventPublisherJob) end + + context "and vote_success_url is not defined" do + it "sets thanks session and redirects the user to process_path" do + post :checkout, params: { budget_id: budget.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + expect(session[:booth_vote_completed]).to be(true) + expect(response).to redirect_to(decidim_participatory_processes.participatory_process_path(component.participatory_space)) + end + end + + context "and vote_success_url is defined" do + it "sets thanks session and redirects the user to vote_success_url" do + component.update!(settings: { vote_success_url: "/processes" }) + post :checkout, params: { budget_id: budget.id, component_id: component.id, participatory_process_slug: component.participatory_space.slug } + expect(session[:booth_vote_completed]).to be(true) + expect(response).to redirect_to(decidim_participatory_processes.participatory_processes_path) + end + end end end end From 2f81fbcc2bbe7321bfa434965453f191dc0180f3 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 9 Jul 2025 16:31:36 +0200 Subject: [PATCH 81/93] fix: vote btn on project not shown if vote is finished --- .../cells/decidim/budgets/project_vote_button/show.erb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb index e412227e..4ef082e9 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb @@ -1,5 +1,6 @@ -<% button_type = resource_added? ? "button__transparent-secondary" : "button__secondary" %> -<%= action_authorized_button_to( +<% unless voting_finished? %> + <% button_type = resource_added? ? "button__transparent-secondary" : "button__secondary" %> + <%= action_authorized_button_to( "vote", budget_order_line_item_path(model.budget, project_id: model, show_only_added: options[:show_only_added], view_mode: options[:view_mode]), method: vote_button_method, @@ -15,6 +16,7 @@ }, disabled: vote_button_disabled?, title: vote_button_label - ) do %> + ) do %> <%= resource_added? ? t("remove_from_vote", scope: "decidim.budgets.project_vote_button") :t("add_to_vote", scope: "decidim.budgets.project_vote_button") %> + <% end %> <% end %> From c9894927262d0022b7dcd42ccff4adc03505ec9e Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 9 Jul 2025 16:32:29 +0200 Subject: [PATCH 82/93] fix: add metadata on project grid card --- .../app/cells/decidim/budgets/project_g/show.erb | 2 +- .../app/cells/decidim/budgets/project_g_cell.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb index fd54e2f2..d7032b12 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g/show.erb @@ -14,7 +14,7 @@ <% if metadata_cell.present? %>
- <%#= cell metadata_cell, resource, links: false, skip_state: true, **options %> + <%= cell metadata_cell, resource, links: false, skip_state: true, **options %> <%= cell("decidim/budgets/project_voted_hint", project, class: "margin-left-1") if current_order_checked_out? && resource_added? %>
<% end %> diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb index fb3e235a..5edbdfb0 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_g_cell.rb @@ -56,7 +56,7 @@ def view_mode end def classes - super.merge(metadata: "card__list-metadata") + super.merge(metadata: "card__grid-metadata") end def resource_id = "project-#{project.id}-item" From e62f1eb154ab372e2374a8bc397d5850a3673f39 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 9 Jul 2025 16:33:05 +0200 Subject: [PATCH 83/93] test: update order system test --- decidim-budgets_booth/spec/system/orders_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decidim-budgets_booth/spec/system/orders_spec.rb b/decidim-budgets_booth/spec/system/orders_spec.rb index 4d5bd680..39a5b938 100644 --- a/decidim-budgets_booth/spec/system/orders_spec.rb +++ b/decidim-budgets_booth/spec/system/orders_spec.rb @@ -706,7 +706,7 @@ it "renders selected projects" do visit_budget - expect(page).to have_css(".card__list-metadata", count: 2) + expect(page).to have_css(".card__grid-metadata", count: 2) end it "does not show a filter to select added projects" do From c089979c5ed5561e4973806ccd678f2e70491957 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 9 Jul 2025 16:54:53 +0200 Subject: [PATCH 84/93] test: add test for no voting btn when vote is finished --- .../spec/system/explore_projects_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/decidim-budgets_booth/spec/system/explore_projects_spec.rb b/decidim-budgets_booth/spec/system/explore_projects_spec.rb index 9a258b17..9d11df54 100644 --- a/decidim-budgets_booth/spec/system/explore_projects_spec.rb +++ b/decidim-budgets_booth/spec/system/explore_projects_spec.rb @@ -161,6 +161,23 @@ end end + context "when votes are finished" do + let!(:component) do + create(:budgets_component, + :with_voting_finished, + manifest:, + participatory_space: participatory_process) + end + + it "does not show the vote button in projects cards" do + visit_budget + + within "#projects" do + expect(page).not_to have_css(".project__vote-button") + end + end + end + context "when directly accessing from URL with an invalid budget id" do it_behaves_like "a 404 page" do let(:target_path) { decidim_budgets.budget_projects_path(99_999_999) } From b8e030c23645fe59fb6629ddac1eb3d2f1c496ec Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 10 Oct 2025 12:04:07 +0200 Subject: [PATCH 85/93] feat: remove vote button if vote is disabled and display specific text --- .../app/cells/decidim/budgets/project_vote_button/show.erb | 2 +- .../decidim/budgets/projects/_order_progress_text.html.erb | 6 +++++- decidim-budgets_booth/config/locales/en.yml | 2 ++ decidim-budgets_booth/config/locales/fr.yml | 2 ++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb index 4ef082e9..3a2adf09 100644 --- a/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb +++ b/decidim-budgets_booth/app/cells/decidim/budgets/project_vote_button/show.erb @@ -1,4 +1,4 @@ -<% unless voting_finished? %> +<% unless voting_finished? || current_settings.votes == "disabled" %> <% button_type = resource_added? ? "button__transparent-secondary" : "button__secondary" %> <%= action_authorized_button_to( "vote", diff --git a/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb b/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb index 491f2e07..eaa7cd1f 100644 --- a/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb +++ b/decidim-budgets_booth/app/views/decidim/budgets/projects/_order_progress_text.html.erb @@ -12,6 +12,10 @@
<% else %>

- <%= current_rule_description %> + <% if current_settings.votes == "disabled" %> + <%= t('.vote_disabled') %> + <% else %> + <%= current_rule_description %> + <% end %>

<% end %> diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 74296a0e..4a1558b5 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -23,6 +23,8 @@ en: ready: I am ready total_budget: 'Total budget: ' vote: Vote + order_progress_text: + vote_disabled: Vote disabled. order_selected_projects: remove: Remove selected_projects: diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index 189e6a6a..fe92b7c0 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -23,6 +23,8 @@ fr: ready: Je suis prêt total_budget: 'Budget total: ' vote: Voter + order_progress_text: + vote_disabled: Vote désactivé. order_selected_projects: remove: Supprimer selected_projects: From 60aeb6cc885620e4940caf34f8276cfb9dffb475 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 10 Oct 2025 12:04:54 +0200 Subject: [PATCH 86/93] test: update projects tests --- .../spec/system/explore_projects_spec.rb | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/decidim-budgets_booth/spec/system/explore_projects_spec.rb b/decidim-budgets_booth/spec/system/explore_projects_spec.rb index 9d11df54..71fd162f 100644 --- a/decidim-budgets_booth/spec/system/explore_projects_spec.rb +++ b/decidim-budgets_booth/spec/system/explore_projects_spec.rb @@ -178,6 +178,31 @@ end end + context "when votes are disabled" do + let!(:component) do + create(:budgets_component, + :with_votes_disabled, + manifest:, + participatory_space: participatory_process) + end + + it "does not show the vote button in projects cards" do + visit_budget + + within "#projects" do + expect(page).not_to have_css(".project__vote-button") + end + end + + it "gives information on disabled votes" do + visit_budget + + within ".layout-2col__aside" do + expect(page).to have_text("Vote disabled.") + end + end + end + context "when directly accessing from URL with an invalid budget id" do it_behaves_like "a 404 page" do let(:target_path) { decidim_budgets.budget_projects_path(99_999_999) } From 4a797f61339c55f3145f1533c7e88de66ab584af Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Mon, 13 Oct 2025 17:45:09 +0200 Subject: [PATCH 87/93] fix: add missing icon --- decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb index 43d140c8..afc9ccfd 100644 --- a/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb +++ b/decidim-budgets_booth/lib/decidim/budgets_booth/engine.rb @@ -31,6 +31,10 @@ class Engine < ::Rails::Engine Cell::ViewModel.view_paths << File.expand_path("#{Decidim::BudgetsBooth::Engine.root}/app/views") # for partials end + initializer "decidim_budgets_booth.register_icon" do + Decidim.icons.register(name: "envelope-closed", icon: "envelope-closed", category: "system", description: "", engine: :core) + end + initializer "decidim_budgets_booth.add_customizations", after: "decidim.action_controller" do config.to_prepare do # Helper extensions From d1c784c8e5049b0b0424afb3103e7b6baa273233 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 14 Oct 2025 10:12:32 +0200 Subject: [PATCH 88/93] fix: add missing locales --- decidim-budgets_booth/config/locales/en.yml | 2 ++ decidim-budgets_booth/config/locales/fr.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/decidim-budgets_booth/config/locales/en.yml b/decidim-budgets_booth/config/locales/en.yml index 4a1558b5..81a08018 100644 --- a/decidim-budgets_booth/config/locales/en.yml +++ b/decidim-budgets_booth/config/locales/en.yml @@ -34,6 +34,8 @@ en: show: budget: Budget voting: + index: + sign_in_first: You must connect before continue thanks_message_modal: continue: Continue default_text: Thank you for your participation diff --git a/decidim-budgets_booth/config/locales/fr.yml b/decidim-budgets_booth/config/locales/fr.yml index fe92b7c0..ef3d8acb 100644 --- a/decidim-budgets_booth/config/locales/fr.yml +++ b/decidim-budgets_booth/config/locales/fr.yml @@ -34,6 +34,8 @@ fr: show: budget: Budget voting: + index: + sign_in_first: Vous devez vous connecter avant de continuer thanks_message_modal: continue: Continuer default_text: Merci pour votre participation From 1b24c389d3d2107db1738c580c28ec535ec97492 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 14 Oct 2025 10:13:05 +0200 Subject: [PATCH 89/93] test: try fixing order system test --- decidim-budgets_booth/spec/system/orders_spec.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/decidim-budgets_booth/spec/system/orders_spec.rb b/decidim-budgets_booth/spec/system/orders_spec.rb index 39a5b938..2db6440b 100644 --- a/decidim-budgets_booth/spec/system/orders_spec.rb +++ b/decidim-budgets_booth/spec/system/orders_spec.rb @@ -375,7 +375,7 @@ expect(page).to have_css("#budget-confirm", visible: :visible) - within "#budget-confirm" do + within "#budget-confirm-content" do page.find(".button", text: "Confirm").click end # there is only one budget, so we are redirected to process show page (cf success_redirect_path method) @@ -428,10 +428,13 @@ before do find("[data-dialog-open='budget-confirm']", match: :first).click - click_on "Confirm" + within "#budget-confirm-content" do + page.find(".button", text: "Confirm").click + end end it "shows private-only activity log entry" do + sleep 1 page.visit decidim.profile_activity_path(nickname: user.nickname) expect(page).to have_content("New budgeting vote at #{translated(budget.title)}") expect(page).to have_link(translated(budget.title), href: router.budget_path(budget)) From ad0a214ea0c3d74f29fd4e7813e02017bd7cffc1 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Tue, 14 Oct 2025 10:25:51 +0200 Subject: [PATCH 90/93] fix: update unused keys to ignore --- decidim-budgets_booth/config/i18n-tasks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/decidim-budgets_booth/config/i18n-tasks.yml b/decidim-budgets_booth/config/i18n-tasks.yml index 2a1f9576..a7d93864 100644 --- a/decidim-budgets_booth/config/i18n-tasks.yml +++ b/decidim-budgets_booth/config/i18n-tasks.yml @@ -13,6 +13,7 @@ ignore_unused: - "decidim.components.budgets.settings.global.maximum_budgets_to_vote_on" - "decidim.budgets.budgets_list.voted_on_all_allowed" - "decidim.budgets.projects.index.projects_for" + - "decidim.budgets.voting.index.sign_in_first" ignore_missing: - decidim.participatory_processes.scopes.global From d8ed874484fea98870b02e88b2479f2caf5818bf Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Fri, 16 Jan 2026 13:39:18 +0100 Subject: [PATCH 91/93] fix: update add_javascript_file method to use asset_pack_path in prod --- .../concerns/decidim/budgets_booth/complete_voting_popup.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb index 211d0fb0..a0f276c7 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/complete_voting_popup.rb @@ -30,13 +30,13 @@ def completed_vote_snippets end def add_javascript_file - if Rails.env.test? + if Rails.env.dev? <<~HTML - + HTML else <<~HTML - + HTML end end From 81a5a69e384c1ac1e965a738f5851ad24224b0df Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 5 Mar 2026 12:14:44 +0100 Subject: [PATCH 92/93] fix: budgets index action --- .../decidim/budgets_booth/budgets_controller_extensions.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb index d5a99620..e4385ef1 100644 --- a/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb +++ b/decidim-budgets_booth/app/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions.rb @@ -9,6 +9,11 @@ module BudgetsControllerExtensions included do layout :determine_layout + def index + # if there is an announcement_body, render index + redirect_to budget_projects_path(current_workflow.single) if current_workflow.single? && announcement_body.nil? + end + private def determine_layout From ce8a886f7186d971e0cf44a5195395d5542ab59d Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Thu, 5 Mar 2026 12:15:04 +0100 Subject: [PATCH 93/93] test: update tests --- .../budgets_controller_extensions_spec.rb | 60 +++++++++++++------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb index c3e05799..35b92bab 100644 --- a/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb +++ b/decidim-budgets_booth/spec/controllers/concerns/decidim/budgets_booth/budgets_controller_extensions_spec.rb @@ -16,13 +16,6 @@ module BudgetsBooth let(:component) { create(:budgets_component, organization:, settings: component_settings) } let(:decidim_budgets) { Decidim::EngineRouter.main_proxy(component) } let(:component_settings) { { votes: "enabled" } } - let!(:budgets) do - [].tap do |list| - list << create(:budget, component:) - list << create(:budget, component:) - list << create(:budget, component:) - end - end before do request.env["decidim.current_organization"] = organization @@ -30,21 +23,54 @@ module BudgetsBooth request.env["decidim.current_component"] = component end - context "when voting enabled" do - it "renders index with budgets_booth application layout" do - get :index - expect(response).to render_template(:index, layout: "layouts/decidim/application") + context "when there is one budget and voting is enabled " do + let(:budget) { create(:budget, component:)} + let!(:projects) { create_list(:project, 2, budget:)} + + context "when voting enabled and budget component has annoucement" do + let(:component_settings) { { votes: "enabled", announcement: { en: "annoucement" } } } + + it "renders index with budgets_booth application layout" do + get :index + expect(response).to render_template(:index, layout: "decidim/budgets/application") + end + end + + context "when voting enabled and budget component has no annoucement" do + let(:component_settings) { { votes: "enabled" } } + + it "redirects to projects index" do + get :index + expect(response).to redirect_to(budget_projects_path(budget)) + end end end - context "when voting is not enabled" do - before do - component.update(settings: component_settings.merge(votes: "finished")) + context "when there are multiple budgets" do + let!(:budgets) do + [].tap do |list| + list << create(:budget, component:) + list << create(:budget, component:) + list << create(:budget, component:) + end end - it "renders index with budgets_booth voting_layout" do - get :index - expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") + context "when voting enabled" do + it "renders index with budgets_booth application layout" do + get :index + expect(response).to render_template(:index, layout: "layouts/decidim/application") + end + end + + context "when voting is not enabled" do + before do + component.update(settings: component_settings.merge(votes: "finished")) + end + + it "renders index with budgets_booth voting_layout" do + get :index + expect(response).to render_template(:index, layout: "decidim/budgets/voting_layout") + end end end end