diff --git a/app/adapters/signal_adapter/inbound.rb b/app/adapters/signal_adapter/inbound.rb
index f6128b293..a32d32a23 100644
--- a/app/adapters/signal_adapter/inbound.rb
+++ b/app/adapters/signal_adapter/inbound.rb
@@ -12,7 +12,7 @@ class Inbound
UNKNOWN_CONTENT_KEYS = %w[mentions contacts sticker].freeze
SUPPORTED_ATTACHMENT_TYPES = %w[image/jpg image/jpeg image/png image/gif audio/oog audio/aac audio/mp4 audio/mpeg video/mp4].freeze
- attr_reader :sender, :text, :message
+ attr_reader :sender, :message
def initialize
@callbacks = {}
@@ -25,12 +25,16 @@ def on(callback, &block)
def consume(signal_message)
signal_message = signal_message.with_indifferent_access
- @sender = initialize_sender(signal_message)
- return unless @sender
+ @sender = initialize_contributing_sender(signal_message)
delivery_receipt = initialize_delivery_receipt(signal_message)
return if delivery_receipt
+ unless @sender
+ initialize_onboarding_sender(signal_message)
+ return
+ end
+
remove_emoji = signal_message.dig(:envelope, :dataMessage, :reaction, :isRemove)
return if remove_emoji
@@ -53,31 +57,41 @@ def trigger(event, *args)
@callbacks[event].call(*args)
end
- def initialize_sender(signal_message)
- signal_phone_number = signal_message.dig(:envelope, :source)
- sender = Contributor.find_by(signal_phone_number: signal_phone_number)
-
- unless sender
- trigger(UNKNOWN_CONTRIBUTOR, signal_phone_number)
- return nil
- end
-
- if sender.signal_onboarding_completed_at.blank?
- trigger(CONNECT, sender)
- return nil
+ def initialize_contributing_sender(signal_message)
+ signal_phone_number = signal_message.dig(:envelope, :sourceNumber)
+ signal_uuid = signal_message.dig(:envelope, :sourceUuid)
+ if signal_phone_number
+ Contributor.find_by(signal_phone_number: signal_phone_number)
+ else
+ Contributor.find_by(signal_uuid: signal_uuid)
end
-
- sender
end
def initialize_delivery_receipt(signal_message)
+ return nil unless delivery_receipt?(signal_message) && sender
+
delivery_receipt = signal_message.dig(:envelope, :receiptMessage)
- return nil unless delivery_receipt
trigger(HANDLE_DELIVERY_RECEIPT, delivery_receipt, sender)
delivery_receipt
end
+ def initialize_onboarding_sender(signal_message)
+ signal_uuid = signal_message.dig(:envelope, :sourceUuid)
+ signal_onboarding_token = signal_message.dig(:envelope, :dataMessage, :message)
+ return nil unless signal_onboarding_token
+
+ sender = Contributor.find_by(signal_onboarding_token: signal_onboarding_token.strip)
+
+ unless sender
+ trigger(UNKNOWN_CONTRIBUTOR, signal_message.dig(:envelope, :source))
+ return nil
+ end
+ return unless signal_uuid
+
+ trigger(CONNECT, sender, signal_uuid)
+ end
+
def initialize_message(signal_message)
is_data_message = signal_message.dig(:envelope, :dataMessage)
return nil unless is_data_message
@@ -148,5 +162,9 @@ def create_message?
text = message.text
has_non_text_content || (text.present? && !unsubscribe_text?(text) && !resubscribe_text?(text))
end
+
+ def delivery_receipt?(signal_message)
+ signal_message.dig(:envelope, :receiptMessage)
+ end
end
end
diff --git a/app/adapters/signal_adapter/outbound.rb b/app/adapters/signal_adapter/outbound.rb
index 7d8fc5a7a..36004ab5f 100644
--- a/app/adapters/signal_adapter/outbound.rb
+++ b/app/adapters/signal_adapter/outbound.rb
@@ -42,7 +42,7 @@ def send_resubscribe_error_message!(contributor)
end
def contributor_can_receive_messages?(recipient)
- recipient&.signal_phone_number.present? && recipient.signal_onboarding_completed_at.present?
+ (recipient&.signal_phone_number.present? || recipient&.signal_uuid.present?) && recipient&.signal_onboarding_completed_at.present?
end
end
end
diff --git a/app/adapters/signal_adapter/outbound/file.rb b/app/adapters/signal_adapter/outbound/file.rb
index 1313719ea..3169c100d 100644
--- a/app/adapters/signal_adapter/outbound/file.rb
+++ b/app/adapters/signal_adapter/outbound/file.rb
@@ -28,7 +28,7 @@ def data
end
{
number: Setting.signal_server_phone_number,
- recipients: [message.recipient.signal_phone_number],
+ recipients: [message.recipient.signal_attr],
message: message.text,
base64_attachments: base64_files
}
diff --git a/app/adapters/signal_adapter/outbound/text.rb b/app/adapters/signal_adapter/outbound/text.rb
index 97e222e98..c9902b8a3 100644
--- a/app/adapters/signal_adapter/outbound/text.rb
+++ b/app/adapters/signal_adapter/outbound/text.rb
@@ -28,7 +28,7 @@ def perform(contributor_id:, text:)
def data
{
number: Setting.signal_server_phone_number,
- recipients: [recipient.signal_phone_number],
+ recipients: [recipient.signal_attr],
message: text
}
end
diff --git a/app/adapters/signal_adapter/unknown_contributor_error.rb b/app/adapters/signal_adapter/unknown_contributor_error.rb
index 0ff21246f..4da9a638d 100644
--- a/app/adapters/signal_adapter/unknown_contributor_error.rb
+++ b/app/adapters/signal_adapter/unknown_contributor_error.rb
@@ -2,8 +2,8 @@
module SignalAdapter
class UnknownContributorError < StandardError
- def initialize(signal_phone_number:)
- super("Received a message on signal from an unknown sender: #{signal_phone_number}")
+ def initialize(signal_attr:)
+ super("Received a message on signal from an unknown sender: #{signal_attr}")
end
end
end
diff --git a/app/components/contributor_signal_settings/contributor_signal_settings.html.erb b/app/components/contributor_signal_settings/contributor_signal_settings.html.erb
index 3cbf152ef..50508c2b5 100644
--- a/app/components/contributor_signal_settings/contributor_signal_settings.html.erb
+++ b/app/components/contributor_signal_settings/contributor_signal_settings.html.erb
@@ -4,27 +4,15 @@
<% end %>
<% if contributor.signal_onboarding_completed_at.present? %>
-
- <%= t('.complete.text',
- name: contributor.name,
- phone_number: contributor.signal_phone_number.phony_formatted
- ) %>
-
+ <%= completed_onboarding_text %>
<% else %>
<%= c 'callout', style: :warning do %>
<%= c 'stack', space: :small do %>
-
- <%= t('.incomplete.text',
- name: contributor.name,
- first_name: contributor.first_name,
- date: l(contributor.created_at.to_date),
- phone_number: contributor.signal_phone_number.phony_formatted,
- ) %>
-
+ <%= incomplete_onboarding_text %>
<%= c 'copy_button',
style: :secondary,
- copy: onboarding_signal_link_url,
+ copy: onboarding_signal_link_url(signal_onboarding_token: contributor.signal_onboarding_token),
label: t('.incomplete.action')
%>
<% end %>
diff --git a/app/components/contributor_signal_settings/contributor_signal_settings.rb b/app/components/contributor_signal_settings/contributor_signal_settings.rb
index caa06f93b..b72f73bbc 100644
--- a/app/components/contributor_signal_settings/contributor_signal_settings.rb
+++ b/app/components/contributor_signal_settings/contributor_signal_settings.rb
@@ -11,5 +11,25 @@ def initialize(contributor:, **)
private
attr_reader :contributor
+
+ def completed_onboarding_text
+ if contributor.signal_phone_number.present?
+ t('.complete.text.phone_number',
+ name: contributor.name,
+ phone_number: contributor.signal_phone_number.phony_formatted)
+ else
+
+ t('.complete.text.uuid',
+ name: contributor.name,
+ uuid: contributor.signal_uuid)
+ end
+ end
+
+ def incomplete_onboarding_text
+ t('.incomplete.text',
+ name: contributor.name,
+ first_name: contributor.first_name,
+ date: l(contributor.created_at.to_date))
+ end
end
end
diff --git a/app/components/onboarding_signal_form/onboarding_signal_form.html.erb b/app/components/onboarding_signal_form/onboarding_signal_form.html.erb
index 2c93a0dc3..e53c96e50 100644
--- a/app/components/onboarding_signal_form/onboarding_signal_form.html.erb
+++ b/app/components/onboarding_signal_form/onboarding_signal_form.html.erb
@@ -18,9 +18,11 @@
<%= c 'input', field.input_defaults.merge(required: true) %>
<% end %>
- <%= c 'field', object: contributor, attr: :signal_phone_number do |field| %>
- <%= c 'input', field.input_defaults.merge(placeholder: '', required: true, type: :tel) %>
- <% end %>
+ <%= c 'input',
+ id: 'contributor[signal_onboarding_token]',
+ type: 'hidden',
+ value: contributor.signal_onboarding_token
+ %>
<%= c 'onboarding_consent', contributor: contributor %>
diff --git a/app/components/onboarding_signal_link/onboarding_signal_link.html.erb b/app/components/onboarding_signal_link/onboarding_signal_link.html.erb
index 175074bda..cce61a32c 100644
--- a/app/components/onboarding_signal_link/onboarding_signal_link.html.erb
+++ b/app/components/onboarding_signal_link/onboarding_signal_link.html.erb
@@ -1,39 +1,14 @@
<%= c 'stack', **attrs do %>
-
<%= c 'stack', class: 'text-serif text-center', space: :xsmall do %>
<%= c 'heading', tag: :h1 do %>
- <%= t('components.onboarding_signal_link.heading') %>
+ <%= t 'components.onboarding_signal_link.heading' %>
<% end %>
-
- <%= t('components.onboarding_signal_link.text').html_safe %>
-
-
-
- <%= t('components.onboarding_signal_link.action',
- number: Setting.signal_server_phone_number.phony_formatted(spaces: ' ')
- ).html_safe %>
-
- <% end %>
-
- <%= c 'stack', space: :small do %>
- <%= c 'button',
- styles: [:block, :primary],
- link: "https://signal.me/#p/#{Setting.signal_server_phone_number}",
- label: t('components.onboarding_signal_link.link'),
- target: '_blank',
- rel: 'noopener noreferrer'
- %>
-
- <%= c 'copy_button',
- styles: [:block, :secondary],
- label: t('components.onboarding_signal_link.copy'),
- copy: Setting.signal_server_phone_number
- %>
-
-
- <%= t('components.onboarding_signal_link.help') %>
-
+ <%= t 'components.onboarding_signal_link.text' %>
<% end %>
+ <%= c 'steps_list',
+ class: 'text-serif',
+ steps: fallback_steps.map(&:html_safe)
+ %>
<% end %>
diff --git a/app/components/onboarding_signal_link/onboarding_signal_link.rb b/app/components/onboarding_signal_link/onboarding_signal_link.rb
index 66fc795d0..4c00f317c 100644
--- a/app/components/onboarding_signal_link/onboarding_signal_link.rb
+++ b/app/components/onboarding_signal_link/onboarding_signal_link.rb
@@ -1,5 +1,20 @@
# frozen_string_literal: true
module OnboardingSignalLink
- class OnboardingSignalLink < ApplicationComponent; end
+ class OnboardingSignalLink < ApplicationComponent
+ def initialize(signal_onboarding_token:, **)
+ super
+
+ @signal_onboarding_token = signal_onboarding_token
+ end
+
+ private
+
+ attr_reader :signal_onboarding_token
+
+ def fallback_steps
+ data = { signal_server_phone_number: Setting.signal_server_phone_number, token: signal_onboarding_token }
+ I18n.t('components.onboarding_signal_link.steps', **data)
+ end
+ end
end
diff --git a/app/controllers/onboarding/signal_controller.rb b/app/controllers/onboarding/signal_controller.rb
index bb7d82f1a..df8cca3fc 100644
--- a/app/controllers/onboarding/signal_controller.rb
+++ b/app/controllers/onboarding/signal_controller.rb
@@ -4,20 +4,28 @@ module Onboarding
class SignalController < OnboardingController
skip_before_action :verify_jwt, only: :link
- def link; end
+ def show
+ super
+ @contributor.signal_onboarding_token = SecureRandom.alphanumeric(8).upcase
+ end
+
+ def link
+ @signal_onboarding_token = signal_onboarding_token
+ end
private
- def attr_name
- :signal_phone_number
+ def redirect_to_success
+ signal_onboarding_token = @contributor.signal_onboarding_token
+ redirect_to onboarding_signal_link_path(signal_onboarding_token: signal_onboarding_token, jwt: nil)
end
- def redirect_to_success
- redirect_to onboarding_signal_link_path(jwt: nil)
+ def attr_name
+ :signal_onboarding_token
end
- def complete_onboarding(contributor)
- SignalAdapter::CreateContactJob.perform_later(contributor)
+ def signal_onboarding_token
+ params.require(:signal_onboarding_token)
end
end
end
diff --git a/app/controllers/onboarding_controller.rb b/app/controllers/onboarding_controller.rb
index 942ef6e6f..b038f2810 100644
--- a/app/controllers/onboarding_controller.rb
+++ b/app/controllers/onboarding_controller.rb
@@ -4,6 +4,7 @@ class OnboardingController < ApplicationController
skip_before_action :require_login
before_action :verify_jwt, except: :success
before_action :resume_telegram_onboarding, only: %i[index show]
+ before_action :resume_signal_onboarding, only: %i[index show]
before_action :redirect_if_contributor_exists, only: :create
rescue_from ActionController::BadRequest, with: :render_unauthorized
@@ -28,7 +29,6 @@ def create
@contributor.tag_list = tag_list_from_jwt
if @contributor.save
- complete_onboarding(@contributor)
@contributor.send_welcome_message!
redirect_to_success
else
@@ -84,11 +84,9 @@ def render_unauthorized
def verify_jwt
return unless jwt
- raise ActionController::BadRequest unless resume_telegram_onboarding?
+ raise ActionController::BadRequest unless resume_telegram_onboarding? || resume_signal_onboarding?
end
- def complete_onboarding(contributor); end
-
def resume_telegram_onboarding
return unless resume_telegram_onboarding?
@@ -101,6 +99,18 @@ def resume_telegram_onboarding?
contributor&.telegram_id.blank? && contributor&.telegram_onboarding_token.present?
end
+ def resume_signal_onboarding
+ return unless resume_signal_onboarding?
+
+ token = jwt.contributor.signal_onboarding_token
+ redirect_to onboarding_signal_link_path(signal_onboarding_token: token)
+ end
+
+ def resume_signal_onboarding?
+ contributor = jwt&.contributor
+ contributor&.signal_uuid.blank? && contributor&.signal_onboarding_token.present?
+ end
+
def jwt
decoded_token = JsonWebToken.decode(jwt_param)
action = decoded_token.first['data']['action']
diff --git a/app/jobs/signal_adapter/attach_contributors_avatar_job.rb b/app/jobs/signal_adapter/attach_contributors_avatar_job.rb
index b4c8a1da9..bbad4ca96 100644
--- a/app/jobs/signal_adapter/attach_contributors_avatar_job.rb
+++ b/app/jobs/signal_adapter/attach_contributors_avatar_job.rb
@@ -4,8 +4,11 @@ module SignalAdapter
class AttachContributorsAvatarJob < ApplicationJob
queue_as :attach_signal_avatar
- def perform(contributor)
- avatar = "/app/signal-cli-config/avatars/profile-#{contributor.signal_phone_number}"
+ def perform(contributor_id:)
+ contributor = Contributor.find_by(id: contributor_id)
+ return unless contributor
+
+ avatar = "/app/signal-cli-config/avatars/profile-#{contributor.signal_uuid}"
return unless File.file?(avatar)
contributor.avatar.attach(io: File.open(avatar), filename: contributor.id)
diff --git a/app/jobs/signal_adapter/create_contact_job.rb b/app/jobs/signal_adapter/create_contact_job.rb
index 497bcef47..109c1ceb6 100644
--- a/app/jobs/signal_adapter/create_contact_job.rb
+++ b/app/jobs/signal_adapter/create_contact_job.rb
@@ -4,14 +4,17 @@
module SignalAdapter
class CreateContactJob < ApplicationJob
- def perform(contributor)
+ def perform(contributor_id:)
+ contributor = Contributor.find_by(id: contributor_id)
+ return unless contributor
+
url = URI.parse("#{Setting.signal_cli_rest_api_endpoint}/v1/contacts/#{Setting.signal_server_phone_number}")
header = {
Accept: 'application/json',
'Content-Type': 'application/json'
}
data = {
- recipient: contributor.signal_phone_number,
+ recipient: contributor.signal_uuid,
name: contributor.name
}
req = Net::HTTP::Put.new(url.to_s, header)
diff --git a/app/jobs/signal_adapter/receive_polling_job.rb b/app/jobs/signal_adapter/receive_polling_job.rb
index b9a1f3d02..6e69a3363 100644
--- a/app/jobs/signal_adapter/receive_polling_job.rb
+++ b/app/jobs/signal_adapter/receive_polling_job.rb
@@ -5,24 +5,46 @@
module SignalAdapter
class ReceivePollingJob < ApplicationJob
queue_as :poll_signal_messages
+ attr_reader :adapter
before_enqueue do
throw(:abort) unless queue_empty?
end
- # rubocop:disable Metrics/MethodLength
def perform(*_args)
return if Setting.signal_server_phone_number.blank?
signal_messages = request_new_messages
- adapter = SignalAdapter::Inbound.new
+ @adapter = SignalAdapter::Inbound.new
- adapter.on(SignalAdapter::CONNECT) do |contributor|
- handle_connect(contributor)
+ handle_callbacks
+
+ signal_messages.each do |raw_message|
+ adapter.consume(raw_message) { |m| m.contributor.reply(adapter) }
+ rescue StandardError => e
+ ErrorNotifier.report(e)
+ end
+
+ ping_monitoring_service && return
+ end
+
+ private
+
+ def request_new_messages
+ url = URI.parse("#{Setting.signal_cli_rest_api_endpoint}/v1/receive/#{Setting.signal_server_phone_number}")
+ res = Net::HTTP.get_response(url)
+ raise SignalAdapter::ServerError if res.instance_of?(Net::HTTPBadRequest)
+
+ JSON.parse(res.body)
+ end
+
+ def handle_callbacks
+ adapter.on(SignalAdapter::CONNECT) do |contributor, signal_uuid|
+ handle_connect(contributor, signal_uuid)
end
- adapter.on(SignalAdapter::UNKNOWN_CONTRIBUTOR) do |signal_phone_number|
- exception = SignalAdapter::UnknownContributorError.new(signal_phone_number: signal_phone_number)
+ adapter.on(SignalAdapter::UNKNOWN_CONTRIBUTOR) do |signal_attr|
+ exception = SignalAdapter::UnknownContributorError.new(signal_attr: signal_attr)
ErrorNotifier.report(exception)
end
@@ -41,25 +63,6 @@ def perform(*_args)
adapter.on(SignalAdapter::HANDLE_DELIVERY_RECEIPT) do |delivery_receipt, contributor|
handle_delivery_receipt(delivery_receipt, contributor)
end
-
- signal_messages.each do |raw_message|
- adapter.consume(raw_message) { |m| m.contributor.reply(adapter) }
- rescue StandardError => e
- ErrorNotifier.report(e)
- end
-
- ping_monitoring_service && return
- end
- # rubocop:enable Metrics/MethodLength
-
- private
-
- def request_new_messages
- url = URI.parse("#{Setting.signal_cli_rest_api_endpoint}/v1/receive/#{Setting.signal_server_phone_number}")
- res = Net::HTTP.get_response(url)
- raise SignalAdapter::ServerError if res.instance_of?(Net::HTTPBadRequest)
-
- JSON.parse(res.body)
end
def ping_monitoring_service
@@ -73,13 +76,15 @@ def queue_empty?
Delayed::Job.where(queue: queue_name, failed_at: nil).none?
end
- def handle_connect(contributor)
- contributor.update!(signal_onboarding_completed_at: Time.zone.now)
+ def handle_connect(contributor, signal_uuid)
+ contributor.update!(signal_uuid: signal_uuid, signal_onboarding_completed_at: Time.current)
+ SignalAdapter::CreateContactJob.perform_later(contributor_id: contributor.id)
+ SignalAdapter::AttachContributorsAvatarJob.perform_later(contributor_id: contributor.id)
SignalAdapter::Outbound.send_welcome_message!(contributor)
- SignalAdapter::AttachContributorsAvatarJob.perform_later(contributor)
end
- def handle_delivery_receipt(delivery_receipt, contributor)
+ def handle_delivery_receipt(signal_message, contributor)
+ delivery_receipt = signal_message.dig(:envelope, :receiptMessage)
datetime = Time.zone.at(delivery_receipt[:when] / 1000).to_datetime
latest_received_message = contributor.received_messages.first
return unless latest_received_message
diff --git a/app/models/contributor.rb b/app/models/contributor.rb
index 43a625832..2dbd22ca6 100644
--- a/app/models/contributor.rb
+++ b/app/models/contributor.rb
@@ -54,7 +54,7 @@ class Contributor < ApplicationRecord
scope :with_email, -> { where.not(email: nil) }
scope :with_threema, -> { where.not(threema_id: nil) }
scope :with_telegram, -> { where.not(telegram_id: nil) }
- scope :with_signal, -> { where.not(signal_phone_number: nil, signal_onboarding_completed_at: nil) }
+ scope :with_signal, -> { where.not(signal_phone_number: nil, signal_uuid: nil) }
scope :with_whats_app, -> { where.not(whats_app_phone_number: nil) }
before_validation do
@@ -145,13 +145,17 @@ def threema?
end
def signal?
- signal_phone_number.present?
+ signal_phone_number.present? || signal_uuid.present?
end
def whats_app?
whats_app_phone_number.present?
end
+ def signal_attr
+ signal_phone_number || signal_uuid
+ end
+
def avatar?
avatar.attached?
end
diff --git a/app/views/onboarding/signal/link.html.erb b/app/views/onboarding/signal/link.html.erb
index 941538323..c9d08f1f3 100644
--- a/app/views/onboarding/signal/link.html.erb
+++ b/app/views/onboarding/signal/link.html.erb
@@ -1,5 +1,5 @@
<%= c 'interstitial' do %>
- <%= c 'onboarding_signal_link' %>
+ <%= c 'onboarding_signal_link', signal_onboarding_token: @signal_onboarding_token %>
<% end %>
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 44e276493..1d84bdded 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -84,16 +84,14 @@ de:
byline: eine Dialog-Recherche von tactile.news
onboarding_signal_link:
heading: Fast geschafft.
- text: Damit wir Ihnen zukünftig auf Signal schreiben können, müssen Sie uns zuerst kontaktieren.
- action: Senden Sie uns hierzu eine Nachricht auf Signal. Ein kurzes „Hallo” reicht aus! Unsere Nummer ist %{number}.
- link: Zur Signal-App
- copy: Handynummer kopieren
- help: Über den Button gelangen Sie direkt zu unserem Kontakt in der Signal-App. Alternativ können Sie unsere Nummer kopieren.
+ text: Verbinden Sie Ihr Signal-Konto in der Signal-App, um die Anmeldung abzuschließen.
+ steps:
+ - "Finden Sie uns auf Signal. Suchen Sie dazu nach %{signal_server_phone_number}."
+ - "Wenn Sie unser Signal-Konto gefunden haben, geben Sie diesen Code ein: %{token}"
onboarding_signal_form:
heading: Mit Signal teilnehmen
text: Geben Sie bitte unten die Handynummer ein, mit der Sie bei Signal registriert sind.
submit: Anmeldung abschließen
-
onboarding_whats_app_form:
heading: Mit WhatsApp teilnehmen
text: Geben Sie bitte unten die Handynummer ein, mit der Sie bei WhatsApp registriert sind.
@@ -244,11 +242,14 @@ de:
contributor_signal_settings:
heading: "Ausgewählter Kanal: Signal"
complete:
- text: |
- %{name} hat sich mit der Handynummer %{phone_number} angemeldet.
+ text:
+ phone_number: |
+ %{name} hat sich mit der Handynummer %{phone_number} angemeldet.
+ uuid: |
+ %{name} hat sich mit der UUID %{uuid} angemeldet.
incomplete:
text: |
- %{name} hat sich am %{date} via Signal mit der Handynummer %{phone_number} angemeldet, die Anmeldung aber noch nicht abgeschlossen.
+ %{name} hat sich am %{date} via Signal angemeldet, die Anmeldung aber noch nicht abgeschlossen.
Sende %{first_name} einen Link mit Hinweisen zum Abschließen der Anmeldung.
action: Link kopieren
contributor_whats_app_settings:
diff --git a/db/migrate/20240618054327_update_signal_attrs_on_contributors.rb b/db/migrate/20240618054327_update_signal_attrs_on_contributors.rb
new file mode 100644
index 000000000..a858803c5
--- /dev/null
+++ b/db/migrate/20240618054327_update_signal_attrs_on_contributors.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class UpdateSignalAttrsOnContributors < ActiveRecord::Migration[6.1]
+ def change
+ change_table :contributors, bulk: true do |t|
+ t.column :signal_uuid, :string, default: nil
+ t.column :signal_onboarding_token, :string, unique: true
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 7e89ac1d2..4731f1de2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2024_03_11_085038) do
+ActiveRecord::Schema.define(version: 2024_06_21_100548) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@@ -116,6 +116,8 @@
t.boolean "deactivated_by_admin", default: false
t.datetime "whats_app_message_template_sent_at"
t.datetime "unsubscribed_at"
+ t.string "signal_uuid"
+ t.string "signal_onboarding_token"
t.index ["email"], name: "index_contributors_on_email", unique: true
t.index ["organization_id"], name: "index_contributors_on_organization_id"
t.index ["signal_phone_number"], name: "index_contributors_on_signal_phone_number", unique: true
diff --git a/docker-compose.yml b/docker-compose.yml
index 118821c07..899ca3450 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -21,7 +21,7 @@ services:
depends_on: [ signal ]
signal:
- image: bbernhard/signal-cli-rest-api:0.81
+ image: bbernhard/signal-cli-rest-api:0.162-dev
environment:
- MODE=native
#- AUTO_RECEIVE_SCHEDULE=0 22 * * * #enable this parameter on demand (see description below)
diff --git a/package-lock.json b/package-lock.json
index d73f84009..ff3bd507b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,4406 @@
{
+ "name": "app",
+ "lockfileVersion": 2,
"requires": true,
- "lockfileVersion": 1,
+ "packages": {
+ "": {
+ "dependencies": {
+ "@hotwired/stimulus": "^3.2.1",
+ "@hotwired/turbo": "^7.2.2",
+ "@rails/ujs": "^6.1.5",
+ "@yaireo/tagify": "^3.25.0",
+ "apexcharts": "^3.36.3",
+ "clipboard-polyfill": "^3.0.3",
+ "dialog-polyfill": "^0.5.6"
+ },
+ "devDependencies": {
+ "@arkweid/lefthook": "^0.7.7",
+ "cssnano": "^5.1.13",
+ "esbuild": "^0.17.10",
+ "esbuild-plugin-import-glob": "^0.1.1",
+ "npm-run-all": "^4.1.5",
+ "postcss": "^8.4.38",
+ "postcss-cli": "^9.1.0",
+ "postcss-easy-import": "^3.0.0",
+ "postcss-preset-env": "^7.8.2",
+ "prettier": "^2.7.1"
+ }
+ },
+ "node_modules/@arkweid/lefthook": {
+ "version": "0.7.7",
+ "resolved": "https://registry.yarnpkg.com/@arkweid/lefthook/-/lefthook-0.7.7.tgz",
+ "integrity": "sha1-EpUbCblV2AVIhf/pKaoHpJ85Anw= sha512-Eq30OXKmjxIAIsTtbX2fcF3SNZIXS8yry1u8yty7PQFYRctx04rVlhOJCEB2UmfTh8T2vrOMC9IHHUvvo5zbaQ==",
+ "cpu": [
+ "x64",
+ "arm64",
+ "ia32"
+ ],
+ "deprecated": "@arkweid/lefthook has been renamed to @evilmartians/lefthook, please upgrade to it. You also can use @evilmartians/lefthook-installer",
+ "dev": true,
+ "hasInstallScript": true,
+ "os": [
+ "darwin",
+ "linux",
+ "win32"
+ ],
+ "bin": {
+ "lefthook": "bin/index.js"
+ }
+ },
+ "node_modules/@csstools/postcss-cascade-layers": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/selector-specificity": "^2.0.2",
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-color-function": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz",
+ "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-font-format-keywords": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-hwb-function": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-ic-unit": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-is-pseudo-class": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/selector-specificity": "^2.0.0",
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-nested-calc": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-normalize-display-values": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-oklab-function": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-progressive-custom-properties": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3"
+ }
+ },
+ "node_modules/@csstools/postcss-stepped-value-functions": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-text-decoration-shorthand": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-trigonometric-functions": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/postcss-unset-value": {
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/@csstools/selector-specificity": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
+ "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
+ "dev": true,
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2",
+ "postcss-selector-parser": "^6.0.10"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.10.tgz",
+ "integrity": "sha512-7YEBfZ5lSem9Tqpsz+tjbdsEshlO9j/REJrfv4DXgKTt1+/MHqGwbtlyxQuaSlMeUZLxUKBaX8wdzlTfHkmnLw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.10.tgz",
+ "integrity": "sha512-ht1P9CmvrPF5yKDtyC+z43RczVs4rrHpRqrmIuoSvSdn44Fs1n6DGlpZKdK6rM83pFLbVaSUwle8IN+TPmkv7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.10.tgz",
+ "integrity": "sha512-CYzrm+hTiY5QICji64aJ/xKdN70IK8XZ6iiyq0tZkd3tfnwwSWTYH1t3m6zyaaBxkuj40kxgMyj1km/NqdjQZA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.10.tgz",
+ "integrity": "sha512-3HaGIowI+nMZlopqyW6+jxYr01KvNaLB5znXfbyyjuo4lE0VZfvFGcguIJapQeQMS4cX/NEispwOekJt3gr5Dg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.10.tgz",
+ "integrity": "sha512-J4MJzGchuCRG5n+B4EHpAMoJmBeAE1L3wGYDIN5oWNqX0tEr7VKOzw0ymSwpoeSpdCa030lagGUfnfhS7OvzrQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.10.tgz",
+ "integrity": "sha512-ZkX40Z7qCbugeK4U5/gbzna/UQkM9d9LNV+Fro8r7HA7sRof5Rwxc46SsqeMvB5ZaR0b1/ITQ/8Y1NmV2F0fXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.10.tgz",
+ "integrity": "sha512-0m0YX1IWSLG9hWh7tZa3kdAugFbZFFx9XrvfpaCMMvrswSTvUZypp0NFKriUurHpBA3xsHVE9Qb/0u2Bbi/otg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.10.tgz",
+ "integrity": "sha512-whRdrrl0X+9D6o5f0sTZtDM9s86Xt4wk1bf7ltx6iQqrIIOH+sre1yjpcCdrVXntQPCNw/G+XqsD4HuxeS+2QA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.10.tgz",
+ "integrity": "sha512-g1EZJR1/c+MmCgVwpdZdKi4QAJ8DCLP5uTgLWSAVd9wlqk9GMscaNMEViG3aE1wS+cNMzXXgdWiW/VX4J+5nTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.10.tgz",
+ "integrity": "sha512-1vKYCjfv/bEwxngHERp7huYfJ4jJzldfxyfaF7hc3216xiDA62xbXJfRlradiMhGZbdNLj2WA1YwYFzs9IWNPw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.10.tgz",
+ "integrity": "sha512-mvwAr75q3Fgc/qz3K6sya3gBmJIYZCgcJ0s7XshpoqIAIBszzfXsqhpRrRdVFAyV1G9VUjj7VopL2HnAS8aHFA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.10.tgz",
+ "integrity": "sha512-XilKPgM2u1zR1YuvCsFQWl9Fc35BqSqktooumOY2zj7CSn5czJn279j9TE1JEqSqz88izJo7yE4x3LSf7oxHzg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.10.tgz",
+ "integrity": "sha512-kM4Rmh9l670SwjlGkIe7pYWezk8uxKHX4Lnn5jBZYBNlWpKMBCVfpAgAJqp5doLobhzF3l64VZVrmGeZ8+uKmQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.10.tgz",
+ "integrity": "sha512-r1m9ZMNJBtOvYYGQVXKy+WvWd0BPvSxMsVq8Hp4GzdMBQvfZRvRr5TtX/1RdN6Va8JMVQGpxqde3O+e8+khNJQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.10.tgz",
+ "integrity": "sha512-LsY7QvOLPw9WRJ+fU5pNB3qrSfA00u32ND5JVDrn/xG5hIQo3kvTxSlWFRP0NJ0+n6HmhPGG0Q4jtQsb6PFoyg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.10.tgz",
+ "integrity": "sha512-zJUfJLebCYzBdIz/Z9vqwFjIA7iSlLCFvVi7glMgnu2MK7XYigwsonXshy9wP9S7szF+nmwrelNaP3WGanstEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.10.tgz",
+ "integrity": "sha512-lOMkailn4Ok9Vbp/q7uJfgicpDTbZFlXlnKT2DqC8uBijmm5oGtXAJy2ZZVo5hX7IOVXikV9LpCMj2U8cTguWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.10.tgz",
+ "integrity": "sha512-/VE0Kx6y7eekqZ+ZLU4AjMlB80ov9tEz4H067Y0STwnGOYL8CsNg4J+cCmBznk1tMpxMoUOf0AbWlb1d2Pkbig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.10.tgz",
+ "integrity": "sha512-ERNO0838OUm8HfUjjsEs71cLjLMu/xt6bhOlxcJ0/1MG3hNqCmbWaS+w/8nFLa0DDjbwZQuGKVtCUJliLmbVgg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.10.tgz",
+ "integrity": "sha512-fXv+L+Bw2AeK+XJHwDAQ9m3NRlNemG6Z6ijLwJAAVdu4cyoFbBWbEtyZzDeL+rpG2lWI51cXeMt70HA8g2MqIg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.10.tgz",
+ "integrity": "sha512-3s+HADrOdCdGOi5lnh5DMQEzgbsFsd4w57L/eLKKjMnN0CN4AIEP0DCP3F3N14xnxh3ruNc32A0Na9zYe1Z/AQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.10.tgz",
+ "integrity": "sha512-oP+zFUjYNaMNmjTwlFtWep85hvwUu19cZklB3QsBOcZSs6y7hmH4LNCJ7075bsqzYaNvZFXJlAVaQ2ApITDXtw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@hotwired/stimulus": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/@hotwired/stimulus/-/stimulus-3.2.1.tgz",
+ "integrity": "sha512-HGlzDcf9vv/EQrMJ5ZG6VWNs8Z/xMN+1o2OhV1gKiSG6CqZt5MCBB1gRg5ILiN3U0jEAxuDTNPRfBcnZBDmupQ=="
+ },
+ "node_modules/@hotwired/turbo": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/@hotwired/turbo/-/turbo-7.2.2.tgz",
+ "integrity": "sha512-YfTHwnur3tDFS/D5JYstU+09Z3bvCF6euqqXajHAks2lTSIDbLc8gMp8yLomD+cAC337h1wnv0oWduK6+6pUDw==",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U= sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos= sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po= sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@rails/ujs": {
+ "version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/@rails/ujs/-/ujs-6.1.5.tgz",
+ "integrity": "sha512-Ir4yd2fdDldWIghavPr874copVKf6OOoecKHZiFRlPtm38tFvhyxr+ywzNieXGwolF9JQe3D5GrM8ejkzUgh5Q=="
+ },
+ "node_modules/@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@yaireo/tagify": {
+ "version": "3.25.0",
+ "resolved": "https://registry.yarnpkg.com/@yaireo/tagify/-/tagify-3.25.0.tgz",
+ "integrity": "sha1-Sgcoz2jHE64Wwl1SOTqRDi37WHU= sha512-aBRkGDkWdv6ZnRUCcA0mBIK5f3YegnxlFO9vj9zN5zSAUO90m2v5TsOPYN60sk6RNU/y556oc8jAmeSY7FUvaQ==",
+ "peerDependencies": {
+ "prop-types": "^15.7.2"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/apexcharts": {
+ "version": "3.36.3",
+ "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.36.3.tgz",
+ "integrity": "sha512-8/FXEs0ohXMff07Gv28XjhPwEJphIUdq2/wii/pcvi54Tw6z1mjrV8ydN8rlWi/ve8BAPBefJkLmRWv7UOBsLw==",
+ "dependencies": {
+ "svg.draggable.js": "^2.2.2",
+ "svg.easing.js": "^2.0.0",
+ "svg.filter.js": "^2.0.2",
+ "svg.pathmorphing.js": "^0.1.3",
+ "svg.resize.js": "^1.4.3",
+ "svg.select.js": "^3.0.1"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "dependencies": {
+ "array-uniq": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.12",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz",
+ "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ }
+ ],
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-lite": "^1.0.30001407",
+ "fraction.js": "^4.2.0",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/autoprefixer/node_modules/browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/autoprefixer/node_modules/caniuse-lite": {
+ "version": "1.0.30001414",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz",
+ "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/autoprefixer/node_modules/electron-to-chromium": {
+ "version": "1.4.270",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz",
+ "integrity": "sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==",
+ "dev": true
+ },
+ "node_modules/autoprefixer/node_modules/node-releases": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4= sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc= sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/browserslist/node_modules/update-browserslist-db": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz",
+ "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist-lint": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw= sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001414",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz",
+ "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/clipboard-polyfill": {
+ "version": "3.0.3",
+ "resolved": "https://registry.yarnpkg.com/clipboard-polyfill/-/clipboard-polyfill-3.0.3.tgz",
+ "integrity": "sha1-FZ6gdo4g7cf/2kBL0TxUxz3k/0A= sha512-hts0o01ZkwjA1qHA5gFePzAj/780W7v+eyN3GdaCRyDnapzcPsKRV5aodv77gcr40NDIcyNjNmc+HvfKV+jD0g=="
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-convert/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/colord": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q= sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/css-blank-pseudo": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.9"
+ },
+ "bin": {
+ "css-blank-pseudo": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/css-declaration-sorter": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
+ "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.9"
+ }
+ },
+ "node_modules/css-has-pseudo": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz",
+ "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.9"
+ },
+ "bin": {
+ "css-has-pseudo": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/css-prefers-color-scheme": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
+ "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
+ "dev": true,
+ "bin": {
+ "css-prefers-color-scheme": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssdb": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.0.1.tgz",
+ "integrity": "sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssnano": {
+ "version": "5.1.13",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.13.tgz",
+ "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==",
+ "dev": true,
+ "dependencies": {
+ "cssnano-preset-default": "^5.2.12",
+ "lilconfig": "^2.0.3",
+ "yaml": "^1.10.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/cssnano"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/cssnano-preset-default": {
+ "version": "5.2.12",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz",
+ "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==",
+ "dev": true,
+ "dependencies": {
+ "css-declaration-sorter": "^6.3.0",
+ "cssnano-utils": "^3.1.0",
+ "postcss-calc": "^8.2.3",
+ "postcss-colormin": "^5.3.0",
+ "postcss-convert-values": "^5.1.2",
+ "postcss-discard-comments": "^5.1.2",
+ "postcss-discard-duplicates": "^5.1.0",
+ "postcss-discard-empty": "^5.1.1",
+ "postcss-discard-overridden": "^5.1.0",
+ "postcss-merge-longhand": "^5.1.6",
+ "postcss-merge-rules": "^5.1.2",
+ "postcss-minify-font-values": "^5.1.0",
+ "postcss-minify-gradients": "^5.1.1",
+ "postcss-minify-params": "^5.1.3",
+ "postcss-minify-selectors": "^5.2.1",
+ "postcss-normalize-charset": "^5.1.0",
+ "postcss-normalize-display-values": "^5.1.0",
+ "postcss-normalize-positions": "^5.1.1",
+ "postcss-normalize-repeat-style": "^5.1.1",
+ "postcss-normalize-string": "^5.1.0",
+ "postcss-normalize-timing-functions": "^5.1.0",
+ "postcss-normalize-unicode": "^5.1.0",
+ "postcss-normalize-url": "^5.1.0",
+ "postcss-normalize-whitespace": "^5.1.1",
+ "postcss-ordered-values": "^5.1.3",
+ "postcss-reduce-initial": "^5.1.0",
+ "postcss-reduce-transforms": "^5.1.0",
+ "postcss-svgo": "^5.1.0",
+ "postcss-unique-selectors": "^5.1.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/cssnano-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
+ "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/csso": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+ "dev": true,
+ "dependencies": {
+ "css-tree": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/dependency-graph": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/dialog-polyfill": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz",
+ "integrity": "sha512-ZbVDJI9uvxPAKze6z146rmfUZjBqNEwcnFTVamQzXH+svluiV7swmVIGr7miwADgfgt1G2JQIytypM9fbyhX4w=="
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dir-glob/node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.270",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz",
+ "integrity": "sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==",
+ "dev": true
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8= sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.18.6",
+ "resolved": "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.6.tgz",
+ "integrity": "sha1-LETj6npiVQORZNJlWXd6bZeMtFY= sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "get-symbol-description": "^1.0.0",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "internal-slot": "^1.0.3",
+ "is-callable": "^1.2.4",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.4",
+ "is-string": "^1.0.7",
+ "object-inspect": "^1.11.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo= sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.17.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.10.tgz",
+ "integrity": "sha512-n7V3v29IuZy5qgxx25TKJrEm0FHghAlS6QweUcyIgh/U0zYmQcvogWROitrTyZId1mHSkuhhuyEXtI9OXioq7A==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.17.10",
+ "@esbuild/android-arm64": "0.17.10",
+ "@esbuild/android-x64": "0.17.10",
+ "@esbuild/darwin-arm64": "0.17.10",
+ "@esbuild/darwin-x64": "0.17.10",
+ "@esbuild/freebsd-arm64": "0.17.10",
+ "@esbuild/freebsd-x64": "0.17.10",
+ "@esbuild/linux-arm": "0.17.10",
+ "@esbuild/linux-arm64": "0.17.10",
+ "@esbuild/linux-ia32": "0.17.10",
+ "@esbuild/linux-loong64": "0.17.10",
+ "@esbuild/linux-mips64el": "0.17.10",
+ "@esbuild/linux-ppc64": "0.17.10",
+ "@esbuild/linux-riscv64": "0.17.10",
+ "@esbuild/linux-s390x": "0.17.10",
+ "@esbuild/linux-x64": "0.17.10",
+ "@esbuild/netbsd-x64": "0.17.10",
+ "@esbuild/openbsd-x64": "0.17.10",
+ "@esbuild/sunos-x64": "0.17.10",
+ "@esbuild/win32-arm64": "0.17.10",
+ "@esbuild/win32-ia32": "0.17.10",
+ "@esbuild/win32-x64": "0.17.10"
+ }
+ },
+ "node_modules/esbuild-plugin-import-glob": {
+ "version": "0.1.1",
+ "resolved": "https://registry.yarnpkg.com/esbuild-plugin-import-glob/-/esbuild-plugin-import-glob-0.1.1.tgz",
+ "integrity": "sha1-arWtmSqme6mxqoDAdZ1WF5YM1cM= sha512-yAFH+9AoIcsQkODSx0KUPRv1FeJUN6Tef8vkPQMcuVkc2vXYneYKsHhOiFS/yIsg5bQ70HHtAlXVA1uTjgoJXg==",
+ "dev": true,
+ "dependencies": {
+ "fast-glob": "^3.2.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.7",
+ "resolved": "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz",
+ "integrity": "sha1-/Wy3otfpqnp4RhEehaGW1rL3ZqE= sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
+ "dev": true,
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha1-YWdg+Ip1Jr38WWt8q4wYk4w2uYw= sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA= sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
+ "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://www.patreon.com/infusion"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y= sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
+ "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha1-f9uByQAQH71WTdXxowr1qtweWNY= sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha1-Oxk+kjPwHULQs/eClLvutBj5SpA= sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ= sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globby": {
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz",
+ "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^3.0.1",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.7",
+ "ignore": "^5.1.9",
+ "merge2": "^1.4.1",
+ "slash": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/array-union": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz",
+ "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.8",
+ "resolved": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha1-5BK40z9eAGWTy9PO5t+fLOu+gCo= sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz",
+ "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.1",
+ "resolved": "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz",
+ "integrity": "sha1-ZP5qywIGc+O3jbA1pa9pqp0HsRM= sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM= sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha1-fhM4GKfTlHNPlB5zw9P5KR5liyU= sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha1-3/wL+aIcAiCQkPKqaUKeFBTa8/k= sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "node_modules/ignore": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "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.",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha1-c0fjB97uovqsKsYgXUvH00ln9Zw= sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha1-CBR6GHW8KzIAXUHM2Ckd/8ZpHfM= sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha1-XG3CACRt2TIa5LiFoRS7H3X2Nxk= sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.4",
+ "resolved": "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz",
+ "integrity": "sha1-RzAdWN0CWUB4ZVR4U99tYf5HGUU= sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.7.0",
+ "resolved": "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz",
+ "integrity": "sha1-PA730xtKz8V0+AxYQJ1WioNoSOM= sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha1-CEHVU25yTCVZe/bqYuG9OCmN8x8= sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.2",
+ "resolved": "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.2.tgz",
+ "integrity": "sha1-hZ/C5zHljJAvmfyrzLdafdB9Kdg= sha512-ZZTOjRcDjuAAAv2cTBQP/lL59ZTArx77+7UzHdWW/XB1mrfp7DEaVpKmZ0XIzx+M7AxfhKcqV+nMetUQmFifwg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha1-PedGwY3aIxkkGlNnWQjY92bxHCQ= sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss= sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.6",
+ "resolved": "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz",
+ "integrity": "sha1-anqvg4x/BoalC0VT9+VKlklOifA= sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha1-7vVmPNWfpMCuM5UFMj32hUuxWVg= sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha1-DdEr8gBvJVu1j2lREO/3SR7rwP0= sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha1-ptrJO2NbBjymhyI23oiRClevE5w= sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk= sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz",
+ "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw= sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+ "dev": true
+ },
+ "node_modules/mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "dev": true
+ },
+ "node_modules/memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4= sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha1-iW1Rnf6dsl/OlM63pQCRm/iB6/k= sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y= sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg= sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-all": {
+ "version": "4.1.5",
+ "resolved": "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz",
+ "integrity": "sha1-BEdiAqFe4OLiFAgIYb/xKlHZj7o= sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "chalk": "^2.4.1",
+ "cross-spawn": "^6.0.5",
+ "memorystream": "^0.3.1",
+ "minimatch": "^3.0.4",
+ "pidtree": "^0.3.0",
+ "read-pkg": "^3.0.0",
+ "shell-quote": "^1.6.1",
+ "string.prototype.padend": "^3.0.0"
+ },
+ "bin": {
+ "npm-run-all": "bin/npm-run-all/index.js",
+ "run-p": "bin/run-p/index.js",
+ "run-s": "bin/run-s/index.js"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.11.0",
+ "resolved": "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz",
+ "integrity": "sha1-nc6xRs7dQUig2eUauI00z1CZIrE= sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4= sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha1-DtVKNC7Os3s4/3brgxoOeIy2OUA= sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU= sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428= sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI= sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.3.1",
+ "resolved": "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz",
+ "integrity": "sha1-7wmsLMBTPfHzJQzPLE02aw0SEUo= sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+ "dev": true,
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-attribute-case-insensitive": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-calc": {
+ "version": "8.2.4",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
+ "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.9",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.2"
+ }
+ },
+ "node_modules/postcss-clamp": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz",
+ "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=7.6.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.6"
+ }
+ },
+ "node_modules/postcss-cli": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz",
+ "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": "^3.3.0",
+ "dependency-graph": "^0.11.0",
+ "fs-extra": "^10.0.0",
+ "get-stdin": "^9.0.0",
+ "globby": "^12.0.0",
+ "picocolors": "^1.0.0",
+ "postcss-load-config": "^3.0.0",
+ "postcss-reporter": "^7.0.0",
+ "pretty-hrtime": "^1.0.3",
+ "read-cache": "^1.0.0",
+ "slash": "^4.0.0",
+ "yargs": "^17.0.0"
+ },
+ "bin": {
+ "postcss": "index.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-color-functional-notation": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-color-hex-alpha": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz",
+ "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-color-rebeccapurple": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-colormin": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz",
+ "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "caniuse-api": "^3.0.0",
+ "colord": "^2.9.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-convert-values": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz",
+ "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.20.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-custom-media": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz",
+ "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3"
+ }
+ },
+ "node_modules/postcss-custom-properties": {
+ "version": "12.1.9",
+ "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.9.tgz",
+ "integrity": "sha512-/E7PRvK8DAVljBbeWrcEQJPG72jaImxF3vvCNFwv9cC8CzigVoNIpeyfnJzphnN3Fd8/auBf5wvkw6W9MfmTyg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-custom-selectors": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz",
+ "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3"
+ }
+ },
+ "node_modules/postcss-dir-pseudo-class": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-discard-comments": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
+ "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-duplicates": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
+ "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-empty": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
+ "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-overridden": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
+ "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-double-position-gradients": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-easy-import": {
+ "version": "3.0.0",
+ "resolved": "https://registry.yarnpkg.com/postcss-easy-import/-/postcss-easy-import-3.0.0.tgz",
+ "integrity": "sha1-jqr1rllWYIPQyumHNd/YA+OrGU0= sha512-cfNsear/v8xlkl9v5Wm8y4Do/puiDQTFF+WX2Fo++h7oKt1fKWVVW/5Ca8hslYDQWnjndrg813cA23Pt1jsYdg==",
+ "dev": true,
+ "dependencies": {
+ "globby": "^6.1.0",
+ "is-glob": "^4.0.0",
+ "lodash": "^4.17.4",
+ "object-assign": "^4.0.1",
+ "pify": "^3.0.0",
+ "postcss": "^6.0.11",
+ "postcss-import": "^10.0.0",
+ "resolve": "^1.1.7"
+ }
+ },
+ "node_modules/postcss-easy-import/node_modules/globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postcss-easy-import/node_modules/globby/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postcss-easy-import/node_modules/postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha1-YcgswyisYOZ3ZF+XkFTrmLwOMyQ= sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/postcss-env-function": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-focus-visible": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.9"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-focus-within": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.9"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-font-variant": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
+ "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
+ "dev": true,
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-gap-properties": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz",
+ "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==",
+ "dev": true,
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-image-set-function": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "10.0.0",
+ "resolved": "https://registry.yarnpkg.com/postcss-import/-/postcss-import-10.0.0.tgz",
+ "integrity": "sha1-TIXJewmRNsxeoCQNwd/b/eTi674=",
+ "dev": true,
+ "dependencies": {
+ "object-assign": "^4.0.1",
+ "postcss": "^6.0.1",
+ "postcss-value-parser": "^3.2.3",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ }
+ },
+ "node_modules/postcss-import/node_modules/postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha1-YcgswyisYOZ3ZF+XkFTrmLwOMyQ= sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/postcss-import/node_modules/postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha1-n/giVH4okyE88cMO+lGsX9G6goE= sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ },
+ "node_modules/postcss-initial": {
+ "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==",
+ "dev": true,
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-lab-function": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz",
+ "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
+ "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
+ "dev": true,
+ "dependencies": {
+ "lilconfig": "^2.0.5",
+ "yaml": "^1.10.2"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-logical": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
+ "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
+ "dev": true,
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-media-minmax": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
+ "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-merge-longhand": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz",
+ "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "stylehacks": "^5.1.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-merge-rules": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz",
+ "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "caniuse-api": "^3.0.0",
+ "cssnano-utils": "^3.1.0",
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-font-values": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz",
+ "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-gradients": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz",
+ "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==",
+ "dev": true,
+ "dependencies": {
+ "colord": "^2.9.1",
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-params": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz",
+ "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-selectors": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz",
+ "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-nesting": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz",
+ "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/selector-specificity": "^2.0.0",
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-normalize-charset": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
+ "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-display-values": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz",
+ "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-positions": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz",
+ "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-repeat-style": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz",
+ "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-string": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz",
+ "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-timing-functions": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz",
+ "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-unicode": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz",
+ "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz",
+ "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==",
+ "dev": true,
+ "dependencies": {
+ "normalize-url": "^6.0.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-whitespace": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz",
+ "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-opacity-percentage": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz",
+ "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "kofi",
+ "url": "https://ko-fi.com/mrcgrtz"
+ },
+ {
+ "type": "liberapay",
+ "url": "https://liberapay.com/mrcgrtz"
+ }
+ ],
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ }
+ },
+ "node_modules/postcss-ordered-values": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz",
+ "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==",
+ "dev": true,
+ "dependencies": {
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-overflow-shorthand": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz",
+ "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-page-break": {
+ "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==",
+ "dev": true,
+ "peerDependencies": {
+ "postcss": "^8"
+ }
+ },
+ "node_modules/postcss-place": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz",
+ "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-preset-env": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz",
+ "integrity": "sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/postcss-cascade-layers": "^1.1.0",
+ "@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.11",
+ "browserslist": "^4.21.3",
+ "css-blank-pseudo": "^3.0.3",
+ "css-has-pseudo": "^3.0.4",
+ "css-prefers-color-scheme": "^6.0.3",
+ "cssdb": "^7.0.1",
+ "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.9",
+ "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"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-preset-env/node_modules/browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/postcss-preset-env/node_modules/caniuse-lite": {
+ "version": "1.0.30001414",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz",
+ "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/postcss-preset-env/node_modules/electron-to-chromium": {
+ "version": "1.4.270",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz",
+ "integrity": "sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==",
+ "dev": true
+ },
+ "node_modules/postcss-preset-env/node_modules/node-releases": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
+ },
+ "node_modules/postcss-pseudo-class-any-link": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-reduce-initial": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz",
+ "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "caniuse-api": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-reduce-transforms": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz",
+ "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-replace-overflow-wrap": {
+ "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==",
+ "dev": true,
+ "peerDependencies": {
+ "postcss": "^8.0.3"
+ }
+ },
+ "node_modules/postcss-reporter": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz",
+ "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==",
+ "dev": true,
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "thenby": "^1.3.4"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-selector-not": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-svgo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz",
+ "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "svgo": "^2.7.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-unique-selectors": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz",
+ "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true
+ },
+ "node_modules/prettier": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+ "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha1-SSkii7xyTfrEPg77BYyve2z7YkM= sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+ "dev": true,
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/read-cache/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "dependencies": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha1-YpoBP7P3B1XW8LeTXMHCxTeLGXU= sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY= sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4= sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz",
+ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
+ "dev": true
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha1-785cj9wQTudRslxY1CkAEfpeos8= sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/slash": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
+ "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM= sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha1-3s6BrJweZxPl99G28X1Gj6U9iak= sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha1-PyjOGnegA3JoPq3kpDMYNSeiFj0= sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha1-z3D1BILu/cmOPOCmgz5KU87rpnk= sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.10",
+ "resolved": "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
+ "integrity": "sha1-DZvszN5wA9bGWNSH3UijLwvzAUs= sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+ "dev": true
+ },
+ "node_modules/stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility",
+ "dev": true
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.padend": {
+ "version": "3.1.2",
+ "resolved": "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz",
+ "integrity": "sha1-aFjKTzXFJo69XoYV4TJ9VfWe4xE= sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha1-51rpDClCxjUEaGwYsoe0oLGkX4A= sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha1-s2OZr0qymZtMnGSL16P7K7Jv7u0= sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/stylehacks": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz",
+ "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/svg.draggable.js": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
+ "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
+ "dependencies": {
+ "svg.js": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svg.easing.js": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
+ "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==",
+ "dependencies": {
+ "svg.js": ">=2.3.x"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svg.filter.js": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
+ "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==",
+ "dependencies": {
+ "svg.js": "^2.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svg.js": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
+ "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
+ },
+ "node_modules/svg.pathmorphing.js": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
+ "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
+ "dependencies": {
+ "svg.js": "^2.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svg.resize.js": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
+ "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
+ "dependencies": {
+ "svg.js": "^2.6.5",
+ "svg.select.js": "^2.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svg.resize.js/node_modules/svg.select.js": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
+ "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
+ "dependencies": {
+ "svg.js": "^2.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svg.select.js": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
+ "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
+ "dependencies": {
+ "svg.js": "^2.6.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/svgo": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
+ "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
+ "dev": true,
+ "dependencies": {
+ "@trysound/sax": "0.2.0",
+ "commander": "^7.2.0",
+ "css-select": "^4.1.3",
+ "css-tree": "^1.1.3",
+ "csso": "^4.2.0",
+ "picocolors": "^1.0.0",
+ "stable": "^0.1.8"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/thenby": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
+ "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
+ "dev": true
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ= sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.1",
+ "resolved": "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
+ "integrity": "sha1-CF4hViXsMWJXTciFmr7nilmxRHE= sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has-bigints": "^1.0.1",
+ "has-symbols": "^1.0.2",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz",
+ "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist-lint": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo= sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz",
+ "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo= sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha1-E3V7yJsgmwSf5dhkMOIc9AqJqOY= sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.5.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+ "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
+ "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ }
+ },
"dependencies": {
"@arkweid/lefthook": {
"version": "0.7.7",
@@ -134,13 +4534,15 @@
"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==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"@csstools/selector-specificity": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
"integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"@esbuild/android-arm": {
"version": "0.17.10",
@@ -346,7 +4748,8 @@
"@yaireo/tagify": {
"version": "3.25.0",
"resolved": "https://registry.yarnpkg.com/@yaireo/tagify/-/tagify-3.25.0.tgz",
- "integrity": "sha1-Sgcoz2jHE64Wwl1SOTqRDi37WHU= sha512-aBRkGDkWdv6ZnRUCcA0mBIK5f3YegnxlFO9vj9zN5zSAUO90m2v5TsOPYN60sk6RNU/y556oc8jAmeSY7FUvaQ=="
+ "integrity": "sha1-Sgcoz2jHE64Wwl1SOTqRDi37WHU= sha512-aBRkGDkWdv6ZnRUCcA0mBIK5f3YegnxlFO9vj9zN5zSAUO90m2v5TsOPYN60sk6RNU/y556oc8jAmeSY7FUvaQ==",
+ "requires": {}
},
"ansi-regex": {
"version": "5.0.1",
@@ -646,7 +5049,8 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
"integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"css-has-pseudo": {
"version": "3.0.4",
@@ -661,7 +5065,8 @@
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
"integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"css-select": {
"version": "4.3.0",
@@ -756,7 +5161,8 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
"integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"csso": {
"version": "4.2.0",
@@ -1742,25 +6148,29 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
"integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-discard-duplicates": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
"integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-discard-empty": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
"integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-discard-overridden": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
"integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-double-position-gradients": {
"version": "3.1.2",
@@ -1853,13 +6263,15 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
"integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-gap-properties": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz",
"integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-image-set-function": {
"version": "4.0.7",
@@ -1906,7 +6318,8 @@
"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==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-lab-function": {
"version": "4.2.1",
@@ -1932,13 +6345,15 @@
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
"integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-media-minmax": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
"integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-merge-longhand": {
"version": "5.1.6",
@@ -2016,7 +6431,8 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
"integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-normalize-display-values": {
"version": "5.1.0",
@@ -2121,7 +6537,8 @@
"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==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-place": {
"version": "7.0.5",
@@ -2253,7 +6670,8 @@
"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==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"postcss-reporter": {
"version": "7.0.5",
diff --git a/spec/adapters/signal_adapter/inbound_spec.rb b/spec/adapters/signal_adapter/inbound_spec.rb
index 7b57276b1..ad94877a8 100644
--- a/spec/adapters/signal_adapter/inbound_spec.rb
+++ b/spec/adapters/signal_adapter/inbound_spec.rb
@@ -8,6 +8,8 @@
{
envelope: {
source: '+4912345789',
+ sourceNumber: '+4912345789',
+ sourceUuid: 'valid_uuid',
sourceDevice: 2,
timestamp: 1_626_708_555_697,
dataMessage: {
@@ -20,6 +22,24 @@
}
end
+ let(:signal_message_with_uuid) do
+ {
+ envelope: {
+ source: 'valid_uuid',
+ sourceNumber: nil,
+ sourceUuid: 'valid_uuid',
+ sourceDevice: 2,
+ timestamp: 1_626_708_555_697,
+ dataMessage: {
+ timestamp: 1_626_708_555_697,
+ message: signal_onboarding_token,
+ expiresInSeconds: 0,
+ viewOnce: false
+ }
+ }
+ }
+ end
+
let(:signal_receipt_message) do
{
envelope: {
@@ -201,12 +221,6 @@
it { should be(nil) }
end
- context 'from a contributor with incomplete onboarding' do
- let(:onboarding_completed_at) { nil }
-
- it { should be(nil) }
- end
-
context 'given a receipt message' do
before { create(:message, recipient_id: contributor.id) }
let(:signal_message) { signal_receipt_message }
@@ -248,6 +262,37 @@
expect(message.files.first.attachment).to be_attached
end
end
+
+ describe 'given a message to complete onboarding' do
+ let(:signal_message) { signal_message_with_uuid }
+ let(:signal_uuid) { nil }
+ let(:onboarding_completed_at) { nil }
+
+ let!(:contributor) do
+ create(
+ :contributor,
+ signal_uuid: signal_uuid,
+ signal_onboarding_completed_at: onboarding_completed_at,
+ signal_onboarding_token: 'NQ272QQK'
+ )
+ end
+
+ context 'unknown contributor' do
+ let(:signal_onboarding_token) { 'some other message' }
+
+ it 'does not create a message' do
+ expect(subject).to be(nil)
+ end
+ end
+
+ context 'known contributor' do
+ let(:signal_onboarding_token) { 'NQ272QQK' }
+
+ it 'does not create a message' do
+ expect(subject).to be(nil)
+ end
+ end
+ end
end
describe '|message|text' do
@@ -361,10 +406,14 @@
describe '#on' do
describe 'CONNECT' do
let(:connect_callback) { spy('connect_callback') }
+ let(:signal_message) { signal_message_with_uuid }
+ let(:signal_uuid) { signal_message.dig(:envelope, :sourceUuid) }
+
+ let!(:contributor) { create(:contributor, signal_onboarding_token: 'NQ272QQK') }
before do
- adapter.on(SignalAdapter::CONNECT) do |contributor|
- connect_callback.call(contributor)
+ adapter.on(SignalAdapter::CONNECT) do |contributor, signal_uuid|
+ connect_callback.call(contributor, signal_uuid)
end
end
@@ -374,26 +423,26 @@
end
context 'if the sender is unknown' do
- let(:phone_number) { nil }
+ let(:signal_onboarding_token) { 'whatever message' }
it { should_not have_received(:call) }
end
context 'if the sender is a contributor with incomplete onboarding' do
- let(:onboarding_completed_at) { nil }
- it { should have_received(:call).with(contributor) }
- end
-
- context 'if the sender is a contributor who has completed onboarding' do
- it { should_not have_received(:call) }
+ let(:signal_onboarding_token) { 'NQ272QQK' }
+ it { should have_received(:call).with(contributor, signal_uuid) }
end
end
describe 'UNKNOWN_CONTRIBUTOR' do
let(:unknown_contributor_callback) { spy('unknown_contributor_callback') }
+ let(:signal_message) { signal_message_with_uuid }
+ let(:signal_uuid) { signal_message.dig(:envelope, :sourceUuid) }
+ let(:source) { signal_message.dig(:envelope, :source) }
+ let!(:contributor) { create(:contributor, signal_onboarding_token: 'NQ272QQK') }
before do
- adapter.on(SignalAdapter::UNKNOWN_CONTRIBUTOR) do |signal_phone_number|
- unknown_contributor_callback.call(signal_phone_number)
+ adapter.on(SignalAdapter::UNKNOWN_CONTRIBUTOR) do |source|
+ unknown_contributor_callback.call(source)
end
end
@@ -402,18 +451,14 @@
unknown_contributor_callback
end
- describe 'if the sender is a contributor ' do
- it { should_not have_received(:call) }
- end
-
- describe 'if the sender has not completed onboarding' do
- let(:onboarding_completed_at) { nil }
+ context 'if the sender is a contributor with incomplete onboarding' do
+ let(:signal_onboarding_token) { 'NQ272QQK' }
it { should_not have_received(:call) }
end
- describe 'if the sender is unknown' do
- before { signal_message[:envelope][:source] = '+4955443322' }
- it { should have_received(:call).with('+4955443322') }
+ context 'if the sender is unknown' do
+ let(:signal_onboarding_token) { 'whatever message' }
+ it { should have_received(:call).with(source) }
end
end
diff --git a/spec/adapters/signal_adapter/outbound_spec.rb b/spec/adapters/signal_adapter/outbound_spec.rb
index 0a9712bbc..781e58276 100644
--- a/spec/adapters/signal_adapter/outbound_spec.rb
+++ b/spec/adapters/signal_adapter/outbound_spec.rb
@@ -10,6 +10,7 @@
let(:expected_job_args) do
{ contributor_id: contributor.id, text: [Setting.onboarding_success_heading, Setting.onboarding_success_text].join("\n") }
end
+ let(:onboarding_completed_at) { nil }
describe '::send_welcome_message!' do
subject { -> { described_class.send_welcome_message!(contributor) } }
@@ -18,7 +19,6 @@
it { should_not enqueue_job(described_class::Text) }
context 'contributor has a phone number' do
- let(:onboarding_completed_at) { nil }
let(:contributor) do
create(
:contributor,
@@ -28,23 +28,58 @@
)
end
- it { should_not enqueue_job(described_class::Text) }
+ context 'but has not completed onboarding' do
+ it 'does not enqueue the job to send the welcome message' do
+ expect { subject.call }.not_to enqueue_job(described_class::Text)
+ end
+ end
+
+ context 'has completed onboarding' do
+ let(:onboarding_completed_at) { 1.minute.ago }
+
+ it 'enqueus the job to send out the welcome message' do
+ expect { subject.call }.to enqueue_job(described_class::Text).with(expected_job_args)
+ end
+ end
+ end
+
+ context 'contributor has a uuid' do
+ let(:contributor) do
+ create(
+ :contributor,
+ signal_uuid: 'valid_uuid',
+ signal_onboarding_completed_at: onboarding_completed_at,
+ email: nil
+ )
+ end
- context 'and has completed onboarding' do
- let(:onboarding_completed_at) { Time.zone.now }
- it { should enqueue_job(described_class::Text).with(expected_job_args) }
+ context 'but has not completed onboarding' do
+ it 'does not enqueue the job to send the welcome message' do
+ expect { subject.call }.not_to enqueue_job(described_class::Text)
+ end
+ end
+
+ context 'has completed onboarding' do
+ let(:onboarding_completed_at) { 1.minute.ago }
+
+ it 'enqueus the job to send out the welcome message' do
+ expect { subject.call }.to enqueue_job(described_class::Text).with(expected_job_args)
+ end
end
end
end
describe '::send!' do
subject { -> { described_class.send!(message) } }
+
+ let(:expected_job_args) do
+ { contributor_id: contributor.id, text: message.text }
+ end
before { message } # we don't count the extra ::send here
+
it { should_not enqueue_job(described_class::Text) }
describe 'contributor has a phone number' do
- let(:onboarding_completed_at) { nil }
-
let(:contributor) do
create(
:contributor,
@@ -54,11 +89,43 @@
)
end
- it { should_not enqueue_job(described_class::Text) }
+ context 'but has not completed onboarding' do
+ it 'does not enqueue the job to send the welcome message' do
+ expect { subject.call }.not_to enqueue_job(described_class::Text)
+ end
+ end
+
+ context 'has completed onboarding' do
+ let(:onboarding_completed_at) { 1.minute.ago }
+
+ it 'enqueus the job to send out the welcome message' do
+ expect { subject.call }.to enqueue_job(described_class::Text).with(expected_job_args)
+ end
+ end
+ end
+
+ describe 'contributor has a uuid' do
+ let(:contributor) do
+ create(
+ :contributor,
+ email: nil,
+ signal_uuid: 'valid_uuid',
+ signal_onboarding_completed_at: onboarding_completed_at
+ )
+ end
+
+ context 'but has not completed onboarding' do
+ it 'does not enqueue the job to send the welcome message' do
+ expect { subject.call }.not_to enqueue_job(described_class::Text)
+ end
+ end
+
+ context 'has completed onboarding' do
+ let(:onboarding_completed_at) { 1.minute.ago }
- context 'and has completed onboarding' do
- let(:onboarding_completed_at) { Time.zone.now }
- it { should enqueue_job(described_class::Text) }
+ it 'enqueus the job to send out the welcome message' do
+ expect { subject.call }.to enqueue_job(described_class::Text).with(expected_job_args)
+ end
end
end
end
diff --git a/spec/components/contributor_signal_settings_spec.rb b/spec/components/contributor_signal_settings_spec.rb
index 0d2a51e13..59517d502 100644
--- a/spec/components/contributor_signal_settings_spec.rb
+++ b/spec/components/contributor_signal_settings_spec.rb
@@ -6,6 +6,7 @@
subject { render_inline(described_class.new(**params)) }
let(:params) { { contributor: contributor } }
+ let(:complete_onboarding_link) { onboarding_signal_link_path(signal_onboarding_token: contributor.signal_onboarding_token) }
let(:contributor) do
create(:contributor,
@@ -24,9 +25,41 @@
context 'given a contributor with incomplete onboarding' do
let(:onboarding_completed_at) { nil }
- it { should have_css('p', text: 'Max Mustermann hat sich am 01.01.2021 via Signal') }
- it { should have_css('p', text: 'mit der Handynummer 0151 1234 5678 angemeldet, die Anmeldung aber noch nicht abgeschlossen.') }
+ it {
+ should have_css('p',
+ text: 'Max Mustermann hat sich am 01.01.2021 via Signal angemeldet, die Anmeldung aber noch nicht abgeschlossen.')
+ }
it { should have_css('p', text: 'Sende Max einen Link mit Hinweisen zum Abschließen der Anmeldung.') }
- it { should have_css('button[data-copy-button-copy-value$="http://test.host/onboarding/signal/link"]') }
+ it { should have_css("button[data-copy-button-copy-value$='#{complete_onboarding_link}']") }
+ end
+
+ describe 'given a contributor with signal_uuid' do
+ let(:contributor) do
+ create(:contributor,
+ first_name: 'Max',
+ last_name: 'Mustermann',
+ signal_phone_number: nil,
+ signal_uuid: signal_uuid,
+ signal_onboarding_completed_at: onboarding_completed_at,
+ created_at: '2021-01-01')
+ end
+
+ let(:onboarding_completed_at) { Time.current }
+ let(:signal_uuid) { 'valid_uuid' }
+
+ it { should have_css('h2', text: 'Signal') }
+ it { should have_css('p', text: 'Max Mustermann hat sich mit der UUID valid_uuid angemeldet.') }
+
+ context 'given a contributor with incomplete onboarding' do
+ let(:onboarding_completed_at) { nil }
+ let(:signal_uuid) { nil }
+
+ it {
+ should have_css('p',
+ text: 'Max Mustermann hat sich am 01.01.2021 via Signal angemeldet, die Anmeldung aber noch nicht abgeschlossen.')
+ }
+ it { should have_css('p', text: 'Sende Max einen Link mit Hinweisen zum Abschließen der Anmeldung.') }
+ it { should have_css("button[data-copy-button-copy-value$='#{complete_onboarding_link}']") }
+ end
end
end
diff --git a/spec/components/onboarding_signal_link_spec.rb b/spec/components/onboarding_signal_link_spec.rb
deleted file mode 100644
index 7022e43b1..000000000
--- a/spec/components/onboarding_signal_link_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe OnboardingSignalLink::OnboardingSignalLink, type: :component do
- subject { render_inline(described_class.new(**params)) }
- let(:params) { {} }
- before(:each) { allow(Setting).to receive(:signal_server_phone_number).and_return('+4915112345678') }
-
- it { should have_css('.OnboardingSignalLink') }
- it { should have_css('strong', text: '015112345678'.phony_formatted(normalize: :DE, spaces: ' ')) }
-end
diff --git a/spec/factories/contributors.rb b/spec/factories/contributors.rb
index 8119cfbe1..89281c56e 100644
--- a/spec/factories/contributors.rb
+++ b/spec/factories/contributors.rb
@@ -39,7 +39,13 @@
after(:build) do |contributor|
contributor.email = nil
contributor.signal_phone_number = Faker::PhoneNumber.cell_phone_in_e164
- contributor.signal_onboarding_completed_at = Time.current
+ end
+ end
+
+ trait :signal_contributor_uuid do
+ after(:build) do |contributor|
+ contributor.email = nil
+ contributor.signal_uuid = Faker::Internet.uuid
end
end
diff --git a/spec/fixtures/files/profile-+491212343434 b/spec/fixtures/files/profile-valid_uuid
similarity index 100%
rename from spec/fixtures/files/profile-+491212343434
rename to spec/fixtures/files/profile-valid_uuid
diff --git a/spec/jobs/signal_adapter/attach_contributors_avatar_job_spec.rb b/spec/jobs/signal_adapter/attach_contributors_avatar_job_spec.rb
index 75883fb92..036d15dca 100644
--- a/spec/jobs/signal_adapter/attach_contributors_avatar_job_spec.rb
+++ b/spec/jobs/signal_adapter/attach_contributors_avatar_job_spec.rb
@@ -4,16 +4,16 @@
RSpec.describe SignalAdapter::AttachContributorsAvatarJob do
describe '#perform_later(contributor)' do
- subject { -> { described_class.new.perform(contributor) } }
- let(:contributor) { create(:contributor, signal_phone_number: '+491212343434') }
+ subject { -> { described_class.new.perform(contributor_id: contributor.id) } }
+ let(:contributor) { create(:contributor, signal_uuid: 'valid_uuid') }
context 'with avatar on file system' do
- let(:avatar) { file_fixture("profile-#{contributor.signal_phone_number}") }
+ let(:avatar) { file_fixture("profile-#{contributor.signal_uuid}") }
before do
- allow(File).to receive(:file?).with("/app/signal-cli-config/avatars/profile-#{contributor.signal_phone_number}").and_return(true)
+ allow(File).to receive(:file?).with("/app/signal-cli-config/avatars/profile-#{contributor.signal_uuid}").and_return(true)
allow(File).to receive(:open).and_call_original
allow(File).to receive(:open)
- .with("/app/signal-cli-config/avatars/profile-#{contributor.signal_phone_number}")
+ .with("/app/signal-cli-config/avatars/profile-#{contributor.signal_uuid}")
.and_return(avatar.open)
end
diff --git a/spec/jobs/signal_adapter/receive_polling_job_spec.rb b/spec/jobs/signal_adapter/receive_polling_job_spec.rb
index 64879bdae..084e72aed 100644
--- a/spec/jobs/signal_adapter/receive_polling_job_spec.rb
+++ b/spec/jobs/signal_adapter/receive_polling_job_spec.rb
@@ -73,55 +73,43 @@
end
end
- describe 'given a message from a contributor with incomplete onboarding' do
- let!(:contributor) { create(:contributor, signal_phone_number: '+4915112345789') }
+ describe 'given a message from a contributor for the first time',
+ vcr: { cassette_name: :receive_signal_message_to_complete_onboarding } do
+ let!(:contributor) { create(:contributor, signal_onboarding_token: signal_onboarding_token) }
+ let(:signal_uuid) { 'valid_uuid' }
+ let(:signal_onboarding_token) { 'CM1TOEC7' }
- before do
- allow(Setting).to receive(:onboarding_success_heading).and_return('Welcome!')
- allow(Setting).to receive(:onboarding_success_text).and_return('')
+ it 'does not create a message' do
+ expect { subject.call }.not_to change(Message, :count)
end
- it { should_not(change { Message.count }) }
-
- it 'sends welcome message' do
- should have_enqueued_job(SignalAdapter::Outbound::Text).with do |text, recipient|
- expect(text).to eq("Welcome!\n")
- expect(recipient.id).to eq(contributor.id)
- end
- end
-
- it 'sets signal_onboarding_completed_at' do
- subject.call
- expect(contributor.reload.signal_onboarding_completed_at).to be_present
+ it 'enqueues a job to create the contact' do
+ expect { subject.call }.to have_enqueued_job(SignalAdapter::CreateContactJob).with(contributor_id: contributor.id)
end
it 'enqueues a job to attach contributors avatar' do
- expect { subject.call }.to have_enqueued_job(SignalAdapter::AttachContributorsAvatarJob).with(contributor)
+ expect { subject.call }.to have_enqueued_job(SignalAdapter::AttachContributorsAvatarJob).with(contributor_id: contributor.id)
end
- end
- describe 'given a message from a contributor with completed onboarding' do
- before do
- create(:contributor, signal_phone_number: '+4915112345789', signal_onboarding_completed_at: Time.zone.now)
- create(:contributor, signal_phone_number: '+4915155555555', signal_onboarding_completed_at: Time.zone.now)
+ it 'is expected to complete the onboarding' do
+ expect { subject.call }.to change { contributor.reload.signal_uuid }.from(nil).to(signal_uuid)
+ .and change {
+ contributor.reload.signal_onboarding_completed_at
+ }.from(nil).to(kind_of(ActiveSupport::TimeWithZone))
end
- it 'is expected to create a message' do
- should(change { Message.count }.from(0).to(1))
+ it 'sends the welcome message' do
+ expect { subject.call }.to have_enqueued_job(SignalAdapter::Outbound::Text).with(
+ contributor_id: contributor.id,
+ text: [Setting.onboarding_success_heading, Setting.onboarding_success_text].join("\n")
+ )
end
-
- it 'is expected to assign the correct contributor' do
- subject.call
- expect(Message.first.contributor.signal_phone_number).to eq('+4915112345789')
- end
-
- it_behaves_like 'an ActivityNotification', 'MessageReceived'
end
describe 'given multiple messages from known and unknown contributors', vcr: { cassette_name: :receive_multiple_signal_messages } do
before do
allow(Sentry).to receive(:capture_exception).with(an_instance_of(SignalAdapter::UnknownContributorError))
- create(:contributor, signal_phone_number: '+4915112345789', signal_onboarding_completed_at: Time.zone.now)
+ create(:contributor, signal_phone_number: '+4915112345789')
end
it 'creates a message for the known contributor' do
@@ -135,7 +123,7 @@
end
describe 'given a message with attachments' do
- let!(:contributor) { create(:contributor, signal_phone_number: '+4915112345678', signal_onboarding_completed_at: Time.zone.now) }
+ let!(:contributor) { create(:contributor, signal_phone_number: '+4915112345678', signal_onboarding_completed_at: 2.weeks.ago) }
before do
allow(File).to receive(:open).and_call_original
@@ -174,7 +162,7 @@
allow(Setting).to receive(:signal_cli_rest_api_endpoint).and_return('http://signal:8080')
end
- let!(:contributor) { create(:contributor, signal_phone_number: '+4915112345789', signal_onboarding_completed_at: Time.zone.now) }
+ let!(:contributor) { create(:contributor, signal_phone_number: '+4915112345789', signal_onboarding_completed_at: 2.weeks.ago) }
it { is_expected.to have_enqueued_job(UnsubscribeContributorJob).with(contributor.id, SignalAdapter::Outbound) }
end
@@ -184,8 +172,8 @@
allow(Setting).to receive(:signal_cli_rest_api_endpoint).and_return('http://signal:8080')
end
let!(:contributor) do
- create(:contributor, signal_phone_number: '+4915112345789', signal_onboarding_completed_at: Time.zone.now,
- unsubscribed_at: 1.week.ago)
+ create(:contributor, signal_phone_number: '+4915112345789', unsubscribed_at: 1.week.ago,
+ signal_onboarding_completed_at: 2.weeks.ago)
end
it { is_expected.to have_enqueued_job(ResubscribeContributorJob).with(contributor.id, SignalAdapter::Outbound) }
diff --git a/spec/models/contributor_spec.rb b/spec/models/contributor_spec.rb
index c0fffa246..3995a90b7 100644
--- a/spec/models/contributor_spec.rb
+++ b/spec/models/contributor_spec.rb
@@ -255,6 +255,16 @@
let(:contributor) { create(:contributor, telegram_id: '123', email: 'contributor@example.org') }
it { should contain_exactly(:telegram, :email) }
end
+
+ describe 'given a contributor with signal_phone_number' do
+ let(:contributor) { create(:contributor, :signal_contributor) }
+ it { should contain_exactly(:signal) }
+ end
+
+ describe 'given a contributor with signal_uuid' do
+ let(:contributor) { create(:contributor, :signal_contributor_uuid) }
+ it { should contain_exactly(:signal) }
+ end
end
describe '#telegram?' do
@@ -514,22 +524,24 @@
end
describe 'given a SignalAdapter::Inbound' do
+ let(:signal_message) do
+ {
+ envelope: {
+ source: '+4912345789',
+ sourceNumber: '+4912345789',
+ sourceDevice: 2,
+ timestamp: 1_626_708_555_697,
+ dataMessage: {
+ timestamp: 1_626_708_555_697,
+ message: 'Hello 100eyes',
+ expiresInSeconds: 0,
+ viewOnce: false
+ }
+ }
+ }
+ end
subject do
lambda do
- signal_message =
- {
- envelope: {
- source: '+4912345789',
- sourceDevice: 2,
- timestamp: 1_626_708_555_697,
- dataMessage: {
- timestamp: 1_626_708_555_697,
- message: 'Hello 100eyes',
- expiresInSeconds: 0,
- viewOnce: false
- }
- }
- }
message_inbound_adapter = SignalAdapter::Inbound.new
message_inbound_adapter.consume(signal_message) do |message|
message.contributor.reply(message_inbound_adapter)
@@ -537,14 +549,9 @@
end
end
- let(:onboarding_completed_at) { Time.zone.now }
let(:phone_number) { '+4912345789' }
let!(:contributor) do
- create(
- :contributor,
- signal_phone_number: phone_number,
- signal_onboarding_completed_at: onboarding_completed_at
- )
+ create(:contributor, signal_phone_number: phone_number)
end
it { should_not raise_error }
@@ -560,6 +567,12 @@
it_behaves_like 'an ActivityNotification', 'MessageReceived'
end
end
+
+ describe 'givena a contributor with signal_uuid' do
+ let!(:contributor) { create(:contributor, signal_uuid: 'valid_uuid') }
+
+ before { signal_message[:envelope][:sourceUuid] = 'valid_uuid' }
+ end
end
end
diff --git a/spec/requests/onboarding/signal_spec.rb b/spec/requests/onboarding/signal_spec.rb
index e699740a9..7b3f6f3c5 100644
--- a/spec/requests/onboarding/signal_spec.rb
+++ b/spec/requests/onboarding/signal_spec.rb
@@ -46,13 +46,14 @@
{
first_name: 'Zora',
last_name: 'Zimmermann',
- signal_phone_number: signal_phone_number,
+ signal_onboarding_token: signal_onboarding_token,
data_processing_consent: data_processing_consent,
additional_consent: additional_consent
}
end
let(:params) { { jwt: jwt, contributor: attrs, context: :contributor_signup } }
+ let(:signal_onboarding_token) { SecureRandom.alphanumeric(8).upcase }
subject { -> { post onboarding_signal_path, params: params } }
@@ -75,6 +76,8 @@
end
describe 'but when a signal server phone number is configured and onboarding has not been disallowed' do
+ let(:welcome_message) { [Setting.onboarding_success_heading, Setting.onboarding_success_text].join("\n") }
+ let(:signal_adapter_outbound_spy) { spy(SignalAdapter::Outbound) }
before do
allow(Setting).to receive(:signal_server_phone_number).and_return('+4491234567890')
allow(Setting).to receive(:signal_onboarding_allowed?).and_return(true)
@@ -87,7 +90,7 @@
expect(contributor).to have_attributes(
first_name: 'Zora',
last_name: 'Zimmermann',
- signal_phone_number: '+4915112345678',
+ signal_onboarding_token: signal_onboarding_token,
data_processing_consent: data_processing_consent,
additional_consent: additional_consent
)
@@ -96,13 +99,9 @@
)
end
- it 'does not send welcome message' do
- should_not enqueue_job(SignalAdapter::Outbound).with(message: Message.new(text: anything), recipient: anything)
- end
-
- it 'redirects to onboarding signal link page' do
+ it 'redirects to success page' do
subject.call
- expect(response).to redirect_to onboarding_signal_link_path
+ expect(response).to redirect_to onboarding_signal_link_path(jwt: nil, signal_onboarding_token: signal_onboarding_token)
end
it 'invalidates the jwt' do
@@ -116,23 +115,6 @@
it_behaves_like 'an ActivityNotification', 'OnboardingCompleted'
end
- context 'given invalid phone number' do
- let(:signal_phone_number) { 'invalid-phone-number' }
-
- it 'displays validation errors' do
- subject.call
- parsed = Capybara::Node::Simple.new(response.body)
- fields = parsed.all('.Field')
- signal_phone_number_field = fields.find { |f| f.has_text? 'Handynummer' }
- expect(signal_phone_number_field).to have_text('ist keine gültige Nummer')
- end
-
- it 'has 422 status code' do
- subject.call
- expect(response).to have_http_status(:unprocessable_entity)
- end
- end
-
context 'without data processing consent' do
let(:data_processing_consent) { false }
@@ -154,26 +136,6 @@
end
end
- describe 'if a contributor exists with the same phone number' do
- let!(:contributor) { create(:contributor, **attrs.merge(json_web_token: create(:json_web_token, invalidated_jwt: :jwt))) }
-
- it 'redirects to success page so that an attacker cannot make a phone number listing' do
- subject.call
- expect(response).to redirect_to onboarding_signal_link_path
- end
-
- it 'invalidates the jwt' do
- expect { subject.call }.to change(JsonWebToken, :count).by(1)
-
- json_web_token = JsonWebToken.where(invalidated_jwt: jwt)
- expect(json_web_token).to exist
- end
-
- it 'does not create new contributor' do
- expect { subject.call }.not_to change(Contributor, :count)
- end
- end
-
context 'without additional consent' do
let(:additional_consent) { false }
@@ -184,7 +146,6 @@
expect(contributor).to have_attributes(
first_name: 'Zora',
last_name: 'Zimmermann',
- signal_phone_number: '+4915112345678',
data_processing_consent: data_processing_consent,
additional_consent: additional_consent
)
diff --git a/spec/system/admin/stats_spec.rb b/spec/system/admin/stats_spec.rb
index b860c3c07..4825c0bc9 100644
--- a/spec/system/admin/stats_spec.rb
+++ b/spec/system/admin/stats_spec.rb
@@ -11,7 +11,8 @@
create_list(:contributor, 3)
create_list(:contributor, 2, :threema_contributor, :skip_validations)
create_list(:contributor, 4, :telegram_contributor)
- create_list(:contributor, 6, :signal_contributor)
+ create_list(:contributor, 2, :signal_contributor)
+ create_list(:contributor, 4, :signal_contributor_uuid)
create_list(:contributor, 12, :whats_app_contributor)
end
diff --git a/spec/system/requests/sending_images_spec.rb b/spec/system/requests/sending_images_spec.rb
index 4936e3ce8..a5ecad454 100644
--- a/spec/system/requests/sending_images_spec.rb
+++ b/spec/system/requests/sending_images_spec.rb
@@ -11,7 +11,7 @@
allow(Request).to receive(:broadcast!).and_call_original
create(:contributor, email: 'adam@example.org')
- create(:contributor, signal_phone_number: '+4912345678', signal_onboarding_completed_at: Time.current)
+ create(:contributor, signal_phone_number: '+4912345678')
create(:contributor, telegram_id: 125_689)
create(:contributor, :skip_validations, threema_id: '12345678')
end
diff --git a/vcr_cassettes/receive_multiple_signal_messages.yml b/vcr_cassettes/receive_multiple_signal_messages.yml
index e1456fa67..129c589e4 100644
--- a/vcr_cassettes/receive_multiple_signal_messages.yml
+++ b/vcr_cassettes/receive_multiple_signal_messages.yml
@@ -29,6 +29,7 @@ http_interactions:
string: '[{
"envelope": {
"source": "+4915100000000",
+ "sourceNumber": "+4915100000000",
"sourceDevice": 1,
"timestamp": 1630589332148,
"dataMessage": {
@@ -42,6 +43,7 @@ http_interactions:
{
"envelope": {
"source": "+4915112345789",
+ "sourceNumber": "+4915112345789",
"sourceDevice": 1,
"timestamp": 1630589338630,
"dataMessage": {
diff --git a/vcr_cassettes/receive_signal_message_to_complete_onboarding.yml b/vcr_cassettes/receive_signal_message_to_complete_onboarding.yml
new file mode 100644
index 000000000..cd331781d
--- /dev/null
+++ b/vcr_cassettes/receive_signal_message_to_complete_onboarding.yml
@@ -0,0 +1,34 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: http://localhost:8080/v1/receive/SIGNAL_SERVER_PHONE_NUMBER
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ Host:
+ - signal:8080
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Content-Type:
+ - text/plain; charset=utf-8
+ Date:
+ - Wed, 26 Jun 2024 10:27:17 GMT
+ Transfer-Encoding:
+ - chunked
+ body:
+ encoding: UTF-8
+ string: '[{"envelope":{"source":"valid_uuid","sourceNumber":null,"sourceUuid":"valid_uuid","sourceName":"Matthew
+ Rider","sourceDevice":1,"timestamp":1719396464361,"dataMessage":{"timestamp":1719396464361,"message":"CM1TOEC7","expiresInSeconds":0,"viewOnce":false}},"account":"+4915888627934"}]'
+ recorded_at: Wed, 26 Jun 2024 10:27:17 GMT
+recorded_with: VCR 6.1.0
diff --git a/vcr_cassettes/receive_signal_messages.yml b/vcr_cassettes/receive_signal_messages.yml
index 547231b85..c86650749 100644
--- a/vcr_cassettes/receive_signal_messages.yml
+++ b/vcr_cassettes/receive_signal_messages.yml
@@ -26,7 +26,7 @@ http_interactions:
- '235'
body:
encoding: UTF-8
- string: '[{"envelope":{"source":"+4915112345789","sourceDevice":2,"timestamp":1626884435591,"dataMessage":{"timestamp":1626884435591,"message":"Hello
+ string: '[{"envelope":{"source":"+4915112345789","sourceNumber":"+4915112345789","sourceUuid":"valid_uuid","sourceDevice":2,"timestamp":1626884435591,"dataMessage":{"timestamp":1626884435591,"message":"Hello
World!","expiresInSeconds":0,"viewOnce":false}}}]'
recorded_at: Wed, 21 Jul 2021 16:20:49 GMT
recorded_with: VCR 6.0.0
diff --git a/vcr_cassettes/receive_signal_messages_containing_unsupported_attachment.yml b/vcr_cassettes/receive_signal_messages_containing_unsupported_attachment.yml
index d1d584a8a..9cde794b4 100644
--- a/vcr_cassettes/receive_signal_messages_containing_unsupported_attachment.yml
+++ b/vcr_cassettes/receive_signal_messages_containing_unsupported_attachment.yml
@@ -29,6 +29,7 @@ http_interactions:
string: '[{
"envelope": {
"source": "+4915112345678",
+ "sourceNumber": "+4915112345678",
"sourceDevice": 2,
"timestamp": 1630790514242,
"dataMessage": {