Compare commits
8 commits
b39542a2ba
...
d118d185e2
| Author | SHA1 | Date | |
|---|---|---|---|
| d118d185e2 | |||
| 7515527555 | |||
| 75418339da | |||
| 9295ae75ad | |||
| 01f9065dbd | |||
| 5631b02157 | |||
| 9fe44e3f91 | |||
| 684dcb53ba |
20 changed files with 96 additions and 49 deletions
1
Gemfile
1
Gemfile
|
|
@ -20,6 +20,7 @@ gem 'sass-rails', '~> 6.0'
|
||||||
gem 'terser', '~> 1.1', '>= 1.1.17'
|
gem 'terser', '~> 1.1', '>= 1.1.17'
|
||||||
gem 'react-rails', '~> 2.7', '>= 2.7.1'
|
gem 'react-rails', '~> 2.7', '>= 2.7.1'
|
||||||
gem 'jsbundling-rails', '~> 1.1'
|
gem 'jsbundling-rails', '~> 1.1'
|
||||||
|
gem 'turbo-rails', '~> 2.0'
|
||||||
|
|
||||||
# For authentication.
|
# For authentication.
|
||||||
gem 'devise', '~> 4.9', '>= 4.9.2'
|
gem 'devise', '~> 4.9', '>= 4.9.2'
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,10 @@ GEM
|
||||||
timeout (0.4.1)
|
timeout (0.4.1)
|
||||||
timers (4.3.5)
|
timers (4.3.5)
|
||||||
traces (0.11.1)
|
traces (0.11.1)
|
||||||
|
turbo-rails (2.0.5)
|
||||||
|
actionpack (>= 6.0.0)
|
||||||
|
activejob (>= 6.0.0)
|
||||||
|
railties (>= 6.0.0)
|
||||||
tzinfo (2.0.6)
|
tzinfo (2.0.6)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
warden (1.2.9)
|
warden (1.2.9)
|
||||||
|
|
@ -396,6 +400,7 @@ DEPENDENCIES
|
||||||
stackprof (~> 0.2.25)
|
stackprof (~> 0.2.25)
|
||||||
terser (~> 1.1, >= 1.1.17)
|
terser (~> 1.1, >= 1.1.17)
|
||||||
thread-local (~> 1.1)
|
thread-local (~> 1.1)
|
||||||
|
turbo-rails (~> 2.0)
|
||||||
web-console (~> 4.2)
|
web-console (~> 4.2)
|
||||||
will_paginate (~> 4.0)
|
will_paginate (~> 4.0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,24 +49,27 @@ class OutfitsController < ApplicationController
|
||||||
def new
|
def new
|
||||||
@colors = Color.funny.alphabetical
|
@colors = Color.funny.alphabetical
|
||||||
@species = Species.alphabetical
|
@species = Species.alphabetical
|
||||||
|
|
||||||
newest_items = Item.newest.
|
|
||||||
select(:id, :name, :updated_at, :thumbnail_url, :rarity_index, :is_manually_nc)
|
|
||||||
.limit(18)
|
|
||||||
@newest_modeled_items, @newest_unmodeled_items =
|
|
||||||
newest_items.partition(&:predicted_fully_modeled?)
|
|
||||||
|
|
||||||
@newest_unmodeled_items_predicted_missing_species_by_color = {}
|
# HACK: Skip this in development, because it's slow!
|
||||||
@newest_unmodeled_items_predicted_modeled_ratio = {}
|
unless Rails.env.development?
|
||||||
@newest_unmodeled_items.each do |item|
|
newest_items = Item.newest.
|
||||||
h = item.predicted_missing_nonstandard_body_ids_by_species_by_color
|
select(:id, :name, :updated_at, :thumbnail_url, :rarity_index, :is_manually_nc)
|
||||||
standard_body_ids_by_species = item.
|
.limit(18)
|
||||||
predicted_missing_standard_body_ids_by_species
|
@newest_modeled_items, @newest_unmodeled_items =
|
||||||
if standard_body_ids_by_species.present?
|
newest_items.partition(&:predicted_fully_modeled?)
|
||||||
h[:standard] = standard_body_ids_by_species
|
|
||||||
|
@newest_unmodeled_items_predicted_missing_species_by_color = {}
|
||||||
|
@newest_unmodeled_items_predicted_modeled_ratio = {}
|
||||||
|
@newest_unmodeled_items.each do |item|
|
||||||
|
h = item.predicted_missing_nonstandard_body_ids_by_species_by_color
|
||||||
|
standard_body_ids_by_species = item.
|
||||||
|
predicted_missing_standard_body_ids_by_species
|
||||||
|
if standard_body_ids_by_species.present?
|
||||||
|
h[:standard] = standard_body_ids_by_species
|
||||||
|
end
|
||||||
|
@newest_unmodeled_items_predicted_missing_species_by_color[item] = h
|
||||||
|
@newest_unmodeled_items_predicted_modeled_ratio[item] = item.predicted_modeled_ratio
|
||||||
end
|
end
|
||||||
@newest_unmodeled_items_predicted_missing_species_by_color[item] = h
|
|
||||||
@newest_unmodeled_items_predicted_modeled_ratio[item] = item.predicted_modeled_ratio
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@species_count = Species.count
|
@species_count = Species.count
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,4 @@
|
||||||
module ClosetListsHelper
|
module ClosetListsHelper
|
||||||
def closet_list_delete_confirmation(closet_list)
|
|
||||||
ownership_key = closet_list.hangers_owned? ? 'owned' : 'wanted'
|
|
||||||
translate("closet_lists.closet_list.delete_confirmation.#{ownership_key}",
|
|
||||||
:list_name => closet_list.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def closet_list_description_format(list)
|
def closet_list_description_format(list)
|
||||||
md = RDiscount.new(list.description)
|
md = RDiscount.new(list.description)
|
||||||
Sanitize.clean(md.to_html, Sanitize::Config::BASIC).html_safe
|
Sanitize.clean(md.to_html, Sanitize::Config::BASIC).html_safe
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
require "addressable/template"
|
||||||
|
|
||||||
module ItemsHelper
|
module ItemsHelper
|
||||||
JNItemsURLFormat = 'https://items.jellyneo.net/search/?name=%s&name_type=3'
|
JNItemsURLFormat = 'https://items.jellyneo.net/search/?name=%s&name_type=3'
|
||||||
|
|
||||||
|
|
@ -75,6 +77,13 @@ module ItemsHelper
|
||||||
def jn_items_url_for(item)
|
def jn_items_url_for(item)
|
||||||
sprintf(JNItemsURLFormat, CGI::escape(item.name))
|
sprintf(JNItemsURLFormat, CGI::escape(item.name))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
IMPRESS_2020_ITEM_URL_TEMPLATE = Addressable::Template.new(
|
||||||
|
"#{Rails.configuration.impress_2020_origin}/items/{id}"
|
||||||
|
)
|
||||||
|
def impress_2020_url_for(item)
|
||||||
|
IMPRESS_2020_ITEM_URL_TEMPLATE.expand(id: item.id).to_s
|
||||||
|
end
|
||||||
|
|
||||||
def shop_wizard_url_for(item)
|
def shop_wizard_url_for(item)
|
||||||
"https://www.neopets.com/market.phtml?type=wizard&string=#{CGI::escape item.name}"
|
"https://www.neopets.com/market.phtml?type=wizard&string=#{CGI::escape item.name}"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import "@hotwired/turbo-rails";
|
||||||
|
|
||||||
document.getElementById("locale").addEventListener("change", function () {
|
document.getElementById("locale").addEventListener("change", function () {
|
||||||
document.getElementById("locale-form").submit();
|
document.getElementById("locale-form").submit();
|
||||||
});
|
});
|
||||||
|
|
@ -19,9 +19,16 @@
|
||||||
existing Neopets account**, instead of creating a new DTI username and
|
existing Neopets account**, instead of creating a new DTI username and
|
||||||
password. Existing DTI users can also link accounts if they want, too!
|
password. Existing DTI users can also link accounts if they want, too!
|
||||||
|
|
||||||
We're also keeping in mind that a _lot_ of the pain points in using DTI right
|
**All of this functionality is optional, and removable at any time!**
|
||||||
now have to do with transferring stuff between Neopets and DTI. It's possible
|
Usernames and passwords will still work as before—and unlike official
|
||||||
that this could set us up for other smoother experiences in the future, too!
|
Neopets accounts that need long-term permanent linkage, we intend to offer
|
||||||
|
both linking and unlinking, so you can always have options.
|
||||||
|
|
||||||
|
We also know that a _lot_ of the pain points in Neopets and DTI right now come
|
||||||
|
from transferring info between our sites by hand. **It's possible this could
|
||||||
|
set us up for other smoother experiences in the future, too!** (Nothing like
|
||||||
|
that in the first release though—we've just been chatting with TNT about what
|
||||||
|
might come next!)
|
||||||
|
|
||||||
## Links to NC Mall
|
## Links to NC Mall
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@
|
||||||
.closet-list-controls
|
.closet-list-controls
|
||||||
= link_to t('.edit'), edit_user_closet_list_path(closet_list.user_id, closet_list)
|
= link_to t('.edit'), edit_user_closet_list_path(closet_list.user_id, closet_list)
|
||||||
= form_tag user_closet_list_path(closet_list.user_id, closet_list), :method => 'delete' do
|
= form_tag user_closet_list_path(closet_list.user_id, closet_list), :method => 'delete' do
|
||||||
= submit_tag t('.delete'), :confirm => closet_list_delete_confirmation(closet_list)
|
= submit_tag t('.delete'),
|
||||||
|
data: {turbo_confirm: t('.delete_confirmation', list_name: closet_list.name)}
|
||||||
= form_tag user_closet_hangers_path(@user), method: :delete, class: 'remove-all' do
|
= form_tag user_closet_hangers_path(@user), method: :delete, class: 'remove-all' do
|
||||||
= hidden_field_tag :list_id, closet_list.id
|
= hidden_field_tag :list_id, closet_list.id
|
||||||
= submit_tag t('.remove_all.submit'), confirm: t('.remove_all.confirm')
|
= submit_tag t('.remove_all.submit'),
|
||||||
|
data: {turbo_confirm: t('.remove_all.confirm')}
|
||||||
%button.select-all= t('.select_all')
|
%button.select-all= t('.select_all')
|
||||||
%h4= closet_list.name
|
%h4= closet_list.name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
}= time_with_only_month_if_old item.created_at
|
}= time_with_only_month_if_old item.created_at
|
||||||
|
|
||||||
= link_to t('items.show.resources.jn_items'), jn_items_url_for(item)
|
= link_to t('items.show.resources.jn_items'), jn_items_url_for(item)
|
||||||
|
= link_to t('items.show.resources.impress_2020'), impress_2020_url_for(item)
|
||||||
- if item.nc_trade_value
|
- if item.nc_trade_value
|
||||||
= link_to t('items.show.resources.owls', value: item.nc_trade_value.value_text),
|
= link_to t('items.show.resources.owls', value: item.nc_trade_value.value_text),
|
||||||
"https://www.neopets.com/~owls",
|
"https://www.neopets.com/~owls",
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
= signed_in_meta_tag
|
= signed_in_meta_tag
|
||||||
- if user_signed_in?
|
- if user_signed_in?
|
||||||
= current_user_id_meta_tag
|
= current_user_id_meta_tag
|
||||||
|
= yield :head
|
||||||
%body{:class => body_class}
|
%body{:class => body_class}
|
||||||
#container
|
#container
|
||||||
= yield :before_title
|
= yield :before_title
|
||||||
|
|
@ -50,7 +51,8 @@
|
||||||
= button_to t('.userbar.logout'), destroy_auth_user_session_path, method: :delete,
|
= button_to t('.userbar.logout'), destroy_auth_user_session_path, method: :delete,
|
||||||
params: {return_to: request.fullpath}
|
params: {return_to: request.fullpath}
|
||||||
- else
|
- else
|
||||||
= link_to auth_user_sign_in_path_with_return_to, :id => 'userbar-log-in' do
|
= link_to auth_user_sign_in_path_with_return_to,
|
||||||
|
id: 'userbar-log-in', "data-turbo-prefetch": false do
|
||||||
%span= t('.userbar.login')
|
%span= t('.userbar.login')
|
||||||
|
|
||||||
#footer
|
#footer
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,10 @@
|
||||||
|
|
||||||
%header
|
%header
|
||||||
.outfit-star
|
.outfit-star
|
||||||
= link_to outfit.name, outfit, :class => 'outfit-name'
|
= link_to outfit.name, outfit, class: 'outfit-name'
|
||||||
|
|
||||||
%footer
|
%footer
|
||||||
= link_to t('.edit'), outfit, :class => 'outfit-edit-link'
|
= link_to t('.edit'), outfit, class: 'outfit-edit-link'
|
||||||
= button_to t('.delete'), outfit, :method => 'delete',
|
= button_to t('.delete'), outfit, method: 'delete',
|
||||||
:class => 'outfit-delete-button',
|
class: 'outfit-delete-button',
|
||||||
:confirm => t('.delete_confirmation',
|
data: {turbo_confirm: t('.delete_confirmation', outfit_name: outfit.name)}
|
||||||
:outfit_name => outfit.name)
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
- turbo_page_requires_reload
|
||||||
|
|
||||||
- if @outfit
|
- if @outfit
|
||||||
- title(@outfit.name || t('.default_outfit_name'))
|
- title(@outfit.name || t('.default_outfit_name'))
|
||||||
- open_graph type: 'openneo-impress:outfit', title: yield(:title),
|
- open_graph type: 'openneo-impress:outfit', title: yield(:title),
|
||||||
|
|
@ -22,5 +24,6 @@
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
= impress_2020_meta_tags
|
= impress_2020_meta_tags
|
||||||
%meta{name: 'dti-current-user-id', content: user_signed_in? ? current_user.id : "null"}
|
%meta{name: 'dti-current-user-id', content: user_signed_in? ? current_user.id : "null"}
|
||||||
|
= yield :head
|
||||||
%body
|
%body
|
||||||
#wardrobe-2020-root
|
#wardrobe-2020-root
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ require "rails"
|
||||||
# Disabled:
|
# Disabled:
|
||||||
# - active_storage/engine
|
# - active_storage/engine
|
||||||
# - active_job/railtie
|
# - active_job/railtie
|
||||||
# - action_cable/engine
|
|
||||||
# - action_mailbox/engine
|
# - action_mailbox/engine
|
||||||
# - action_text/engine
|
# - action_text/engine
|
||||||
%w(
|
%w(
|
||||||
active_record/railtie
|
active_record/railtie
|
||||||
|
action_cable/engine
|
||||||
action_controller/railtie
|
action_controller/railtie
|
||||||
action_view/railtie
|
action_view/railtie
|
||||||
action_mailer/railtie
|
action_mailer/railtie
|
||||||
|
|
|
||||||
|
|
@ -157,12 +157,8 @@ en-MEEP:
|
||||||
edit: Meepit
|
edit: Meepit
|
||||||
delete: Deleep
|
delete: Deleep
|
||||||
delete_confirmation:
|
delete_confirmation:
|
||||||
owned:
|
Are you sure you want to deleep "%{list_name}"? If you do, we'll deleep
|
||||||
Are you sure you want to deleep "%{list_name}"? Even if you do, we'll
|
all the items in it, too.
|
||||||
remember that you own these items.
|
|
||||||
wanted:
|
|
||||||
Are you sure you want to deleep "%{list_name}"? Even if you do, we'll
|
|
||||||
remember that you want these items.
|
|
||||||
empty: This meep is empty.
|
empty: This meep is empty.
|
||||||
|
|
||||||
edit:
|
edit:
|
||||||
|
|
|
||||||
|
|
@ -169,10 +169,8 @@ en:
|
||||||
edit: Edit
|
edit: Edit
|
||||||
delete: Delete
|
delete: Delete
|
||||||
delete_confirmation:
|
delete_confirmation:
|
||||||
owned: Are you sure you want to delete "%{list_name}"?
|
Are you sure you want to delete "%{list_name}"?
|
||||||
If you do, we'll move these items into Items You Own, not in a list.
|
If you do, we'll delete all the items in it, too.
|
||||||
wanted: Are you sure you want to delete "%{list_name}"?
|
|
||||||
If you do, we'll move these items into Items You Want, not in a list.
|
|
||||||
remove_all:
|
remove_all:
|
||||||
confirm: "Remove all items from this list?"
|
confirm: "Remove all items from this list?"
|
||||||
submit: Remove all
|
submit: Remove all
|
||||||
|
|
@ -311,6 +309,7 @@ en:
|
||||||
description: Only obtainable via paintbrush
|
description: Only obtainable via paintbrush
|
||||||
resources:
|
resources:
|
||||||
jn_items: JN Items
|
jn_items: JN Items
|
||||||
|
impress_2020: DTI 2020
|
||||||
owls: "Owls: %{value}"
|
owls: "Owls: %{value}"
|
||||||
shop_wizard: Shop Wizard
|
shop_wizard: Shop Wizard
|
||||||
super_shop_wizard: Super Wizard
|
super_shop_wizard: Super Wizard
|
||||||
|
|
|
||||||
|
|
@ -117,8 +117,7 @@ es:
|
||||||
edit: Editar
|
edit: Editar
|
||||||
delete: Eliminar
|
delete: Eliminar
|
||||||
delete_confirmation:
|
delete_confirmation:
|
||||||
owned: ¿Estás seguro/a que quieres eliminar la lista "%{list_name}"? Recuerda que si eliminas la lista seguirás teniendo estos objetos.
|
¿Estás seguro/a que quieres eliminar la lista "%{list_name}"?
|
||||||
wanted: ¿Estás seguro/a que quieres eliminar la lista "%{list_name}"? Recuerda que si eliminas la lista seguirás queriendo estos objetos.
|
|
||||||
empty: Esta lista está vacía.
|
empty: Esta lista está vacía.
|
||||||
edit:
|
edit:
|
||||||
title: Editando la lista "%{list_name}"
|
title: Editando la lista "%{list_name}"
|
||||||
|
|
|
||||||
|
|
@ -117,8 +117,7 @@ pt:
|
||||||
edit: Editar
|
edit: Editar
|
||||||
delete: Excluir
|
delete: Excluir
|
||||||
delete_confirmation:
|
delete_confirmation:
|
||||||
owned: Você tem certeza que deseja excluir "%{list_name}"? Mesmo se você fizer isso, vamos lembrar que você possui esses itens.
|
Você tem certeza que deseja excluir "%{list_name}"?
|
||||||
wanted: Você tem certeza que deseja excluir "%{list_name}"? Mesmo se você fizer isso, vamos lembrar que você procura esses itens.
|
|
||||||
empty: Esta lista está vazia.
|
empty: Esta lista está vazia.
|
||||||
edit:
|
edit:
|
||||||
title: Editando lista "%{list_name}"
|
title: Editando lista "%{list_name}"
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
"@chakra-ui/react": "^1.6.0",
|
"@chakra-ui/react": "^1.6.0",
|
||||||
"@emotion/react": "^11.1.4",
|
"@emotion/react": "^11.1.4",
|
||||||
"@emotion/styled": "^11.0.0",
|
"@emotion/styled": "^11.0.0",
|
||||||
|
"@hotwired/turbo-rails": "^8.0.4",
|
||||||
"@loadable/component": "^5.12.0",
|
"@loadable/component": "^5.12.0",
|
||||||
"@sentry/react": "^5.30.0",
|
"@sentry/react": "^5.30.0",
|
||||||
"@sentry/tracing": "^5.30.0",
|
"@sentry/tracing": "^5.30.0",
|
||||||
|
|
|
||||||
BIN
vendor/cache/turbo-rails-2.0.5.gem
vendored
Normal file
BIN
vendor/cache/turbo-rails-2.0.5.gem
vendored
Normal file
Binary file not shown.
25
yarn.lock
25
yarn.lock
|
|
@ -1339,6 +1339,23 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@hotwired/turbo-rails@npm:^8.0.4":
|
||||||
|
version: 8.0.4
|
||||||
|
resolution: "@hotwired/turbo-rails@npm:8.0.4"
|
||||||
|
dependencies:
|
||||||
|
"@hotwired/turbo": "npm:^8.0.4"
|
||||||
|
"@rails/actioncable": "npm:^7.0"
|
||||||
|
checksum: c35fdcc79876f3ceaed7100f2e6965bcf9aa647309dce7a6ed685e880ffc1ac475299e00538ecc926addfa4023704c9bd1ea37e70fbef3a77697f7f01d4e344f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@hotwired/turbo@npm:^8.0.4":
|
||||||
|
version: 8.0.4
|
||||||
|
resolution: "@hotwired/turbo@npm:8.0.4"
|
||||||
|
checksum: 3e7174d550adf3b9a0a4c45ff5d1b71d47c20de6ae01f646fbbaf8ed447677bd1a5fb6dbd46e95b14645a663fe58a6187c1c6d2a688b0981b5cf437379c5e00a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@humanwhocodes/config-array@npm:^0.11.13":
|
"@humanwhocodes/config-array@npm:^0.11.13":
|
||||||
version: 0.11.13
|
version: 0.11.13
|
||||||
resolution: "@humanwhocodes/config-array@npm:0.11.13"
|
resolution: "@humanwhocodes/config-array@npm:0.11.13"
|
||||||
|
|
@ -1411,6 +1428,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@rails/actioncable@npm:^7.0":
|
||||||
|
version: 7.1.3
|
||||||
|
resolution: "@rails/actioncable@npm:7.1.3"
|
||||||
|
checksum: 6019097498387a9c0684df0be380182820a0480173e05a5c5a830cef6cf3e40c9ec75b834af0396b0f57b4e658891c820163e84b9f2bd1ac293c90f5a12ce488
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@reach/alert@npm:0.13.2":
|
"@reach/alert@npm:0.13.2":
|
||||||
version: 0.13.2
|
version: 0.13.2
|
||||||
resolution: "@reach/alert@npm:0.13.2"
|
resolution: "@reach/alert@npm:0.13.2"
|
||||||
|
|
@ -3177,6 +3201,7 @@ __metadata:
|
||||||
"@chakra-ui/react": "npm:^1.6.0"
|
"@chakra-ui/react": "npm:^1.6.0"
|
||||||
"@emotion/react": "npm:^11.1.4"
|
"@emotion/react": "npm:^11.1.4"
|
||||||
"@emotion/styled": "npm:^11.0.0"
|
"@emotion/styled": "npm:^11.0.0"
|
||||||
|
"@hotwired/turbo-rails": "npm:^8.0.4"
|
||||||
"@loadable/component": "npm:^5.12.0"
|
"@loadable/component": "npm:^5.12.0"
|
||||||
"@sentry/react": "npm:^5.30.0"
|
"@sentry/react": "npm:^5.30.0"
|
||||||
"@sentry/tracing": "npm:^5.30.0"
|
"@sentry/tracing": "npm:^5.30.0"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue