diff --git a/.buildpacks b/.buildpacks
deleted file mode 100644
index 31dd570966..0000000000
--- a/.buildpacks
+++ /dev/null
@@ -1 +0,0 @@
-https://github.com/hashnuke/heroku-buildpack-elixir
diff --git a/.dockerignore b/.dockerignore
index 6b1879e629..cc92e70895 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -9,3 +9,65 @@ test/
# Required to get version
!.git
+
+# App artifacts
+/_build
+/db
+/deps
+/*.ez
+/test/instance
+/test/uploads
+/.elixir_ls
+/test/fixtures/DSCN0010_tmp.jpg
+/test/fixtures/test_tmp.txt
+/test/fixtures/image_tmp.jpg
+/test/tmp/
+/test/frontend_static_test/
+/doc
+/instance
+/priv/ssh_keys
+
+# Prevent committing custom emojis
+/priv/static/emoji/custom/*
+
+# Generated on crash by the VM
+erl_crash.dump
+
+# Files matching config/*.secret.exs pattern contain sensitive
+# data and you should not commit them into version control.
+#
+# Alternatively, you may comment the line below and commit the
+# secrets files as long as you replace their contents by environment
+# variables.
+/config/*.secret.exs
+/config/generated_config.exs
+/config/runtime.exs
+/config/*.env
+
+
+# Database setup file, some may forget to delete it
+/config/setup_db*.psql
+
+# Whitelist Landing FE
+!/instance/static/frontends/landing-fe/vendor/**
+
+.DS_Store
+.env
+
+# Editor config
+/.vscode/
+
+# Prevent committing docs files
+/priv/static/doc/*
+docs/generated_config.md
+
+# Code test coverage
+/cover
+/Elixir.*.coverdata
+
+.idea
+pleroma.iml
+
+# Editor temp files
+/*~
+/*#
diff --git a/.gitignore b/.gitignore
index 1ec9dd1574..71af612544 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,9 +36,6 @@ erl_crash.dump
# Database setup file, some may forget to delete it
/config/setup_db*.psql
-# Whitelist Landing FE
-!/instance/static/frontends/landing-fe/vendor/**
-
.DS_Store
.env
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 582e283cca..85beaa5837 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,6 +6,9 @@ variables: &global_variables
POSTGRES_PASSWORD: postgres
DB_HOST: postgres
MIX_ENV: test
+ # Needed for Dokku deployment.
+ # https://github.com/dokku/dokku/issues/2514#issuecomment-616775470
+ GIT_DEPTH: 0
cache: &global_cache_policy
key:
@@ -88,7 +91,6 @@ unit-testing:
unit-testing-erratic:
stage: test
- retry: 2
allow_failure: true
only:
changes: *build_changes_policy
@@ -187,34 +189,27 @@ docs-deploy:
- apk add curl
script:
- curl -X POST -F"token=$DOCS_PIPELINE_TRIGGER" -F'ref=master' -F"variables[BRANCH]=$CI_COMMIT_REF_NAME" https://git.pleroma.social/api/v4/projects/673/trigger/pipeline
+
+# Deploy with Dokku
+# https://github.com/dokku/gitlab-ci
+# https://github.com/dokku/ci-docker-image
review_app:
- image: alpine:3.9
+ image: dokku/ci-docker-image
stage: deploy
- before_script:
- - apk update && apk add openssh-client git
- when: manual
environment:
name: review/$CI_COMMIT_REF_NAME
- url: https://$CI_ENVIRONMENT_SLUG.pleroma.online/
- on_stop: stop_review_app
+ url: https://$CI_ENVIRONMENT_SLUG.dokku.soapbox.pub
+ # on_stop: stop_review_app
only:
- branches
except:
- - master
- develop
- script:
- - echo "$CI_ENVIRONMENT_SLUG"
- - mkdir -p ~/.ssh
- - eval $(ssh-agent -s)
- - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- - ssh-keyscan -H "pleroma.online" >> ~/.ssh/known_hosts
- - (ssh -t dokku@pleroma.online -- apps:create "$CI_ENVIRONMENT_SLUG") || true
- - (ssh -t dokku@pleroma.online -- git:set "$CI_ENVIRONMENT_SLUG" keep-git-dir true) || true
- - ssh -t dokku@pleroma.online -- config:set "$CI_ENVIRONMENT_SLUG" APP_NAME="$CI_ENVIRONMENT_SLUG" APP_HOST="$CI_ENVIRONMENT_SLUG.pleroma.online" MIX_ENV=dokku
- - (ssh -t dokku@pleroma.online -- postgres:create $(echo $CI_ENVIRONMENT_SLUG | sed -e 's/-/_/g')_db) || true
- - (ssh -t dokku@pleroma.online -- postgres:link $(echo $CI_ENVIRONMENT_SLUG | sed -e 's/-/_/g')_db "$CI_ENVIRONMENT_SLUG") || true
- - (ssh -t dokku@pleroma.online -- certs:add "$CI_ENVIRONMENT_SLUG" /home/dokku/server.crt /home/dokku/server.key) || true
- - git push -f dokku@pleroma.online:$CI_ENVIRONMENT_SLUG $CI_COMMIT_SHA:refs/heads/master
+ variables:
+ GIT_REMOTE_URL: ssh://dokku@$DOKKU_HOST/$CI_ENVIRONMENT_SLUG
+ script: dokku-deploy
+ after_script: [dokku-unlock]
+ before_script: []
+ allow_failure: true
spec-deploy:
stage: deploy
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2ed9bbadf..8d0ef4e113 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- Allow users to remove their emails if instance does not need email to register
- Uploadfilter `Pleroma.Upload.Filter.Exiftool` has been renamed to `Pleroma.Upload.Filter.Exiftool.StripLocation`
+- Updated the recommended pleroma.vcl configuration for Varnish to target Varnish 7.0+
### Added
- `activeMonth` and `activeHalfyear` fields in NodeInfo usage.users object
@@ -48,6 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fixed crash when pinned_objects is nil
- Fixed slow timelines when there are a lot of deactivated users
- Fixed account deletion API
+- Fixed lowercase HTTP HEAD method in the Media Proxy Preview code
### Removed
diff --git a/Dockerfile b/Dockerfile
index 8c48980ba1..3a662796e9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,8 @@
FROM ubuntu:22.04 as build
-ENV MIX_ENV=prod
+ARG MIX_ENV=prod \
+ OAUTH_CONSUMER_STRATEGIES="twitter facebook google microsoft slack github keycloak:ueberauth_keycloak_strategy"
+
WORKDIR /src
RUN apt-get update &&\
@@ -24,8 +26,8 @@ ARG DEBIAN_FRONTEND="noninteractive"
ENV TZ="Etc/UTC"
LABEL maintainer="hello@soapbox.pub" \
- org.opencontainers.image.title="soapbox-be" \
- org.opencontainers.image.description="Soapbox BE for Docker" \
+ org.opencontainers.image.title="rebased" \
+ org.opencontainers.image.description="Rebased" \
org.opencontainers.image.authors="hello@soapbox.pub" \
org.opencontainers.image.vendor="soapbox.pub" \
org.opencontainers.image.documentation="https://gitlab.com/soapbox-pub/soapbox-be" \
@@ -53,6 +55,4 @@ COPY --from=build --chown=pleroma:0 /src/release ${HOME}
COPY ./config/docker.exs /etc/pleroma/config.exs
COPY ./docker-entrypoint.sh ${HOME}
-EXPOSE 4000
-
ENTRYPOINT ["/opt/pleroma/docker-entrypoint.sh"]
diff --git a/README.md b/README.md
index 2d33e68c9f..82d42a09ce 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,16 @@
-# Soapbox BE
+# Rebased
-![Soapbox BE](https://gitlab.com/soapbox-pub/soapbox-be/uploads/288bc05ba65e60970ffddd37d58f7c21/be-1-0-thumb.png)
+![Rebased](rebased.png)
-**Soapbox BE** is the preferred backend for Soapbox.
-It is based on [Pleroma](https://pleroma.social/).
+**Rebased** is a Fediverse backend written in Elixir.
+It's compatible with the Mastodon API and is the recommended backend for Soapbox.
## Your social media server
-Soapbox empowers people to take control of their social media experience.
+Rebased empowers people to take control of their social media experience.
Hosting your own server means that *you* get to decide the rules.
-Soapbox connects to over 4,000 other servers on the Fediverse.
+Rebased connects to over 4,000 other servers on the Fediverse.
It is designed to spread your message far and wide, while being resilient to deplatforming.
## Installation
@@ -19,15 +19,15 @@ See [the installation guide](https://soapbox.pub/install/).
## License
-Soapbox is free software: you can redistribute it and/or modify
+Rebased is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-Soapbox is distributed in the hope that it will be useful,
+Rebased is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
-along with Soapbox. If not, see .
+along with Rebased. If not, see .
diff --git a/app.json b/app.json
new file mode 100644
index 0000000000..b0b28b9db4
--- /dev/null
+++ b/app.json
@@ -0,0 +1,13 @@
+{
+ "name": "Rebased",
+ "description": "Rebased, the recommended backend for Soapbox written in Elixir.",
+ "keywords": [
+ "fediverse"
+ ],
+ "website": "https://soapbox.pub",
+ "dokku": {
+ "plugins": [
+ "postgres"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/config/config.exs b/config/config.exs
index 2d2b62f378..321ea40d0d 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -189,7 +189,7 @@
description: "Pleroma: An efficient and flexible fediverse server",
short_description: "",
background_image: "/images/city.jpg",
- instance_thumbnail: "/instance/thumbnail.jpeg",
+ instance_thumbnail: "/instance/thumbnail.png",
limit: 5_000,
description_limit: 5_000,
remote_limit: 100_000,
@@ -629,7 +629,14 @@
for strategy <- oauth_consumer_strategies do
strategy_module_name = "Elixir.Ueberauth.Strategy.#{String.capitalize(strategy)}"
strategy_module = String.to_atom(strategy_module_name)
- {String.to_atom(strategy), {strategy_module, [callback_params: ["state"]]}}
+
+ params =
+ case strategy do
+ "keycloak" -> [uid_field: :email, default_scope: "openid profile"]
+ _ -> [callback_params: ["state"]]
+ end
+
+ {String.to_atom(strategy), {strategy_module, params}}
end
config :ueberauth,
@@ -752,7 +759,7 @@
"name" => "fedi-fe",
"git" => "https://git.pleroma.social/pleroma/fedi-fe",
"build_url" =>
- "https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build",
+ "https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build_release",
"ref" => "master",
"custom-http-headers" => [
{"service-worker-allowed", "/"}
@@ -772,6 +779,14 @@
"https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/${ref}/download?job=build-production",
"ref" => "develop",
"build_dir" => "static"
+ },
+ "glitch-lily" => %{
+ "name" => "glitch-lily",
+ "git" => "https://lily-is.land/infra/glitch-lily",
+ "build_url" =>
+ "https://lily-is.land/infra/glitch-lily/-/jobs/artifacts/${ref}/download?job=build",
+ "ref" => "servant",
+ "build_dir" => "public"
}
}
diff --git a/config/docker.exs b/config/docker.exs
index f9f27d1415..4d9c05e5b5 100644
--- a/config/docker.exs
+++ b/config/docker.exs
@@ -2,23 +2,28 @@
config :pleroma, Pleroma.Web.Endpoint,
url: [host: System.get_env("DOMAIN", "localhost"), scheme: "https", port: 443],
- http: [ip: {0, 0, 0, 0}, port: 4000]
+ http: [ip: {0, 0, 0, 0}, port: System.get_env("PORT", "5000")]
config :pleroma, :instance,
- name: System.get_env("INSTANCE_NAME", "Pleroma"),
+ name: System.get_env("INSTANCE_NAME", "Soapbox"),
email: System.get_env("ADMIN_EMAIL"),
notify_email: System.get_env("NOTIFY_EMAIL"),
limit: 5000,
registrations_open: false,
healthcheck: true
-config :pleroma, Pleroma.Repo,
- adapter: Ecto.Adapters.Postgres,
- username: System.get_env("DB_USER", "pleroma"),
- password: System.fetch_env!("DB_PASS"),
- database: System.get_env("DB_NAME", "pleroma"),
- hostname: System.get_env("DB_HOST", "db"),
- pool_size: 10
+# Prefer `DATABASE_URL` if set, otherwise use granular env.
+case System.get_env("DATABASE_URL") do
+ database_url when is_binary(database_url) ->
+ config :pleroma, Pleroma.Repo, url: database_url
+
+ _ ->
+ config :pleroma, Pleroma.Repo,
+ username: System.get_env("DB_USER", "postgres"),
+ password: System.get_env("DB_PASS", "postgres"),
+ database: System.get_env("DB_NAME", "postgres"),
+ hostname: System.get_env("DB_HOST", "db")
+end
# Configure web push notifications
config :web_push_encryption, :vapid_details, subject: "mailto:#{System.get_env("NOTIFY_EMAIL")}"
diff --git a/config/soapbox.exs b/config/soapbox.exs
index b12646c3f9..3006747cff 100644
--- a/config/soapbox.exs
+++ b/config/soapbox.exs
@@ -6,9 +6,6 @@
# Twitter-like block behavior
config :pleroma, :activitypub, blockers_visible: false
-# Set the default frontend to an instructions page
-config :pleroma, :frontends, primary: %{"name" => "landing-fe", "ref" => "vendor"}
-
# Sane default upload filters
config :pleroma, Pleroma.Upload,
filters: [
@@ -37,6 +34,9 @@
# Allow privileged staff
config :pleroma, :instance, privileged_staff: true
+# Enable instance favicons
+config :pleroma, :instances_favicons, enabled: true
+
# Hellthread limits
config :pleroma, :mrf_hellthread,
delist_threshold: 15,
diff --git a/config/test.exs b/config/test.exs
index 255f6a1785..9cbf8c2747 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -122,6 +122,8 @@
config :pleroma, :mrf, policies: []
+config :pleroma, :instances_favicons, enabled: false
+
config :pleroma, :pipeline,
object_validator: Pleroma.Web.ActivityPub.ObjectValidatorMock,
mrf: Pleroma.Web.ActivityPub.MRFMock,
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
index 97390caf5e..c8d9aaeb3f 100755
--- a/docker-entrypoint.sh
+++ b/docker-entrypoint.sh
@@ -2,8 +2,10 @@
set -e
+DATABASE_URL=${DATABASE_URL:-"postgres://${DB_USER:-postgres}:${DB_PASS:-postgres}@${DB_HOST:-db}:5432/${DB_NAME:-postgres}"}
+
echo "-- Waiting for database..."
-while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:5432/${DB_NAME:-pleroma} -t 1; do
+while ! pg_isready -d $DATABASE_URL -t 1; do
sleep 1s
done
diff --git a/installation/pleroma.vcl b/installation/pleroma.vcl
index 4752510ea0..4eb2f3cfae 100644
--- a/installation/pleroma.vcl
+++ b/installation/pleroma.vcl
@@ -1,4 +1,5 @@
# Recommended varnishncsa logging format: '%h %l %u %t "%m %{X-Forwarded-Proto}i://%{Host}i%U%q %H" %s %b "%{Referer}i" "%{User-agent}i"'
+# Please use Varnish 7.0+ for proper Range Requests / Chunked encoding support
vcl 4.1;
import std;
@@ -22,11 +23,6 @@ sub vcl_recv {
set req.http.X-Forwarded-Proto = "https";
}
- # CHUNKED SUPPORT
- if (req.http.Range ~ "bytes=") {
- set req.http.x-range = req.http.Range;
- }
-
# Pipe if WebSockets request is coming through
if (req.http.upgrade ~ "(?i)websocket") {
return (pipe);
@@ -35,9 +31,9 @@ sub vcl_recv {
# Allow purging of the cache
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
- return(synth(405,"Not allowed."));
+ return (synth(405,"Not allowed."));
}
- return(purge);
+ return (purge);
}
}
@@ -53,17 +49,11 @@ sub vcl_backend_response {
return (retry);
}
- # CHUNKED SUPPORT
- if (bereq.http.x-range ~ "bytes=" && beresp.status == 206) {
- set beresp.ttl = 10m;
- set beresp.http.CR = beresp.http.content-range;
- }
-
# Bypass cache for large files
# 50000000 ~ 50MB
if (std.integer(beresp.http.content-length, 0) > 50000000) {
set beresp.uncacheable = true;
- return(deliver);
+ return (deliver);
}
# Don't cache objects that require authentication
@@ -94,7 +84,7 @@ sub vcl_synth {
if (resp.status == 750) {
set resp.status = 301;
set resp.http.Location = req.http.x-redir;
- return(deliver);
+ return (deliver);
}
}
@@ -106,25 +96,12 @@ sub vcl_pipe {
}
}
-sub vcl_hash {
- # CHUNKED SUPPORT
- if (req.http.x-range ~ "bytes=") {
- hash_data(req.http.x-range);
- unset req.http.Range;
- }
-}
-
sub vcl_backend_fetch {
# Be more lenient for slow servers on the fediverse
if (bereq.url ~ "^/proxy/") {
set bereq.first_byte_timeout = 300s;
}
- # CHUNKED SUPPORT
- if (bereq.http.x-range) {
- set bereq.http.Range = bereq.http.x-range;
- }
-
if (bereq.retries == 0) {
# Clean up the X-Varnish-Backend-503 flag that is used internally
# to mark broken backend responses that should be retried.
@@ -143,14 +120,6 @@ sub vcl_backend_fetch {
}
}
-sub vcl_deliver {
- # CHUNKED SUPPORT
- if (resp.http.CR) {
- set resp.http.Content-Range = resp.http.CR;
- unset resp.http.CR;
- }
-}
-
sub vcl_backend_error {
# Retry broken backend responses.
set bereq.http.X-Varnish-Backend-503 = "1";
diff --git a/instance/static/frontends/landing-fe/vendor/assets/soapbox-logo-wide.svg b/instance/static/frontends/landing-fe/vendor/assets/soapbox-logo-wide.svg
deleted file mode 100644
index 038ce75e83..0000000000
--- a/instance/static/frontends/landing-fe/vendor/assets/soapbox-logo-wide.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/instance/static/frontends/landing-fe/vendor/favicon.png b/instance/static/frontends/landing-fe/vendor/favicon.png
deleted file mode 100644
index ebe3a7e157..0000000000
Binary files a/instance/static/frontends/landing-fe/vendor/favicon.png and /dev/null differ
diff --git a/instance/static/frontends/landing-fe/vendor/images/avi.png b/instance/static/frontends/landing-fe/vendor/images/avi.png
deleted file mode 100644
index 6de33a5a49..0000000000
Binary files a/instance/static/frontends/landing-fe/vendor/images/avi.png and /dev/null differ
diff --git a/instance/static/frontends/landing-fe/vendor/images/banner.png b/instance/static/frontends/landing-fe/vendor/images/banner.png
deleted file mode 100644
index 26b59e75a0..0000000000
Binary files a/instance/static/frontends/landing-fe/vendor/images/banner.png and /dev/null differ
diff --git a/instance/static/frontends/landing-fe/vendor/images/logo.png b/instance/static/frontends/landing-fe/vendor/images/logo.png
deleted file mode 100644
index 1f2fedf35e..0000000000
Binary files a/instance/static/frontends/landing-fe/vendor/images/logo.png and /dev/null differ
diff --git a/instance/static/frontends/landing-fe/vendor/index.html b/instance/static/frontends/landing-fe/vendor/index.html
deleted file mode 100644
index 9347cb64cd..0000000000
--- a/instance/static/frontends/landing-fe/vendor/index.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
- Welcome to Soapbox
-
-
-
-
-
-
-
-
- Almost done...
- Congrats! ๐ You've installed Soapbox BE. Now you just need to install a frontend.
- Installing Soapbox FE
- To install Soapbox FE, SSH into the server and download a .zip of the latest build:
- curl -L https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/develop/download?job=build-production -o soapbox-fe.zip
- Then unpack it into the instance
directory:
- busybox unzip soapbox-fe.zip -o -d /opt/pleroma/instance
- That's it! Just refresh this page.
-
-
-
diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex
index 96d4eb90b4..50ffb7f27e 100644
--- a/lib/mix/tasks/pleroma/user.ex
+++ b/lib/mix/tasks/pleroma/user.ex
@@ -421,6 +421,38 @@ def run(["list"]) do
|> Stream.run()
end
+ def run(["fix_follow_state", local_user, remote_user]) do
+ start_pleroma()
+
+ with {:local, %User{} = local} <- {:local, User.get_by_nickname(local_user)},
+ {:remote, %User{} = remote} <- {:remote, User.get_by_nickname(remote_user)},
+ {:follow_data, %{data: %{"state" => request_state}}} <-
+ {:follow_data, Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(local, remote)} do
+ calculated_state = User.following?(local, remote)
+
+ shell_info(
+ "Request state is #{request_state}, vs calculated state of following=#{calculated_state}"
+ )
+
+ if calculated_state == false && request_state == "accept" do
+ shell_info("Discrepancy found, fixing")
+ Pleroma.Web.CommonAPI.reject_follow_request(local, remote)
+ shell_info("Relationship fixed")
+ else
+ shell_info("No discrepancy found")
+ end
+ else
+ {:local, _} ->
+ shell_error("No local user #{local_user}")
+
+ {:remote, _} ->
+ shell_error("No remote user #{remote_user}")
+
+ {:follow_data, _} ->
+ shell_error("No follow data for #{local_user} and #{remote_user}")
+ end
+ end
+
defp set_moderator(user, value) do
{:ok, user} =
user
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index eeb256f0dc..ae70c0b02b 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -12,13 +12,16 @@ defmodule Pleroma.Application do
require Logger
@name Mix.Project.config()[:name]
+ @compat_name Mix.Project.config()[:compat_name]
@version Mix.Project.config()[:version]
@repository Mix.Project.config()[:source_url]
@mix_env Mix.env()
def name, do: @name
+ def compat_name, do: @compat_name
def version, do: @version
def named_version, do: @name <> " " <> @version
+ def compat_version, do: @compat_name <> " " <> @version
def repository, do: @repository
def user_agent do
@@ -26,7 +29,7 @@ def user_agent do
case Config.get([:http, :user_agent], :default) do
:default ->
info = "#{Pleroma.Web.Endpoint.url()} <#{Config.get([:instance, :email], "")}>"
- named_version() <> "; " <> info
+ compat_version() <> "; " <> info
custom ->
custom
@@ -112,7 +115,17 @@ def start(_type, _args) do
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
- opts = [strategy: :one_for_one, name: Pleroma.Supervisor]
+ # If we have a lot of caches, default max_restarts can cause test
+ # resets to fail.
+ # Go for the default 3 unless we're in test
+ max_restarts =
+ if @mix_env == :test do
+ 100
+ else
+ 3
+ end
+
+ opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts]
result = Supervisor.start_link(children, opts)
set_postgres_server_version()
diff --git a/lib/pleroma/emoji-test.txt b/lib/pleroma/emoji-test.txt
index dd54933661..87d093d646 100644
--- a/lib/pleroma/emoji-test.txt
+++ b/lib/pleroma/emoji-test.txt
@@ -1,13 +1,13 @@
# emoji-test.txt
-# Date: 2021-08-26, 17:22:23 GMT
-# ยฉ 2021 Unicodeยฎ, Inc.
+# Date: 2022-08-12, 20:24:39 GMT
+# ยฉ 2022 Unicodeยฎ, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Emoji Keyboard/Display Test Data for UTS #51
-# Version: 14.0
+# Version: 15.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
+# For documentation and usage, see https://www.unicode.org/reports/tr51
#
# This file provides data for testing which emoji forms should be in keyboards and which should also be displayed/processed.
# Format: code points; status # emoji name
@@ -92,6 +92,7 @@
1F62C ; fully-qualified # ๐ฌ E1.0 grimacing face
1F62E 200D 1F4A8 ; fully-qualified # ๐ฎโ๐จ E13.1 face exhaling
1F925 ; fully-qualified # ๐คฅ E3.0 lying face
+1FAE8 ; fully-qualified # ๐ซจ E15.0 shaking face
# subgroup: face-sleepy
1F60C ; fully-qualified # ๐ E0.6 relieved face
@@ -155,7 +156,7 @@
# subgroup: face-negative
1F624 ; fully-qualified # ๐ค E0.6 face with steam from nose
-1F621 ; fully-qualified # ๐ก E0.6 pouting face
+1F621 ; fully-qualified # ๐ก E0.6 enraged face
1F620 ; fully-qualified # ๐ E0.6 angry face
1F92C ; fully-qualified # ๐คฌ E5.0 face with symbols on mouth
1F608 ; fully-qualified # ๐ E1.0 smiling face with horns
@@ -190,8 +191,7 @@
1F649 ; fully-qualified # ๐ E0.6 hear-no-evil monkey
1F64A ; fully-qualified # ๐ E0.6 speak-no-evil monkey
-# subgroup: emotion
-1F48B ; fully-qualified # ๐ E0.6 kiss mark
+# subgroup: heart
1F48C ; fully-qualified # ๐ E0.6 love letter
1F498 ; fully-qualified # ๐ E0.6 heart with arrow
1F49D ; fully-qualified # ๐ E0.6 heart with ribbon
@@ -210,14 +210,20 @@
2764 200D 1FA79 ; unqualified # โคโ๐ฉน E13.1 mending heart
2764 FE0F ; fully-qualified # โค๏ธ E0.6 red heart
2764 ; unqualified # โค E0.6 red heart
+1FA77 ; fully-qualified # ๐ฉท E15.0 pink heart
1F9E1 ; fully-qualified # ๐งก E5.0 orange heart
1F49B ; fully-qualified # ๐ E0.6 yellow heart
1F49A ; fully-qualified # ๐ E0.6 green heart
1F499 ; fully-qualified # ๐ E0.6 blue heart
+1FA75 ; fully-qualified # ๐ฉต E15.0 light blue heart
1F49C ; fully-qualified # ๐ E0.6 purple heart
1F90E ; fully-qualified # ๐ค E12.0 brown heart
1F5A4 ; fully-qualified # ๐ค E3.0 black heart
+1FA76 ; fully-qualified # ๐ฉถ E15.0 grey heart
1F90D ; fully-qualified # ๐ค E12.0 white heart
+
+# subgroup: emotion
+1F48B ; fully-qualified # ๐ E0.6 kiss mark
1F4AF ; fully-qualified # ๐ฏ E0.6 hundred points
1F4A2 ; fully-qualified # ๐ข E0.6 anger symbol
1F4A5 ; fully-qualified # ๐ฅ E0.6 collision
@@ -226,21 +232,20 @@
1F4A8 ; fully-qualified # ๐จ E0.6 dashing away
1F573 FE0F ; fully-qualified # ๐ณ๏ธ E0.7 hole
1F573 ; unqualified # ๐ณ E0.7 hole
-1F4A3 ; fully-qualified # ๐ฃ E0.6 bomb
1F4AC ; fully-qualified # ๐ฌ E0.6 speech balloon
1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # ๐๏ธโ๐จ๏ธ E2.0 eye in speech bubble
1F441 200D 1F5E8 FE0F ; unqualified # ๐โ๐จ๏ธ E2.0 eye in speech bubble
-1F441 FE0F 200D 1F5E8 ; unqualified # ๐๏ธโ๐จ E2.0 eye in speech bubble
+1F441 FE0F 200D 1F5E8 ; minimally-qualified # ๐๏ธโ๐จ E2.0 eye in speech bubble
1F441 200D 1F5E8 ; unqualified # ๐โ๐จ E2.0 eye in speech bubble
1F5E8 FE0F ; fully-qualified # ๐จ๏ธ E2.0 left speech bubble
1F5E8 ; unqualified # ๐จ E2.0 left speech bubble
1F5EF FE0F ; fully-qualified # ๐ฏ๏ธ E0.7 right anger bubble
1F5EF ; unqualified # ๐ฏ E0.7 right anger bubble
1F4AD ; fully-qualified # ๐ญ E1.0 thought balloon
-1F4A4 ; fully-qualified # ๐ค E0.6 zzz
+1F4A4 ; fully-qualified # ๐ค E0.6 ZZZ
-# Smileys & Emotion subtotal: 177
-# Smileys & Emotion subtotal: 177 w/o modifiers
+# Smileys & Emotion subtotal: 180
+# Smileys & Emotion subtotal: 180 w/o modifiers
# group: People & Body
@@ -300,6 +305,18 @@
1FAF4 1F3FD ; fully-qualified # ๐ซด๐ฝ E14.0 palm up hand: medium skin tone
1FAF4 1F3FE ; fully-qualified # ๐ซด๐พ E14.0 palm up hand: medium-dark skin tone
1FAF4 1F3FF ; fully-qualified # ๐ซด๐ฟ E14.0 palm up hand: dark skin tone
+1FAF7 ; fully-qualified # ๐ซท E15.0 leftwards pushing hand
+1FAF7 1F3FB ; fully-qualified # ๐ซท๐ป E15.0 leftwards pushing hand: light skin tone
+1FAF7 1F3FC ; fully-qualified # ๐ซท๐ผ E15.0 leftwards pushing hand: medium-light skin tone
+1FAF7 1F3FD ; fully-qualified # ๐ซท๐ฝ E15.0 leftwards pushing hand: medium skin tone
+1FAF7 1F3FE ; fully-qualified # ๐ซท๐พ E15.0 leftwards pushing hand: medium-dark skin tone
+1FAF7 1F3FF ; fully-qualified # ๐ซท๐ฟ E15.0 leftwards pushing hand: dark skin tone
+1FAF8 ; fully-qualified # ๐ซธ E15.0 rightwards pushing hand
+1FAF8 1F3FB ; fully-qualified # ๐ซธ๐ป E15.0 rightwards pushing hand: light skin tone
+1FAF8 1F3FC ; fully-qualified # ๐ซธ๐ผ E15.0 rightwards pushing hand: medium-light skin tone
+1FAF8 1F3FD ; fully-qualified # ๐ซธ๐ฝ E15.0 rightwards pushing hand: medium skin tone
+1FAF8 1F3FE ; fully-qualified # ๐ซธ๐พ E15.0 rightwards pushing hand: medium-dark skin tone
+1FAF8 1F3FF ; fully-qualified # ๐ซธ๐ฟ E15.0 rightwards pushing hand: dark skin tone
# subgroup: hand-fingers-partial
1F44C ; fully-qualified # ๐ E0.6 OK hand
@@ -473,11 +490,11 @@
1F932 1F3FE ; fully-qualified # ๐คฒ๐พ E5.0 palms up together: medium-dark skin tone
1F932 1F3FF ; fully-qualified # ๐คฒ๐ฟ E5.0 palms up together: dark skin tone
1F91D ; fully-qualified # ๐ค E3.0 handshake
-1F91D 1F3FB ; fully-qualified # ๐ค๐ป E3.0 handshake: light skin tone
-1F91D 1F3FC ; fully-qualified # ๐ค๐ผ E3.0 handshake: medium-light skin tone
-1F91D 1F3FD ; fully-qualified # ๐ค๐ฝ E3.0 handshake: medium skin tone
-1F91D 1F3FE ; fully-qualified # ๐ค๐พ E3.0 handshake: medium-dark skin tone
-1F91D 1F3FF ; fully-qualified # ๐ค๐ฟ E3.0 handshake: dark skin tone
+1F91D 1F3FB ; fully-qualified # ๐ค๐ป E14.0 handshake: light skin tone
+1F91D 1F3FC ; fully-qualified # ๐ค๐ผ E14.0 handshake: medium-light skin tone
+1F91D 1F3FD ; fully-qualified # ๐ค๐ฝ E14.0 handshake: medium skin tone
+1F91D 1F3FE ; fully-qualified # ๐ค๐พ E14.0 handshake: medium-dark skin tone
+1F91D 1F3FF ; fully-qualified # ๐ค๐ฟ E14.0 handshake: dark skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FC ; fully-qualified # ๐ซฑ๐ปโ๐ซฒ๐ผ E14.0 handshake: light skin tone, medium-light skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FD ; fully-qualified # ๐ซฑ๐ปโ๐ซฒ๐ฝ E14.0 handshake: light skin tone, medium skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FE ; fully-qualified # ๐ซฑ๐ปโ๐ซฒ๐พ E14.0 handshake: light skin tone, medium-dark skin tone
@@ -1455,7 +1472,7 @@
1F575 1F3FF ; fully-qualified # ๐ต๐ฟ E2.0 detective: dark skin tone
1F575 FE0F 200D 2642 FE0F ; fully-qualified # ๐ต๏ธโโ๏ธ E4.0 man detective
1F575 200D 2642 FE0F ; unqualified # ๐ตโโ๏ธ E4.0 man detective
-1F575 FE0F 200D 2642 ; unqualified # ๐ต๏ธโโ E4.0 man detective
+1F575 FE0F 200D 2642 ; minimally-qualified # ๐ต๏ธโโ E4.0 man detective
1F575 200D 2642 ; unqualified # ๐ตโโ E4.0 man detective
1F575 1F3FB 200D 2642 FE0F ; fully-qualified # ๐ต๐ปโโ๏ธ E4.0 man detective: light skin tone
1F575 1F3FB 200D 2642 ; minimally-qualified # ๐ต๐ปโโ E4.0 man detective: light skin tone
@@ -1469,7 +1486,7 @@
1F575 1F3FF 200D 2642 ; minimally-qualified # ๐ต๐ฟโโ E4.0 man detective: dark skin tone
1F575 FE0F 200D 2640 FE0F ; fully-qualified # ๐ต๏ธโโ๏ธ E4.0 woman detective
1F575 200D 2640 FE0F ; unqualified # ๐ตโโ๏ธ E4.0 woman detective
-1F575 FE0F 200D 2640 ; unqualified # ๐ต๏ธโโ E4.0 woman detective
+1F575 FE0F 200D 2640 ; minimally-qualified # ๐ต๏ธโโ E4.0 woman detective
1F575 200D 2640 ; unqualified # ๐ตโโ E4.0 woman detective
1F575 1F3FB 200D 2640 FE0F ; fully-qualified # ๐ต๐ปโโ๏ธ E4.0 woman detective: light skin tone
1F575 1F3FB 200D 2640 ; minimally-qualified # ๐ต๐ปโโ E4.0 woman detective: light skin tone
@@ -2302,7 +2319,7 @@
1F3CC 1F3FF ; fully-qualified # ๐๐ฟ E4.0 person golfing: dark skin tone
1F3CC FE0F 200D 2642 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 man golfing
1F3CC 200D 2642 FE0F ; unqualified # ๐โโ๏ธ E4.0 man golfing
-1F3CC FE0F 200D 2642 ; unqualified # ๐๏ธโโ E4.0 man golfing
+1F3CC FE0F 200D 2642 ; minimally-qualified # ๐๏ธโโ E4.0 man golfing
1F3CC 200D 2642 ; unqualified # ๐โโ E4.0 man golfing
1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 man golfing: light skin tone
1F3CC 1F3FB 200D 2642 ; minimally-qualified # ๐๐ปโโ E4.0 man golfing: light skin tone
@@ -2316,7 +2333,7 @@
1F3CC 1F3FF 200D 2642 ; minimally-qualified # ๐๐ฟโโ E4.0 man golfing: dark skin tone
1F3CC FE0F 200D 2640 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 woman golfing
1F3CC 200D 2640 FE0F ; unqualified # ๐โโ๏ธ E4.0 woman golfing
-1F3CC FE0F 200D 2640 ; unqualified # ๐๏ธโโ E4.0 woman golfing
+1F3CC FE0F 200D 2640 ; minimally-qualified # ๐๏ธโโ E4.0 woman golfing
1F3CC 200D 2640 ; unqualified # ๐โโ E4.0 woman golfing
1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 woman golfing: light skin tone
1F3CC 1F3FB 200D 2640 ; minimally-qualified # ๐๐ปโโ E4.0 woman golfing: light skin tone
@@ -2427,7 +2444,7 @@
26F9 1F3FF ; fully-qualified # โน๐ฟ E2.0 person bouncing ball: dark skin tone
26F9 FE0F 200D 2642 FE0F ; fully-qualified # โน๏ธโโ๏ธ E4.0 man bouncing ball
26F9 200D 2642 FE0F ; unqualified # โนโโ๏ธ E4.0 man bouncing ball
-26F9 FE0F 200D 2642 ; unqualified # โน๏ธโโ E4.0 man bouncing ball
+26F9 FE0F 200D 2642 ; minimally-qualified # โน๏ธโโ E4.0 man bouncing ball
26F9 200D 2642 ; unqualified # โนโโ E4.0 man bouncing ball
26F9 1F3FB 200D 2642 FE0F ; fully-qualified # โน๐ปโโ๏ธ E4.0 man bouncing ball: light skin tone
26F9 1F3FB 200D 2642 ; minimally-qualified # โน๐ปโโ E4.0 man bouncing ball: light skin tone
@@ -2441,7 +2458,7 @@
26F9 1F3FF 200D 2642 ; minimally-qualified # โน๐ฟโโ E4.0 man bouncing ball: dark skin tone
26F9 FE0F 200D 2640 FE0F ; fully-qualified # โน๏ธโโ๏ธ E4.0 woman bouncing ball
26F9 200D 2640 FE0F ; unqualified # โนโโ๏ธ E4.0 woman bouncing ball
-26F9 FE0F 200D 2640 ; unqualified # โน๏ธโโ E4.0 woman bouncing ball
+26F9 FE0F 200D 2640 ; minimally-qualified # โน๏ธโโ E4.0 woman bouncing ball
26F9 200D 2640 ; unqualified # โนโโ E4.0 woman bouncing ball
26F9 1F3FB 200D 2640 FE0F ; fully-qualified # โน๐ปโโ๏ธ E4.0 woman bouncing ball: light skin tone
26F9 1F3FB 200D 2640 ; minimally-qualified # โน๐ปโโ E4.0 woman bouncing ball: light skin tone
@@ -2462,7 +2479,7 @@
1F3CB 1F3FF ; fully-qualified # ๐๐ฟ E2.0 person lifting weights: dark skin tone
1F3CB FE0F 200D 2642 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 man lifting weights
1F3CB 200D 2642 FE0F ; unqualified # ๐โโ๏ธ E4.0 man lifting weights
-1F3CB FE0F 200D 2642 ; unqualified # ๐๏ธโโ E4.0 man lifting weights
+1F3CB FE0F 200D 2642 ; minimally-qualified # ๐๏ธโโ E4.0 man lifting weights
1F3CB 200D 2642 ; unqualified # ๐โโ E4.0 man lifting weights
1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 man lifting weights: light skin tone
1F3CB 1F3FB 200D 2642 ; minimally-qualified # ๐๐ปโโ E4.0 man lifting weights: light skin tone
@@ -2476,7 +2493,7 @@
1F3CB 1F3FF 200D 2642 ; minimally-qualified # ๐๐ฟโโ E4.0 man lifting weights: dark skin tone
1F3CB FE0F 200D 2640 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 woman lifting weights
1F3CB 200D 2640 FE0F ; unqualified # ๐โโ๏ธ E4.0 woman lifting weights
-1F3CB FE0F 200D 2640 ; unqualified # ๐๏ธโโ E4.0 woman lifting weights
+1F3CB FE0F 200D 2640 ; minimally-qualified # ๐๏ธโโ E4.0 woman lifting weights
1F3CB 200D 2640 ; unqualified # ๐โโ E4.0 woman lifting weights
1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 woman lifting weights: light skin tone
1F3CB 1F3FB 200D 2640 ; minimally-qualified # ๐๐ปโโ E4.0 woman lifting weights: light skin tone
@@ -3262,8 +3279,8 @@
1FAC2 ; fully-qualified # ๐ซ E13.0 people hugging
1F463 ; fully-qualified # ๐ฃ E0.6 footprints
-# People & Body subtotal: 2986
-# People & Body subtotal: 506 w/o modifiers
+# People & Body subtotal: 2998
+# People & Body subtotal: 508 w/o modifiers
# group: Component
@@ -3306,6 +3323,8 @@
1F405 ; fully-qualified # ๐
E1.0 tiger
1F406 ; fully-qualified # ๐ E1.0 leopard
1F434 ; fully-qualified # ๐ด E0.6 horse face
+1FACE ; fully-qualified # ๐ซ E15.0 moose
+1FACF ; fully-qualified # ๐ซ E15.0 donkey
1F40E ; fully-qualified # ๐ E0.6 horse
1F984 ; fully-qualified # ๐ฆ E1.0 unicorn
1F993 ; fully-qualified # ๐ฆ E5.0 zebra
@@ -3373,6 +3392,9 @@
1F9A9 ; fully-qualified # ๐ฆฉ E12.0 flamingo
1F99A ; fully-qualified # ๐ฆ E11.0 peacock
1F99C ; fully-qualified # ๐ฆ E11.0 parrot
+1FABD ; fully-qualified # ๐ชฝ E15.0 wing
+1F426 200D 2B1B ; fully-qualified # ๐ฆโโฌ E15.0 black bird
+1FABF ; fully-qualified # ๐ชฟ E15.0 goose
# subgroup: animal-amphibian
1F438 ; fully-qualified # ๐ธ E0.6 frog
@@ -3399,6 +3421,7 @@
1F419 ; fully-qualified # ๐ E0.6 octopus
1F41A ; fully-qualified # ๐ E0.6 spiral shell
1FAB8 ; fully-qualified # ๐ชธ E14.0 coral
+1FABC ; fully-qualified # ๐ชผ E15.0 jellyfish
# subgroup: animal-bug
1F40C ; fully-qualified # ๐ E0.6 snail
@@ -3433,6 +3456,7 @@
1F33B ; fully-qualified # ๐ป E0.6 sunflower
1F33C ; fully-qualified # ๐ผ E0.6 blossom
1F337 ; fully-qualified # ๐ท E0.6 tulip
+1FABB ; fully-qualified # ๐ชป E15.0 hyacinth
# subgroup: plant-other
1F331 ; fully-qualified # ๐ฑ E0.6 seedling
@@ -3451,9 +3475,10 @@
1F343 ; fully-qualified # ๐ E0.6 leaf fluttering in wind
1FAB9 ; fully-qualified # ๐ชน E14.0 empty nest
1FABA ; fully-qualified # ๐ชบ E14.0 nest with eggs
+1F344 ; fully-qualified # ๐ E0.6 mushroom
-# Animals & Nature subtotal: 151
-# Animals & Nature subtotal: 151 w/o modifiers
+# Animals & Nature subtotal: 159
+# Animals & Nature subtotal: 159 w/o modifiers
# group: Food & Drink
@@ -3492,10 +3517,11 @@
1F966 ; fully-qualified # ๐ฅฆ E5.0 broccoli
1F9C4 ; fully-qualified # ๐ง E12.0 garlic
1F9C5 ; fully-qualified # ๐ง
E12.0 onion
-1F344 ; fully-qualified # ๐ E0.6 mushroom
1F95C ; fully-qualified # ๐ฅ E3.0 peanuts
1FAD8 ; fully-qualified # ๐ซ E14.0 beans
1F330 ; fully-qualified # ๐ฐ E0.6 chestnut
+1FADA ; fully-qualified # ๐ซ E15.0 ginger root
+1FADB ; fully-qualified # ๐ซ E15.0 pea pod
# subgroup: food-prepared
1F35E ; fully-qualified # ๐ E0.6 bread
@@ -3607,8 +3633,8 @@
1FAD9 ; fully-qualified # ๐ซ E14.0 jar
1F3FA ; fully-qualified # ๐บ E1.0 amphora
-# Food & Drink subtotal: 134
-# Food & Drink subtotal: 134 w/o modifiers
+# Food & Drink subtotal: 135
+# Food & Drink subtotal: 135 w/o modifiers
# group: Travel & Places
@@ -3974,11 +4000,10 @@
1F3AF ; fully-qualified # ๐ฏ E0.6 bullseye
1FA80 ; fully-qualified # ๐ช E12.0 yo-yo
1FA81 ; fully-qualified # ๐ช E12.0 kite
+1F52B ; fully-qualified # ๐ซ E0.6 water pistol
1F3B1 ; fully-qualified # ๐ฑ E0.6 pool 8 ball
1F52E ; fully-qualified # ๐ฎ E0.6 crystal ball
1FA84 ; fully-qualified # ๐ช E13.0 magic wand
-1F9FF ; fully-qualified # ๐งฟ E11.0 nazar amulet
-1FAAC ; fully-qualified # ๐ชฌ E14.0 hamsa
1F3AE ; fully-qualified # ๐ฎ E0.6 video game
1F579 FE0F ; fully-qualified # ๐น๏ธ E0.7 joystick
1F579 ; unqualified # ๐น E0.7 joystick
@@ -4013,8 +4038,8 @@
1F9F6 ; fully-qualified # ๐งถ E11.0 yarn
1FAA2 ; fully-qualified # ๐ชข E13.0 knot
-# Activities subtotal: 97
-# Activities subtotal: 97 w/o modifiers
+# Activities subtotal: 96
+# Activities subtotal: 96 w/o modifiers
# group: Objects
@@ -4040,6 +4065,7 @@
1FA73 ; fully-qualified # ๐ฉณ E12.0 shorts
1F459 ; fully-qualified # ๐ E0.6 bikini
1F45A ; fully-qualified # ๐ E0.6 womanโs clothes
+1FAAD ; fully-qualified # ๐ชญ E15.0 folding hand fan
1F45B ; fully-qualified # ๐ E0.6 purse
1F45C ; fully-qualified # ๐ E0.6 handbag
1F45D ; fully-qualified # ๐ E0.6 clutch bag
@@ -4055,6 +4081,7 @@
1F461 ; fully-qualified # ๐ก E0.6 womanโs sandal
1FA70 ; fully-qualified # ๐ฉฐ E12.0 ballet shoes
1F462 ; fully-qualified # ๐ข E0.6 womanโs boot
+1FAAE ; fully-qualified # ๐ชฎ E15.0 hair pick
1F451 ; fully-qualified # ๐ E0.6 crown
1F452 ; fully-qualified # ๐ E0.6 womanโs hat
1F3A9 ; fully-qualified # ๐ฉ E0.6 top hat
@@ -4103,6 +4130,8 @@
1FA95 ; fully-qualified # ๐ช E12.0 banjo
1F941 ; fully-qualified # ๐ฅ E3.0 drum
1FA98 ; fully-qualified # ๐ช E13.0 long drum
+1FA87 ; fully-qualified # ๐ช E15.0 maracas
+1FA88 ; fully-qualified # ๐ช E15.0 flute
# subgroup: phone
1F4F1 ; fully-qualified # ๐ฑ E0.6 mobile phone
@@ -4275,7 +4304,7 @@
1F5E1 ; unqualified # ๐ก E0.7 dagger
2694 FE0F ; fully-qualified # โ๏ธ E1.0 crossed swords
2694 ; unqualified # โ E1.0 crossed swords
-1F52B ; fully-qualified # ๐ซ E0.6 water pistol
+1F4A3 ; fully-qualified # ๐ฃ E0.6 bomb
1FA83 ; fully-qualified # ๐ช E13.0 boomerang
1F3F9 ; fully-qualified # ๐น E1.0 bow and arrow
1F6E1 FE0F ; fully-qualified # ๐ก๏ธ E0.7 shield
@@ -4354,12 +4383,14 @@
1FAA6 ; fully-qualified # ๐ชฆ E13.0 headstone
26B1 FE0F ; fully-qualified # โฑ๏ธ E1.0 funeral urn
26B1 ; unqualified # โฑ E1.0 funeral urn
+1F9FF ; fully-qualified # ๐งฟ E11.0 nazar amulet
+1FAAC ; fully-qualified # ๐ชฌ E14.0 hamsa
1F5FF ; fully-qualified # ๐ฟ E0.6 moai
1FAA7 ; fully-qualified # ๐ชง E13.0 placard
1FAAA ; fully-qualified # ๐ชช E14.0 identification card
-# Objects subtotal: 304
-# Objects subtotal: 304 w/o modifiers
+# Objects subtotal: 310
+# Objects subtotal: 310 w/o modifiers
# group: Symbols
@@ -4455,6 +4486,7 @@
262E ; unqualified # โฎ E1.0 peace symbol
1F54E ; fully-qualified # ๐ E1.0 menorah
1F52F ; fully-qualified # ๐ฏ E0.6 dotted six-pointed star
+1FAAF ; fully-qualified # ๐ชฏ E15.0 khanda
# subgroup: zodiac
2648 ; fully-qualified # โ E0.6 Aries
@@ -4503,6 +4535,7 @@
1F505 ; fully-qualified # ๐
E1.0 dim button
1F506 ; fully-qualified # ๐ E1.0 bright button
1F4F6 ; fully-qualified # ๐ถ E0.6 antenna bars
+1F6DC ; fully-qualified # ๐ E15.0 wireless
1F4F3 ; fully-qualified # ๐ณ E0.6 vibration mode
1F4F4 ; fully-qualified # ๐ด E0.6 mobile phone off
@@ -4693,8 +4726,8 @@
1F533 ; fully-qualified # ๐ณ E0.6 white square button
1F532 ; fully-qualified # ๐ฒ E0.6 black square button
-# Symbols subtotal: 302
-# Symbols subtotal: 302 w/o modifiers
+# Symbols subtotal: 304
+# Symbols subtotal: 304 w/o modifiers
# group: Flags
@@ -4709,7 +4742,7 @@
1F3F3 200D 1F308 ; unqualified # ๐ณโ๐ E4.0 rainbow flag
1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # ๐ณ๏ธโโง๏ธ E13.0 transgender flag
1F3F3 200D 26A7 FE0F ; unqualified # ๐ณโโง๏ธ E13.0 transgender flag
-1F3F3 FE0F 200D 26A7 ; unqualified # ๐ณ๏ธโโง E13.0 transgender flag
+1F3F3 FE0F 200D 26A7 ; minimally-qualified # ๐ณ๏ธโโง E13.0 transgender flag
1F3F3 200D 26A7 ; unqualified # ๐ณโโง E13.0 transgender flag
1F3F4 200D 2620 FE0F ; fully-qualified # ๐ดโโ ๏ธ E11.0 pirate flag
1F3F4 200D 2620 ; minimally-qualified # ๐ดโโ E11.0 pirate flag
@@ -4983,9 +5016,9 @@
# Flags subtotal: 275 w/o modifiers
# Status Counts
-# fully-qualified : 3624
-# minimally-qualified : 817
-# unqualified : 252
+# fully-qualified : 3655
+# minimally-qualified : 827
+# unqualified : 242
# component : 9
#EOF
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 3682ae3d97..1c635ee92c 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -1587,13 +1587,19 @@ def block(%User{} = blocker, %User{} = blocked) do
blocker
end
- # clear any requested follows as well
+ # clear any requested follows from both sides as well
blocked =
case CommonAPI.reject_follow_request(blocked, blocker) do
{:ok, %User{} = updated_blocked} -> updated_blocked
nil -> blocked
end
+ blocker =
+ case CommonAPI.reject_follow_request(blocker, blocked) do
+ {:ok, %User{} = updated_blocker} -> updated_blocker
+ nil -> blocker
+ end
+
unsubscribe(blocked, blocker)
unfollowing_blocked = Config.get([:activitypub, :unfollow_blocked], true)
diff --git a/lib/pleroma/user_relationship.ex b/lib/pleroma/user_relationship.ex
index 5b3e593d37..fbecf31292 100644
--- a/lib/pleroma/user_relationship.ex
+++ b/lib/pleroma/user_relationship.ex
@@ -91,8 +91,9 @@ def create(relationship_type, %User{} = source, %User{} = target, expires_at \\
expires_at: expires_at
})
|> Repo.insert(
- on_conflict: {:replace_all_except, [:id]},
- conflict_target: [:source_id, :relationship_type, :target_id]
+ on_conflict: {:replace_all_except, [:id, :inserted_at]},
+ conflict_target: [:source_id, :relationship_type, :target_id],
+ returning: true
)
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex
index 4bfa295084..00b85a2148 100644
--- a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex
@@ -29,6 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
field(:closed, ObjectValidators.DateTime)
field(:voters, {:array, ObjectValidators.ObjectID}, default: [])
+ field(:votersCount, :integer)
field(:nonAnonymous, :boolean)
embeds_many(:anyOf, QuestionOptionsValidator)
embeds_many(:oneOf, QuestionOptionsValidator)
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 9129c2445b..b5796b3308 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -723,6 +723,14 @@ def replies(%{"replies" => %{"items" => items}}) when not is_nil(items) do
def replies(_), do: []
+ defp set_voters_count(%{"voters" => [_ | _] = voters} = obj) do
+ obj
+ |> Map.merge(%{"votersCount" => length(voters)})
+ |> Map.delete("voters")
+ end
+
+ defp set_voters_count(obj), do: obj
+
# Prepares the object of an outgoing create activity.
def prepare_object(object) do
object
@@ -735,6 +743,7 @@ def prepare_object(object) do
|> set_reply_to_uri
|> set_quote_url
|> set_replies
+ |> set_voters_count
|> strip_internal_fields
|> strip_internal_tags
|> set_type
diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex
index 2249c84e2f..c2343d37ab 100644
--- a/lib/pleroma/web/mastodon_api/views/instance_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex
@@ -18,7 +18,7 @@ def render("show.json", _) do
title: Keyword.get(instance, :name),
description: Keyword.get(instance, :description),
short_description: Keyword.get(instance, :short_description),
- version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
+ version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.compat_version()})",
email: Keyword.get(instance, :email),
urls: %{
streaming_api: Pleroma.Web.Endpoint.websocket_url()
@@ -54,7 +54,8 @@ def render("show.json", _) do
birthday_min_age: Config.get([:instance, :birthday_min_age])
},
stats: %{mau: Pleroma.User.active_user_count()},
- vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
+ vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key),
+ oauth_consumer_strategies: Pleroma.Config.oauth_consumer_strategies()
},
configuration: configuration(),
soapbox: %{
diff --git a/lib/pleroma/web/mastodon_api/views/poll_view.ex b/lib/pleroma/web/mastodon_api/views/poll_view.ex
index 1e3c9f36d4..5bc482c8d8 100644
--- a/lib/pleroma/web/mastodon_api/views/poll_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/poll_view.ex
@@ -71,6 +71,10 @@ defp options_and_votes_count(options) do
end)
end
+ defp voters_count(%{data: %{"votersCount" => voters}}) when is_number(voters) do
+ voters
+ end
+
defp voters_count(%{data: %{"voters" => [_ | _] = voters}}) do
length(voters)
end
diff --git a/lib/pleroma/web/media_proxy/media_proxy_controller.ex b/lib/pleroma/web/media_proxy/media_proxy_controller.ex
index 3d6716d434..d2ad62c139 100644
--- a/lib/pleroma/web/media_proxy/media_proxy_controller.ex
+++ b/lib/pleroma/web/media_proxy/media_proxy_controller.ex
@@ -54,7 +54,7 @@ defp handle_preview(conn, url) do
media_proxy_url = MediaProxy.url(url)
with {:ok, %{status: status} = head_response} when status in 200..299 <-
- Pleroma.HTTP.request("head", media_proxy_url, [], [], pool: :media) do
+ Pleroma.HTTP.request("HEAD", media_proxy_url, [], [], pool: :media) do
content_type = Tesla.get_header(head_response, "content-type")
content_length = Tesla.get_header(head_response, "content-length")
content_length = content_length && String.to_integer(content_length)
diff --git a/lib/pleroma/web/nodeinfo/nodeinfo.ex b/lib/pleroma/web/nodeinfo/nodeinfo.ex
index 62d445f349..3c7c9eafca 100644
--- a/lib/pleroma/web/nodeinfo/nodeinfo.ex
+++ b/lib/pleroma/web/nodeinfo/nodeinfo.ex
@@ -24,7 +24,7 @@ def get_nodeinfo("2.0") do
%{
version: "2.0",
software: %{
- name: Pleroma.Application.name() |> String.downcase(),
+ name: Pleroma.Application.compat_name() |> String.downcase(),
version: Pleroma.Application.version()
},
protocols: Publisher.gather_nodeinfo_protocol_names(),
diff --git a/lib/pleroma/web/plugs/o_auth_plug.ex b/lib/pleroma/web/plugs/o_auth_plug.ex
index 0f74d626bb..ba04ddb72f 100644
--- a/lib/pleroma/web/plugs/o_auth_plug.ex
+++ b/lib/pleroma/web/plugs/o_auth_plug.ex
@@ -47,15 +47,17 @@ def call(conn, _) do
#
@spec fetch_user_and_token(String.t()) :: {:ok, User.t(), Token.t()} | nil
defp fetch_user_and_token(token) do
- query =
+ token_query =
from(t in Token,
- where: t.token == ^token,
- join: user in assoc(t, :user),
- preload: [user: user]
+ where: t.token == ^token
)
- with %Token{user: user} = token_record <- Repo.one(query) do
+ with %Token{user_id: user_id} = token_record <- Repo.one(token_query),
+ false <- is_nil(user_id),
+ %User{} = user <- User.get_cached_by_id(user_id) do
{:ok, user, token_record}
+ else
+ _ -> nil
end
end
diff --git a/lib/pleroma/web/templates/layout/app.html.eex b/lib/pleroma/web/templates/layout/app.html.eex
index e33bada858..6003c39dd4 100644
--- a/lib/pleroma/web/templates/layout/app.html.eex
+++ b/lib/pleroma/web/templates/layout/app.html.eex
@@ -5,11 +5,23 @@
<%= Pleroma.Config.get([:instance, :name]) %>
+
diff --git a/lib/pleroma/web/utils/colors.ex b/lib/pleroma/web/utils/colors.ex
new file mode 100644
index 0000000000..6e386df803
--- /dev/null
+++ b/lib/pleroma/web/utils/colors.ex
@@ -0,0 +1,90 @@
+# Pleroma: A lightweight social networking server
+# Copyright ยฉ 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Utils.Colors do
+ alias Pleroma.Web.Utils.Colors.RGB
+
+ # Adapted from:
+ # https://gitlab.com/soapbox-pub/soapbox-fe/-/blob/develop/app/soapbox/utils/colors.ts
+ @intensity_map %{
+ 50 => 0.95,
+ 100 => 0.9,
+ 200 => 0.75,
+ 300 => 0.3,
+ 400 => 0.2,
+ 600 => 0.9,
+ 700 => 0.75,
+ 800 => 0.3,
+ 900 => 0.19
+ }
+
+ def get_shades("#" <> base_color) do
+ base_color = base_color |> hex_to_rgb()
+
+ shades = %{
+ 500 => base_color |> rgb_to_string()
+ }
+
+ shades =
+ [50, 100, 200, 300, 400]
+ |> Enum.reduce(shades, fn level, map ->
+ Map.put(map, level, lighten(base_color, Map.get(@intensity_map, level)))
+ end)
+
+ shades =
+ [600, 700, 800, 900]
+ |> Enum.reduce(shades, fn level, map ->
+ Map.put(map, level, darken(base_color, Map.get(@intensity_map, level)))
+ end)
+
+ shades
+ end
+
+ def get_shades(_) do
+ get_shades("#0482d8")
+ end
+
+ defp lighten(%RGB{red: red, green: green, blue: blue}, intensity) do
+ %RGB{
+ red: round(red + (255 - red) * intensity),
+ green: round(green + (255 - green) * intensity),
+ blue: round(blue + (255 - blue) * intensity)
+ }
+ |> rgb_to_string()
+ end
+
+ defp darken(%RGB{red: red, green: green, blue: blue}, intensity) do
+ %RGB{
+ red: round(red * intensity),
+ green: round(green * intensity),
+ blue: round(blue * intensity)
+ }
+ |> rgb_to_string()
+ end
+
+ defp rgb_to_string(%RGB{red: red, green: green, blue: blue}) do
+ "#{red}, #{green}, #{blue}"
+ end
+
+ defp hex_to_rgb(<>) do
+ %RGB{
+ red: hex_to_decimal(red),
+ green: hex_to_decimal(green),
+ blue: hex_to_decimal(blue)
+ }
+ end
+
+ defp hex_to_decimal(hex) do
+ {decimal, ""} = Integer.parse(hex, 16)
+
+ decimal
+ end
+
+ def shades_to_css(name, base_color \\ nil) do
+ get_shades(base_color)
+ |> Map.to_list()
+ |> Enum.reduce([], fn {key, shade}, list -> list ++ ["--color-#{name}-#{key}: #{shade};"] end)
+ |> Enum.join("\n")
+ end
+end
diff --git a/lib/pleroma/web/utils/colors/rgb.ex b/lib/pleroma/web/utils/colors/rgb.ex
new file mode 100644
index 0000000000..2526466a61
--- /dev/null
+++ b/lib/pleroma/web/utils/colors/rgb.ex
@@ -0,0 +1,13 @@
+# Pleroma: A lightweight social networking server
+# Copyright ยฉ 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Utils.Colors.RGB do
+ defstruct red: 0, green: 0, blue: 0
+
+ @type t :: %__MODULE__{
+ red: non_neg_integer(),
+ green: non_neg_integer(),
+ blue: non_neg_integer()
+ }
+end
diff --git a/lib/pleroma/workers/receiver_worker.ex b/lib/pleroma/workers/receiver_worker.ex
index 268b5f30ff..c41b44e141 100644
--- a/lib/pleroma/workers/receiver_worker.ex
+++ b/lib/pleroma/workers/receiver_worker.ex
@@ -9,6 +9,12 @@ defmodule Pleroma.Workers.ReceiverWorker do
@impl Oban.Worker
def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do
- Federator.perform(:incoming_ap_doc, params)
+ with {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do
+ {:ok, res}
+ else
+ {:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed}
+ {:error, {:reject, reason}} -> {:cancel, reason}
+ e -> e
+ end
end
end
diff --git a/mix.exs b/mix.exs
index df3bf15a49..2aefe5779e 100644
--- a/mix.exs
+++ b/mix.exs
@@ -6,6 +6,8 @@ defmodule Pleroma.Mixfile do
def project do
[
app: :pleroma,
+ name: "Rebased",
+ compat_name: "Pleroma",
version: version("2.4.52"),
elixir: "~> 1.9",
elixirc_paths: elixirc_paths(Mix.env()),
@@ -18,12 +20,11 @@ def project do
test_coverage: [tool: ExCoveralls],
preferred_cli_env: ["coveralls.html": :test],
# Docs
- name: "Pleroma",
- homepage_url: "https://pleroma.social/",
- source_url: "https://git.pleroma.social/pleroma/pleroma",
+ homepage_url: "https://soapbox.pub/",
+ source_url: "https://gitlab.com/soapbox-pub/rebased",
docs: [
source_url_pattern:
- "https://git.pleroma.social/pleroma/pleroma/blob/develop/%{path}#L%{line}",
+ "https://gitlab.com/soapbox-pub/rebased/blob/develop/%{path}#L%{line}",
logo: "priv/static/images/logo.png",
extras: ["README.md", "CHANGELOG.md"] ++ Path.wildcard("docs/**/*.md"),
groups_for_extras: [
diff --git a/mix.lock b/mix.lock
index ca7ff4a13d..9e3e7d8612 100644
--- a/mix.lock
+++ b/mix.lock
@@ -90,6 +90,8 @@
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm", "5c040b8469c1ff1b10093d3186e2e10dbe483cd73d79ec017993fb3985b8a9b3"},
"nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"},
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
+ "oauth2": {:hex, :oauth2, "0.9.4", "632e8e8826a45e33ac2ea5ac66dcc019ba6bb5a0d2ba77e342d33e3b7b252c6e", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "407c6b9f60aa0d01b915e2347dc6be78adca706a37f0c530808942da3b62e7af"},
+ "oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"},
"oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"},
"oembed_providers": {:hex, :oembed_providers, "0.1.0", "9b336ee5f3ca20ee4ed005383c74b154d30d0abeb98e95828855c0e2841ae46b", [:mix], [{:glob, "~> 1.0", [hex: :glob, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "ac1dda0f743aa6fdead3eef59decfefc9de91d550bf0805b8fce16ed10d421ba"},
"open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"},
@@ -135,6 +137,13 @@
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
"tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"},
"ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"},
+ "ueberauth_facebook": {:hex, :ueberauth_facebook, "0.8.0", "9ec8571f804dd5c06f4e305d70606b39fc0ac8a8f43ed56ebb76012a97d14729", [:mix], [{:oauth2, "~> 0.9", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "6d0c88d6ea4cc40cf99b3abcf8aaa435a31f836dc8921e8b4015d760e183f7ba"},
+ "ueberauth_github": {:hex, :ueberauth_github, "0.7.0", "637067c5500f7b13c18caca3db66d09eba661524e0d0e9518b54151e99484bad", [:mix], [{:oauth2, "~> 0.9", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "05d5ec9ac501a8ca82c41275436d1d0cf05f5c380ab194c5d79414a02de2645e"},
+ "ueberauth_google": {:hex, :ueberauth_google, "0.8.0", "dc0e8417061c74107a3ba1419943cc930d3403b5c536b3757886964a3a70c333", [:mix], [{:oauth2, "~> 0.9", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "72cd7710cd721ec340a2eda418658e77254ab516ddcb52257db834055878cdc7"},
+ "ueberauth_keycloak_strategy": {:hex, :ueberauth_keycloak_strategy, "0.2.0", "5ed0471a1cbb2ad4c0b371ab9f2a8e413070d9f307a2e55925a613254e7be619", [:mix], [{:oauth2, "~> 0.9", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "9db30c00fe7e55f032254e6220d7c9b260e14367bfd0dba6c29760ce05a0131c"},
+ "ueberauth_microsoft": {:hex, :ueberauth_microsoft, "0.4.0", "1c0be9c218e93c426e32c416421e9d41ea59fdf1e3b24310ed5be41df46ddcc1", [:mix], [{:oauth2, "~> 0.8", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "0b124367853a9becd265639f9eaa0c5318a313feb8ebd51464c8c68be1353e20"},
+ "ueberauth_slack": {:hex, :ueberauth_slack, "0.3.0", "ec8f6c96e1d41a458a00b5d8cd918c1f387998884fe4636e67dd88b1bd06f928", [:mix], [{:oauth2, "~> 0.5", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.2", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "b4012b2cf1664dc80eda5762c5d3a495a819456186ab789da8ce4e7b9c0fa22f"},
+ "ueberauth_twitter": {:hex, :ueberauth_twitter, "0.4.0", "4b98620341bc91bac90459093bba093c650823b6e2df35b70255c493c17e9227", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:oauther, "~> 1.1", [hex: :oauther, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "fb29c9047ca263038c0c61f5a0ec8597e8564aba3f2b4cb02704b60205fd4468"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
"web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
diff --git a/priv/static/emoji/Firefox.gif b/priv/static/emoji/Firefox.gif
deleted file mode 100644
index 81561d94bc..0000000000
Binary files a/priv/static/emoji/Firefox.gif and /dev/null differ
diff --git a/priv/static/emoji/blank.png b/priv/static/emoji/blank.png
deleted file mode 100644
index 8f50fa0234..0000000000
Binary files a/priv/static/emoji/blank.png and /dev/null differ
diff --git a/priv/static/emoji/dino walking.gif b/priv/static/emoji/dino walking.gif
deleted file mode 100644
index 694a541e7f..0000000000
Binary files a/priv/static/emoji/dino walking.gif and /dev/null differ
diff --git a/priv/static/favicon.png b/priv/static/favicon.png
index 098040a00d..ebe3a7e157 100644
Binary files a/priv/static/favicon.png and b/priv/static/favicon.png differ
diff --git a/priv/static/images/avi.png b/priv/static/images/avi.png
index df4e2d2336..6de33a5a49 100644
Binary files a/priv/static/images/avi.png and b/priv/static/images/avi.png differ
diff --git a/priv/static/images/banner.png b/priv/static/images/banner.png
index aa76fdd8de..26b59e75a0 100644
Binary files a/priv/static/images/banner.png and b/priv/static/images/banner.png differ
diff --git a/priv/static/images/city.jpg b/priv/static/images/city.jpg
deleted file mode 100644
index 75c07b5bd9..0000000000
Binary files a/priv/static/images/city.jpg and /dev/null differ
diff --git a/priv/static/images/logo.png b/priv/static/images/logo.png
index 7744b1acc3..1f2fedf35e 100644
Binary files a/priv/static/images/logo.png and b/priv/static/images/logo.png differ
diff --git a/priv/static/images/pleroma-fox-tan-shy.png b/priv/static/images/pleroma-fox-tan-shy.png
deleted file mode 100644
index 6e24be1e36..0000000000
Binary files a/priv/static/images/pleroma-fox-tan-shy.png and /dev/null differ
diff --git a/priv/static/images/pleroma-fox-tan-smol.png b/priv/static/images/pleroma-fox-tan-smol.png
deleted file mode 100644
index e944d0e2aa..0000000000
Binary files a/priv/static/images/pleroma-fox-tan-smol.png and /dev/null differ
diff --git a/priv/static/images/pleroma-fox-tan.png b/priv/static/images/pleroma-fox-tan.png
deleted file mode 100644
index da0022ff29..0000000000
Binary files a/priv/static/images/pleroma-fox-tan.png and /dev/null differ
diff --git a/priv/static/images/pleroma-tan.png b/priv/static/images/pleroma-tan.png
deleted file mode 100644
index 6c12c8e469..0000000000
Binary files a/priv/static/images/pleroma-tan.png and /dev/null differ
diff --git a/priv/static/images/rebased-wide.svg b/priv/static/images/rebased-wide.svg
new file mode 100644
index 0000000000..d2b224f88a
--- /dev/null
+++ b/priv/static/images/rebased-wide.svg
@@ -0,0 +1,45 @@
+
+
+
+
diff --git a/priv/static/index.html b/priv/static/index.html
index b1455c1846..a888b895a9 100644
--- a/priv/static/index.html
+++ b/priv/static/index.html
@@ -1 +1,75 @@
-
\ No newline at end of file
+
+
+
+ Welcome to Rebased
+
+
+
+
+
+
+
+
+
+ Almost done...
+ Congrats! ๐ You've installed Rebased. Now you just need to install a frontend.
+ Installing Soapbox
+ To install Soapbox, SSH into the server and download a .zip of the latest build:
+ curl -L https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/develop/download?job=build-production -o soapbox-fe.zip
+ Then unpack it into the instance
directory:
+ busybox unzip soapbox-fe.zip -o -d /opt/pleroma/instance
+ That's it! Just refresh this page.
+
+
+
diff --git a/priv/static/instance/static.css b/priv/static/instance/static.css
index 361bf0be11..3a734faab8 100644
Binary files a/priv/static/instance/static.css and b/priv/static/instance/static.css differ
diff --git a/priv/static/instance/thumbnail.jpeg b/priv/static/instance/thumbnail.jpeg
deleted file mode 100644
index f63c9fef20..0000000000
Binary files a/priv/static/instance/thumbnail.jpeg and /dev/null differ
diff --git a/instance/static/frontends/landing-fe/vendor/instance/thumbnail.png b/priv/static/instance/thumbnail.png
similarity index 100%
rename from instance/static/frontends/landing-fe/vendor/instance/thumbnail.png
rename to priv/static/instance/thumbnail.png
diff --git a/priv/static/schemas/litepub-0.1.jsonld b/priv/static/schemas/litepub-0.1.jsonld
index 69f7667dee..d4e2687a93 100644
--- a/priv/static/schemas/litepub-0.1.jsonld
+++ b/priv/static/schemas/litepub-0.1.jsonld
@@ -42,7 +42,8 @@
"vcard": "http://www.w3.org/2006/vcard/ns#",
"sm": "http://smithereen.software/ns#",
"nonAnonymous": "sm:nonAnonymous",
- "formerRepresentations": "litepub:formerRepresentations"
+ "formerRepresentations": "litepub:formerRepresentations",
+ "votersCount" : "toot:votersCount"
}
]
}
diff --git a/priv/static/static/aurora_borealis.jpg b/priv/static/static/aurora_borealis.jpg
deleted file mode 100644
index b6a0daf916..0000000000
Binary files a/priv/static/static/aurora_borealis.jpg and /dev/null differ
diff --git a/priv/static/static/config.json b/priv/static/static/config.json
deleted file mode 100644
index 53a4be8236..0000000000
--- a/priv/static/static/config.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "alwaysShowSubjectInput": true,
- "background": "/static/aurora_borealis.jpg",
- "collapseMessageWithSubject": false,
- "greentext": false,
- "hideFilteredStatuses": false,
- "hideMutedPosts": false,
- "hidePostStats": false,
- "hideSitename": false,
- "hideUserStats": false,
- "loginMethod": "password",
- "logo": "/static/logo.svg",
- "logoMargin": ".1em",
- "logoMask": true,
- "logoLeft": false,
- "minimalScopesMode": false,
- "nsfwCensorImage": "",
- "postContentType": "text/plain",
- "redirectRootLogin": "/main/friends",
- "redirectRootNoLogin": "/main/all",
- "scopeCopy": true,
- "showFeaturesPanel": true,
- "showInstanceSpecificPanel": false,
- "sidebarRight": false,
- "subjectLineBehavior": "email",
- "theme": "pleroma-dark",
- "webPushNotifications": false
-}
diff --git a/priv/static/static/css/2.0778a6a864a1307a6c41.css b/priv/static/static/css/2.0778a6a864a1307a6c41.css
deleted file mode 100644
index a33585ef1b..0000000000
Binary files a/priv/static/static/css/2.0778a6a864a1307a6c41.css and /dev/null differ
diff --git a/priv/static/static/css/2.0778a6a864a1307a6c41.css.map b/priv/static/static/css/2.0778a6a864a1307a6c41.css.map
deleted file mode 100644
index 28cd8ba540..0000000000
--- a/priv/static/static/css/2.0778a6a864a1307a6c41.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack:///./src/hocs/with_subscription/with_subscription.scss"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,C","file":"static/css/2.0778a6a864a1307a6c41.css","sourcesContent":[".with-subscription-loading {\n padding: 10px;\n text-align: center;\n}\n.with-subscription-loading .error {\n font-size: 14px;\n}"],"sourceRoot":""}
\ No newline at end of file
diff --git a/priv/static/static/css/3.b2603a50868c68a1c192.css b/priv/static/static/css/3.b2603a50868c68a1c192.css
deleted file mode 100644
index 4cec5785b1..0000000000
Binary files a/priv/static/static/css/3.b2603a50868c68a1c192.css and /dev/null differ
diff --git a/priv/static/static/css/3.b2603a50868c68a1c192.css.map b/priv/static/static/css/3.b2603a50868c68a1c192.css.map
deleted file mode 100644
index 805e7dc049..0000000000
--- a/priv/static/static/css/3.b2603a50868c68a1c192.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack:///./node_modules/cropperjs/dist/cropper.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,wCAAwC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA","file":"static/css/3.b2603a50868c68a1c192.css","sourcesContent":["/*!\n * Cropper.js v1.4.3\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2018-10-24T13:07:11.429Z\n */\n\n.cropper-container {\n direction: ltr;\n font-size: 0;\n line-height: 0;\n position: relative;\n -ms-touch-action: none;\n touch-action: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.cropper-container img {\n display: block;\n height: 100%;\n image-orientation: 0deg;\n max-height: none !important;\n max-width: none !important;\n min-height: 0 !important;\n min-width: 0 !important;\n width: 100%;\n}\n\n.cropper-wrap-box,\n.cropper-canvas,\n.cropper-drag-box,\n.cropper-crop-box,\n.cropper-modal {\n bottom: 0;\n left: 0;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.cropper-wrap-box,\n.cropper-canvas {\n overflow: hidden;\n}\n\n.cropper-drag-box {\n background-color: #fff;\n opacity: 0;\n}\n\n.cropper-modal {\n background-color: #000;\n opacity: .5;\n}\n\n.cropper-view-box {\n display: block;\n height: 100%;\n outline-color: rgba(51, 153, 255, 0.75);\n outline: 1px solid #39f;\n overflow: hidden;\n width: 100%;\n}\n\n.cropper-dashed {\n border: 0 dashed #eee;\n display: block;\n opacity: .5;\n position: absolute;\n}\n\n.cropper-dashed.dashed-h {\n border-bottom-width: 1px;\n border-top-width: 1px;\n height: calc(100% / 3);\n left: 0;\n top: calc(100% / 3);\n width: 100%;\n}\n\n.cropper-dashed.dashed-v {\n border-left-width: 1px;\n border-right-width: 1px;\n height: 100%;\n left: calc(100% / 3);\n top: 0;\n width: calc(100% / 3);\n}\n\n.cropper-center {\n display: block;\n height: 0;\n left: 50%;\n opacity: .75;\n position: absolute;\n top: 50%;\n width: 0;\n}\n\n.cropper-center:before,\n.cropper-center:after {\n background-color: #eee;\n content: ' ';\n display: block;\n position: absolute;\n}\n\n.cropper-center:before {\n height: 1px;\n left: -3px;\n top: 0;\n width: 7px;\n}\n\n.cropper-center:after {\n height: 7px;\n left: 0;\n top: -3px;\n width: 1px;\n}\n\n.cropper-face,\n.cropper-line,\n.cropper-point {\n display: block;\n height: 100%;\n opacity: .1;\n position: absolute;\n width: 100%;\n}\n\n.cropper-face {\n background-color: #fff;\n left: 0;\n top: 0;\n}\n\n.cropper-line {\n background-color: #39f;\n}\n\n.cropper-line.line-e {\n cursor: ew-resize;\n right: -3px;\n top: 0;\n width: 5px;\n}\n\n.cropper-line.line-n {\n cursor: ns-resize;\n height: 5px;\n left: 0;\n top: -3px;\n}\n\n.cropper-line.line-w {\n cursor: ew-resize;\n left: -3px;\n top: 0;\n width: 5px;\n}\n\n.cropper-line.line-s {\n bottom: -3px;\n cursor: ns-resize;\n height: 5px;\n left: 0;\n}\n\n.cropper-point {\n background-color: #39f;\n height: 5px;\n opacity: .75;\n width: 5px;\n}\n\n.cropper-point.point-e {\n cursor: ew-resize;\n margin-top: -3px;\n right: -3px;\n top: 50%;\n}\n\n.cropper-point.point-n {\n cursor: ns-resize;\n left: 50%;\n margin-left: -3px;\n top: -3px;\n}\n\n.cropper-point.point-w {\n cursor: ew-resize;\n left: -3px;\n margin-top: -3px;\n top: 50%;\n}\n\n.cropper-point.point-s {\n bottom: -3px;\n cursor: s-resize;\n left: 50%;\n margin-left: -3px;\n}\n\n.cropper-point.point-ne {\n cursor: nesw-resize;\n right: -3px;\n top: -3px;\n}\n\n.cropper-point.point-nw {\n cursor: nwse-resize;\n left: -3px;\n top: -3px;\n}\n\n.cropper-point.point-sw {\n bottom: -3px;\n cursor: nesw-resize;\n left: -3px;\n}\n\n.cropper-point.point-se {\n bottom: -3px;\n cursor: nwse-resize;\n height: 20px;\n opacity: 1;\n right: -3px;\n width: 20px;\n}\n\n@media (min-width: 768px) {\n .cropper-point.point-se {\n height: 15px;\n width: 15px;\n }\n}\n\n@media (min-width: 992px) {\n .cropper-point.point-se {\n height: 10px;\n width: 10px;\n }\n}\n\n@media (min-width: 1200px) {\n .cropper-point.point-se {\n height: 5px;\n opacity: .75;\n width: 5px;\n }\n}\n\n.cropper-point.point-se:before {\n background-color: #39f;\n bottom: -50%;\n content: ' ';\n display: block;\n height: 200%;\n opacity: 0;\n position: absolute;\n right: -50%;\n width: 200%;\n}\n\n.cropper-invisible {\n opacity: 0;\n}\n\n.cropper-bg {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');\n}\n\n.cropper-hide {\n display: block;\n height: 0;\n position: absolute;\n width: 0;\n}\n\n.cropper-hidden {\n display: none !important;\n}\n\n.cropper-move {\n cursor: move;\n}\n\n.cropper-crop {\n cursor: crosshair;\n}\n\n.cropper-disabled .cropper-drag-box,\n.cropper-disabled .cropper-face,\n.cropper-disabled .cropper-line,\n.cropper-disabled .cropper-point {\n cursor: not-allowed;\n}\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/priv/static/static/css/app.7d2d223f75c3a14b0991.css b/priv/static/static/css/app.7d2d223f75c3a14b0991.css
deleted file mode 100644
index d79cf910f6..0000000000
Binary files a/priv/static/static/css/app.7d2d223f75c3a14b0991.css and /dev/null differ
diff --git a/priv/static/static/css/app.7d2d223f75c3a14b0991.css.map b/priv/static/static/css/app.7d2d223f75c3a14b0991.css.map
deleted file mode 100644
index ce9a6fa127..0000000000
--- a/priv/static/static/css/app.7d2d223f75c3a14b0991.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack:///./src/components/rich_content/rich_content.scss","webpack:///./src/components/tab_switcher/tab_switcher.scss","webpack:///./src/hocs/with_load_more/with_load_more.scss"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,C;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,C;ACtOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,C","file":"static/css/app.7d2d223f75c3a14b0991.css","sourcesContent":[".RichContent blockquote {\n margin: 0.2em 0 0.2em 2em;\n font-style: italic;\n}\n.RichContent pre {\n overflow: auto;\n}\n.RichContent code,\n.RichContent samp,\n.RichContent kbd,\n.RichContent var,\n.RichContent pre {\n font-family: var(--postCodeFont, monospace);\n}\n.RichContent p {\n margin: 0 0 1em 0;\n}\n.RichContent p:last-child {\n margin: 0 0 0 0;\n}\n.RichContent h1 {\n font-size: 1.1em;\n line-height: 1.2em;\n margin: 1.4em 0;\n}\n.RichContent h2 {\n font-size: 1.1em;\n margin: 1em 0;\n}\n.RichContent h3 {\n font-size: 1em;\n margin: 1.2em 0;\n}\n.RichContent h4 {\n margin: 1.1em 0;\n}\n.RichContent .img {\n display: inline-block;\n}\n.RichContent .emoji {\n display: inline-block;\n width: var(--emoji-size, 32px);\n height: var(--emoji-size, 32px);\n}\n.RichContent .img,\n.RichContent video {\n max-width: 100%;\n max-height: 400px;\n vertical-align: middle;\n -o-object-fit: contain;\n object-fit: contain;\n}",".tab-switcher {\n display: -ms-flexbox;\n display: flex;\n}\n.tab-switcher .tab-icon {\n margin: 0.2em auto;\n display: block;\n}\n.tab-switcher.top-tabs {\n -ms-flex-direction: column;\n flex-direction: column;\n}\n.tab-switcher.top-tabs > .tabs {\n width: 100%;\n overflow-y: hidden;\n overflow-x: auto;\n padding-top: 5px;\n -ms-flex-direction: row;\n flex-direction: row;\n}\n.tab-switcher.top-tabs > .tabs::after, .tab-switcher.top-tabs > .tabs::before {\n content: \"\";\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n border-bottom: 1px solid;\n border-bottom-color: #222;\n border-bottom-color: var(--border, #222);\n}\n.tab-switcher.top-tabs > .tabs .tab-wrapper {\n height: 28px;\n}\n.tab-switcher.top-tabs > .tabs .tab-wrapper:not(.active)::after {\n left: 0;\n right: 0;\n bottom: 0;\n border-bottom: 1px solid;\n border-bottom-color: #222;\n border-bottom-color: var(--border, #222);\n}\n.tab-switcher.top-tabs > .tabs .tab {\n width: 100%;\n min-width: 1px;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n padding-bottom: 99px;\n margin-bottom: -93px;\n}\n.tab-switcher.top-tabs .contents.scrollable-tabs {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n}\n.tab-switcher.side-tabs {\n -ms-flex-direction: row;\n flex-direction: row;\n}\n@media all and (max-width: 800px) {\n .tab-switcher.side-tabs {\n overflow-x: auto;\n }\n}\n.tab-switcher.side-tabs > .contents {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n}\n.tab-switcher.side-tabs > .tabs {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n overflow-y: auto;\n overflow-x: hidden;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n.tab-switcher.side-tabs > .tabs::after, .tab-switcher.side-tabs > .tabs::before {\n -ms-flex-negative: 0;\n flex-shrink: 0;\n -ms-flex-preferred-size: 0.5em;\n flex-basis: 0.5em;\n content: \"\";\n border-right: 1px solid;\n border-right-color: #222;\n border-right-color: var(--border, #222);\n}\n.tab-switcher.side-tabs > .tabs::after {\n -ms-flex-positive: 1;\n flex-grow: 1;\n}\n.tab-switcher.side-tabs > .tabs::before {\n -ms-flex-positive: 0;\n flex-grow: 0;\n}\n.tab-switcher.side-tabs > .tabs .tab-wrapper {\n min-width: 10em;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n@media all and (max-width: 800px) {\n .tab-switcher.side-tabs > .tabs .tab-wrapper {\n min-width: 4em;\n }\n}\n.tab-switcher.side-tabs > .tabs .tab-wrapper:not(.active)::after {\n top: 0;\n right: 0;\n bottom: 0;\n border-right: 1px solid;\n border-right-color: #222;\n border-right-color: var(--border, #222);\n}\n.tab-switcher.side-tabs > .tabs .tab-wrapper::before {\n -ms-flex: 0 0 6px;\n flex: 0 0 6px;\n content: \"\";\n border-right: 1px solid;\n border-right-color: #222;\n border-right-color: var(--border, #222);\n}\n.tab-switcher.side-tabs > .tabs .tab-wrapper:last-child .tab {\n margin-bottom: 0;\n}\n.tab-switcher.side-tabs > .tabs .tab {\n -ms-flex: 1;\n flex: 1;\n box-sizing: content-box;\n min-width: 10em;\n min-width: 1px;\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n padding-left: 1em;\n padding-right: calc(1em + 200px);\n margin-right: -200px;\n margin-left: 1em;\n}\n@media all and (max-width: 800px) {\n .tab-switcher.side-tabs > .tabs .tab {\n padding-left: 0.25em;\n padding-right: calc(.25em + 200px);\n margin-right: calc(.25em - 200px);\n margin-left: 0.25em;\n }\n .tab-switcher.side-tabs > .tabs .tab .text {\n display: none;\n }\n}\n.tab-switcher .contents {\n -ms-flex: 1 0 auto;\n flex: 1 0 auto;\n min-height: 0px;\n}\n.tab-switcher .contents .hidden {\n display: none;\n}\n.tab-switcher .contents .full-height:not(.hidden) {\n height: 100%;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n.tab-switcher .contents .full-height:not(.hidden) > *:not(.mobile-label) {\n -ms-flex: 1;\n flex: 1;\n}\n.tab-switcher .contents.scrollable-tabs {\n overflow-y: auto;\n}\n.tab-switcher .tab {\n position: relative;\n white-space: nowrap;\n padding: 6px 1em;\n background-color: #182230;\n background-color: var(--tab, #182230);\n}\n.tab-switcher .tab, .tab-switcher .tab:active .tab-icon {\n color: #b9b9ba;\n color: var(--tabText, #b9b9ba);\n}\n.tab-switcher .tab:not(.active) {\n z-index: 4;\n}\n.tab-switcher .tab:not(.active):hover {\n z-index: 6;\n}\n.tab-switcher .tab.active {\n background: transparent;\n z-index: 5;\n color: #b9b9ba;\n color: var(--tabActiveText, #b9b9ba);\n}\n.tab-switcher .tab img {\n max-height: 26px;\n vertical-align: top;\n margin-top: -5px;\n}\n.tab-switcher .tabs {\n display: -ms-flexbox;\n display: flex;\n position: relative;\n box-sizing: border-box;\n}\n.tab-switcher .tabs::after, .tab-switcher .tabs::before {\n display: block;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n}\n.tab-switcher .tab-wrapper {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n}\n.tab-switcher .tab-wrapper:not(.active)::after {\n content: \"\";\n position: absolute;\n z-index: 7;\n}\n.tab-switcher .mobile-label {\n padding-left: 0.3em;\n padding-bottom: 0.25em;\n margin-top: 0.5em;\n margin-left: 0.2em;\n margin-bottom: 0.25em;\n border-bottom: 1px solid var(--border, #222);\n}\n@media all and (min-width: 800px) {\n .tab-switcher .mobile-label {\n display: none;\n }\n}",".with-load-more-footer {\n padding: 10px;\n text-align: center;\n border-top: 1px solid;\n border-top-color: #222;\n border-top-color: var(--border, #222);\n}\n.with-load-more-footer .error {\n font-size: 14px;\n}\n.with-load-more-footer a {\n cursor: pointer;\n}"],"sourceRoot":""}
\ No newline at end of file
diff --git a/priv/static/static/emoji.json b/priv/static/static/emoji.json
deleted file mode 100644
index 12b91b3f6a..0000000000
--- a/priv/static/static/emoji.json
+++ /dev/null
@@ -1,1431 +0,0 @@
-{
- "100": "๐ฏ",
- "1234": "๐ข",
- "1st_place_medal": "๐ฅ",
- "2nd_place_medal": "๐ฅ",
- "3rd_place_medal": "๐ฅ",
- "8ball": "๐ฑ",
- "a_button_blood_type": "๐
ฐ",
- "ab": "๐",
- "abacus": "๐งฎ",
- "abc": "๐ค",
- "abcd": "๐ก",
- "accept": "๐",
- "adhesive_bandage": "๐ฉน",
- "admission_tickets": "๐",
- "adult": "๐ง",
- "aerial_tramway": "๐ก",
- "airplane": "โ",
- "airplane_arriving": "๐ฌ",
- "airplane_departure": "๐ซ",
- "alarm_clock": "โฐ",
- "alembic": "โ๏ธ",
- "alien": "๐ฝ",
- "ambulance": "๐",
- "amphora": "๐บ",
- "anchor": "โ",
- "angel": "๐ผ",
- "anger": "๐ข",
- "anger_right": "๐ฏ",
- "angry": "๐ ",
- "anguished": "๐ง",
- "ant": "๐",
- "apple": "๐",
- "aquarius": "โ",
- "aries": "โ",
- "arrow_backward": "โ๏ธ",
- "arrow_double_down": "โฌ",
- "arrow_double_up": "โซ",
- "arrow_down": "โฌ๏ธ",
- "arrow_down_small": "๐ฝ",
- "arrow_forward": "โถ๏ธ",
- "arrow_heading_down": "โคต๏ธ",
- "arrow_heading_up": "โคด๏ธ",
- "arrow_left": "โฌ
๏ธ",
- "arrow_lower_left": "โ๏ธ",
- "arrow_lower_right": "โ๏ธ",
- "arrow_right": "โก",
- "arrow_right_hook": "โช๏ธ",
- "arrow_up": "โฌ๏ธ",
- "arrow_up_down": "โ",
- "arrow_up_small": "๐ผ",
- "arrow_upper_left": "โ",
- "arrow_upper_right": "โ๏ธ",
- "arrows_clockwise": "๐",
- "arrows_counterclockwise": "๐",
- "art": "๐จ",
- "articulated_lorry": "๐",
- "artist_palette": "๐จ",
- "asterisk": "*โฃ",
- "astonished": "๐ฒ",
- "athletic_shoe": "๐",
- "atm": "๐ง",
- "atom": "โ",
- "atom_symbol": "โ๏ธ",
- "auto_rickshaw": "๐บ",
- "automobile": "๐",
- "avocado": "๐ฅ",
- "axe": "๐ช",
- "b_button_blood_type": "๐
ฑ",
- "baby": "๐ถ",
- "baby_bottle": "๐ผ",
- "baby_chick": "๐ค",
- "baby_symbol": "๐ผ",
- "back": "๐",
- "bacon": "๐ฅ",
- "badger": "๐ฆก",
- "badminton": "๐ธ",
- "bagel": "๐ฅฏ",
- "baggage_claim": "๐",
- "baguette_bread": "๐ฅ",
- "balance_scale": "โ๏ธ",
- "bald": "๐ฆฒ",
- "ballet_shoes": "๐ฉฐ",
- "balloon": "๐",
- "ballot_box": "๐ณ",
- "ballot_box_with_check": "โ๏ธ",
- "bamboo": "๐",
- "banana": "๐",
- "bangbang": "โผ๏ธ",
- "banjo": "๐ช",
- "bank": "๐ฆ",
- "bar_chart": "๐",
- "barber": "๐",
- "baseball": "โพ",
- "basket": "๐งบ",
- "basketball": "๐",
- "basketballer": "โน",
- "bat": "๐ฆ",
- "bath": "๐",
- "bathtub": "๐",
- "battery": "๐",
- "beach_umbrella": "โฑ",
- "beach_with_umbrella": "๐",
- "bear": "๐ป",
- "beard": "๐ง",
- "bearded_person": "๐ง",
- "bed": "๐",
- "bee": "๐",
- "beer": "๐บ",
- "beers": "๐ป",
- "beetle": "๐",
- "beginner": "๐ฐ",
- "bell": "๐",
- "bellhop_bell": "๐",
- "bento": "๐ฑ",
- "beverage_box": "๐ง",
- "bicyclist": "๐ด",
- "bike": "๐ฒ",
- "bikini": "๐",
- "billed_cap": "๐งข",
- "biohazard": "โฃ๏ธ",
- "bird": "๐ฆ",
- "birthday": "๐",
- "black_circle": "โซ",
- "black_heart": "๐ค",
- "black_joker": "๐",
- "black_large_square": "โฌ",
- "black_medium_small_square": "โพ",
- "black_medium_square": "โผ",
- "black_nib": "โ๏ธ",
- "black_small_square": "โช",
- "black_square_button": "๐ฒ",
- "blond_haired_person": "๐ฑ",
- "blossom": "๐ผ",
- "blowfish": "๐ก",
- "blue_book": "๐",
- "blue_car": "๐",
- "blue_circle": "๐ต",
- "blue_heart": "๐",
- "blue_square": "๐ฆ",
- "blush": "๐",
- "boar": "๐",
- "bomb": "๐ฃ",
- "bone": "๐ฆด",
- "book": "๐",
- "bookmark": "๐",
- "bookmark_tabs": "๐",
- "books": "๐",
- "boom": "๐ฅ",
- "boot": "๐ข",
- "bouquet": "๐",
- "bow": "๐",
- "bow_and_arrow": "๐น",
- "bowl_with_spoon": "๐ฅฃ",
- "bowling": "๐ณ",
- "boxing_glove": "๐ฅ",
- "boy": "๐ฆ",
- "brain": "๐ง ",
- "bread": "๐",
- "breast_feeding": "๐คฑ",
- "breastfeeding": "๐คฑ",
- "brick": "๐งฑ",
- "bride_with_veil": "๐ฐ",
- "bridge_at_night": "๐",
- "briefcase": "๐ผ",
- "briefs": "๐ฉฒ",
- "broccoli": "๐ฅฆ",
- "broken_heart": "๐",
- "broom": "๐งน",
- "brown_circle": "๐ค",
- "brown_heart": "๐ค",
- "bug": "๐",
- "building_construction": "๐",
- "bulb": "๐ก",
- "bullettrain_front": "๐
",
- "bullettrain_side": "๐",
- "burrito": "๐ฏ",
- "bus": "๐",
- "busstop": "๐",
- "bust_in_silhouette": "๐ค",
- "busts_in_silhouette": "๐ฅ",
- "butter": "๐ง",
- "butterfly": "๐ฆ",
- "cactus": "๐ต",
- "cake": "๐ฐ",
- "calendar": "๐",
- "call_me": "๐ค",
- "call_me_hand": "๐ค",
- "calling": "๐ฒ",
- "camel": "๐ซ",
- "camera": "๐ท",
- "camera_with_flash": "๐ธ",
- "camping": "๐",
- "cancer": "โ",
- "candle": "๐ฏ",
- "candy": "๐ฌ",
- "canned_food": "๐ฅซ",
- "canoe": "๐ถ",
- "capital_abcd": "๐ ",
- "capricorn": "โ",
- "card_file_box": "๐",
- "card_index": "๐",
- "card_index_dividers": "๐",
- "carousel_horse": "๐ ",
- "carrot": "๐ฅ",
- "cat": "๐ฑ",
- "cat2": "๐",
- "cd": "๐ฟ",
- "chains": "โ๏ธ",
- "chair": "๐ช",
- "champagne": "๐พ",
- "champagne_glass": "๐ฅ",
- "chart": "๐น",
- "chart_with_downwards_trend": "๐",
- "chart_with_upwards_trend": "๐",
- "check_box_with_check": "โ",
- "check_mark": "โ",
- "checkered_flag": "๐",
- "cheese": "๐ง",
- "cheese_wedge": "๐ง",
- "cherries": "๐",
- "cherry_blossom": "๐ธ",
- "chess_pawn": "โ",
- "chestnut": "๐ฐ",
- "chicken": "๐",
- "child": "๐ง",
- "children_crossing": "๐ธ",
- "chipmunk": "๐ฟ",
- "chocolate_bar": "๐ซ",
- "chopsticks": "๐ฅข",
- "christmas_tree": "๐",
- "church": "โช",
- "cinema": "๐ฆ",
- "circled_m": "โ",
- "circus_tent": "๐ช",
- "city_dusk": "๐",
- "city_sunset": "๐",
- "cityscape": "๐",
- "cityscape_at_dusk": "๐",
- "cl": "๐",
- "clap": "๐",
- "clapper": "๐ฌ",
- "classical_building": "๐",
- "clinking_glasses": "๐ฅ",
- "clipboard": "๐",
- "clock1": "๐",
- "clock10": "๐",
- "clock1030": "๐ฅ",
- "clock11": "๐",
- "clock1130": "๐ฆ",
- "clock12": "๐",
- "clock1230": "๐ง",
- "clock130": "๐",
- "clock2": "๐",
- "clock230": "๐",
- "clock3": "๐",
- "clock330": "๐",
- "clock4": "๐",
- "clock430": "๐",
- "clock5": "๐",
- "clock530": "๐ ",
- "clock6": "๐",
- "clock630": "๐ก",
- "clock7": "๐",
- "clock730": "๐ข",
- "clock8": "๐",
- "clock830": "๐ฃ",
- "clock9": "๐",
- "clock930": "๐ค",
- "closed_book": "๐",
- "closed_lock_with_key": "๐",
- "closed_umbrella": "๐",
- "cloud": "โ๏ธ",
- "cloud_with_lightning": "๐ฉ",
- "cloud_with_lightning_and_rain": "โ๏ธ",
- "cloud_with_rain": "๐ง",
- "cloud_with_snow": "๐จ",
- "clown": "๐คก",
- "clown_face": "๐คก",
- "club_suit": "โฃ๏ธ",
- "clubs": "โฃ",
- "coat": "๐งฅ",
- "cocktail": "๐ธ",
- "coconut": "๐ฅฅ",
- "coffee": "โ",
- "coffin": "โฐ๏ธ",
- "cold_face": "๐ฅถ",
- "cold_sweat": "๐ฐ",
- "comet": "โ๏ธ",
- "compass": "๐งญ",
- "compression": "๐",
- "computer": "๐ป",
- "computer_mouse": "๐ฑ",
- "confetti_ball": "๐",
- "confounded": "๐",
- "confused": "๐",
- "congratulations": "ใ",
- "construction": "๐ง",
- "construction_worker": "๐ท",
- "control_knobs": "๐",
- "convenience_store": "๐ช",
- "cookie": "๐ช",
- "cooking": "๐ณ",
- "cool": "๐",
- "cop": "๐ฎ",
- "copyright": "ยฉ",
- "corn": "๐ฝ",
- "couch_and_lamp": "๐",
- "couple": "๐ซ",
- "couple_with_heart": "๐",
- "couplekiss": "๐",
- "cow": "๐ฎ",
- "cow2": "๐",
- "cowboy": "๐ค ",
- "cowboy_hat_face": "๐ค ",
- "crab": "๐ฆ",
- "crayon": "๐",
- "crazy_face": "๐คช",
- "credit_card": "๐ณ",
- "crescent_moon": "๐",
- "cricket": "๐ฆ",
- "cricket_game": "๐",
- "crocodile": "๐",
- "croissant": "๐ฅ",
- "cross": "โ๏ธ",
- "crossed_fingers": "๐ค",
- "crossed_flags": "๐",
- "crossed_swords": "โ๏ธ",
- "crown": "๐",
- "cry": "๐ข",
- "crying_cat_face": "๐ฟ",
- "crystal_ball": "๐ฎ",
- "cucumber": "๐ฅ",
- "cup_with_straw": "๐ฅค",
- "cupcake": "๐ง",
- "cupid": "๐",
- "curling_stone": "๐ฅ",
- "curly_hair": "๐ฆฑ",
- "curly_loop": "โฐ",
- "currency_exchange": "๐ฑ",
- "curry": "๐",
- "custard": "๐ฎ",
- "customs": "๐",
- "cut_of_meat": "๐ฅฉ",
- "cyclone": "๐",
- "dagger": "๐ก",
- "dancer": "๐",
- "dancers": "๐ฏ",
- "dango": "๐ก",
- "dark_skin_tone": "๐ฟ",
- "dark_sunglasses": "๐ถ",
- "dart": "๐ฏ",
- "dash": "๐จ",
- "date": "๐
",
- "deaf_person": "๐ง",
- "deciduous_tree": "๐ณ",
- "deer": "๐ฆ",
- "department_store": "๐ฌ",
- "derelict_house": "๐",
- "desert": "๐",
- "desert_island": "๐",
- "desktop_computer": "๐ฅ",
- "detective": "๐ต",
- "diamond_shape_with_a_dot_inside": "๐ ",
- "diamond_suit": "โฆ๏ธ",
- "diamonds": "โฆ",
- "disappointed": "๐",
- "disappointed_relieved": "๐ฅ",
- "diving_mask": "๐คฟ",
- "diya_lamp": "๐ช",
- "dizzy": "๐ซ",
- "dizzy_face": "๐ต",
- "dna": "๐งฌ",
- "do_not_litter": "๐ฏ",
- "dog": "๐ถ",
- "dog2": "๐",
- "dollar": "๐ต",
- "dolls": "๐",
- "dolphin": "๐ฌ",
- "door": "๐ช",
- "double_exclamation_mark": "โผ",
- "doughnut": "๐ฉ",
- "dove": "๐",
- "down_arrow": "โฌ",
- "downleft_arrow": "โ",
- "downright_arrow": "โ",
- "dragon": "๐",
- "dragon_face": "๐ฒ",
- "dress": "๐",
- "dromedary_camel": "๐ช",
- "drooling_face": "๐คค",
- "drop_of_blood": "๐ฉธ",
- "droplet": "๐ง",
- "drum": "๐ฅ",
- "duck": "๐ฆ",
- "dumpling": "๐ฅ",
- "dvd": "๐",
- "e-mail": "๐ง",
- "eagle": "๐ฆ
",
- "ear": "๐",
- "ear_of_rice": "๐พ",
- "ear_with_hearing_aid": "๐ฆป",
- "earth_africa": "๐",
- "earth_americas": "๐",
- "earth_asia": "๐",
- "egg": "๐ฅ",
- "eggplant": "๐",
- "eight": "8โฃ",
- "eight_pointed_black_star": "โด๏ธ",
- "eight_spoked_asterisk": "โณ๏ธ",
- "eightpointed_star": "โด",
- "eightspoked_asterisk": "โณ",
- "eject_button": "โ",
- "electric_plug": "๐",
- "elephant": "๐",
- "elf": "๐ง",
- "end": "๐",
- "envelope": "โ",
- "envelope_with_arrow": "๐ฉ",
- "euro": "๐ถ",
- "european_castle": "๐ฐ",
- "european_post_office": "๐ค",
- "evergreen_tree": "๐ฒ",
- "exclamation": "โ",
- "exclamation_question_mark": "โ",
- "exploding_head": "๐คฏ",
- "expressionless": "๐",
- "eye": "๐",
- "eyeglasses": "๐",
- "eyes": "๐",
- "face_vomiting": "๐คฎ",
- "face_with_hand_over_mouth": "๐คญ",
- "face_with_headbandage": "๐ค",
- "face_with_monocle": "๐ง",
- "face_with_raised_eyebrow": "๐คจ",
- "face_with_symbols_on_mouth": "๐คฌ",
- "face_with_symbols_over_mouth": "๐คฌ",
- "face_with_thermometer": "๐ค",
- "factory": "๐ญ",
- "fairy": "๐ง",
- "falafel": "๐ง",
- "fallen_leaf": "๐",
- "family": "๐ช",
- "fast_forward": "โฉ",
- "fax": "๐ ",
- "fearful": "๐จ",
- "feet": "๐พ",
- "female_sign": "โ",
- "ferris_wheel": "๐ก",
- "ferry": "โด๏ธ",
- "field_hockey": "๐",
- "file_cabinet": "๐",
- "file_folder": "๐",
- "film_frames": "๐",
- "film_projector": "๐ฝ",
- "fingers_crossed": "๐ค",
- "fire": "๐ฅ",
- "fire_engine": "๐",
- "fire_extinguisher": "๐งฏ",
- "firecracker": "๐งจ",
- "fireworks": "๐",
- "first_place": "๐ฅ",
- "first_quarter_moon": "๐",
- "first_quarter_moon_with_face": "๐",
- "fish": "๐",
- "fish_cake": "๐ฅ",
- "fishing_pole_and_fish": "๐ฃ",
- "fist": "โ",
- "five": "5โฃ",
- "flag_black": "๐ด",
- "flag_white": "๐ณ",
- "flags": "๐",
- "flamingo": "๐ฆฉ",
- "flashlight": "๐ฆ",
- "flat_shoe": "๐ฅฟ",
- "fleur-de-lis": "โ",
- "fleurde-lis": "โ๏ธ",
- "floppy_disk": "๐พ",
- "flower_playing_cards": "๐ด",
- "flushed": "๐ณ",
- "flying_disc": "๐ฅ",
- "flying_saucer": "๐ธ",
- "fog": "๐ซ",
- "foggy": "๐",
- "foot": "๐ฆถ",
- "football": "๐",
- "footprints": "๐ฃ",
- "fork_and_knife": "๐ด",
- "fork_and_knife_with_plate": "๐ฝ",
- "fortune_cookie": "๐ฅ ",
- "fountain": "โฒ",
- "fountain_pen": "๐",
- "four": "4โฃ",
- "four_leaf_clover": "๐",
- "fox": "๐ฆ",
- "framed_picture": "๐ผ",
- "free": "๐",
- "french_bread": "๐ฅ",
- "fried_shrimp": "๐ค",
- "fries": "๐",
- "frog": "๐ธ",
- "frowning": "๐ฆ",
- "frowning_face": "โน๏ธ",
- "fuelpump": "โฝ",
- "full_moon": "๐",
- "full_moon_with_face": "๐",
- "funeral_urn": "โฑ๏ธ",
- "game_die": "๐ฒ",
- "garlic": "๐ง",
- "gear": "โ๏ธ",
- "gem": "๐",
- "gemini": "โ",
- "genie": "๐ง",
- "ghost": "๐ป",
- "gift": "๐",
- "gift_heart": "๐",
- "giraffe": "๐ฆ",
- "girl": "๐ง",
- "glass_of_milk": "๐ฅ",
- "globe_with_meridians": "๐",
- "gloves": "๐งค",
- "goal": "๐ฅ
",
- "goal_net": "๐ฅ
",
- "goat": "๐",
- "goggles": "๐ฅฝ",
- "golf": "โณ",
- "golfer": "๐",
- "gorilla": "๐ฆ",
- "grapes": "๐",
- "green_apple": "๐",
- "green_book": "๐",
- "green_circle": "๐ข",
- "green_heart": "๐",
- "green_salad": "๐ฅ",
- "green_square": "๐ฉ",
- "grey_exclamation": "โ",
- "grey_question": "โ",
- "grimacing": "๐ฌ",
- "grin": "๐",
- "grinning": "๐",
- "guard": "๐",
- "guardsman": "๐",
- "guide_dog": "๐ฆฎ",
- "guitar": "๐ธ",
- "gun": "๐ซ",
- "haircut": "๐",
- "hamburger": "๐",
- "hammer": "๐จ",
- "hammer_and_pick": "โ๏ธ",
- "hammer_and_wrench": "๐ ",
- "hamster": "๐น",
- "hand_with_fingers_splayed": "๐",
- "handbag": "๐",
- "handshake": "๐ค",
- "hash": "#โฃ",
- "hatched_chick": "๐ฅ",
- "hatching_chick": "๐ฃ",
- "head_bandage": "๐ค",
- "headphones": "๐ง",
- "hear_no_evil": "๐",
- "heart": "โค๏ธ",
- "heart_decoration": "๐",
- "heart_exclamation": "โฃ",
- "heart_eyes": "๐",
- "heart_eyes_cat": "๐ป",
- "heart_suit": "โฅ๏ธ",
- "heartbeat": "๐",
- "heartpulse": "๐",
- "hearts": "โฅ",
- "heavy_check_mark": "โ๏ธ",
- "heavy_division_sign": "โ",
- "heavy_dollar_sign": "๐ฒ",
- "heavy_minus_sign": "โ",
- "heavy_multiplication_x": "โ๏ธ",
- "heavy_plus_sign": "โ",
- "hedgehog": "๐ฆ",
- "helicopter": "๐",
- "herb": "๐ฟ",
- "hibiscus": "๐บ",
- "high_brightness": "๐",
- "high_heel": "๐ ",
- "hiking_boot": "๐ฅพ",
- "hindu_temple": "๐",
- "hippopotamus": "๐ฆ",
- "hockey": "๐",
- "hole": "๐ณ",
- "honey_pot": "๐ฏ",
- "horse": "๐ด",
- "horse_racing": "๐",
- "hospital": "๐ฅ",
- "hot_face": "๐ฅต",
- "hot_pepper": "๐ถ",
- "hot_springs": "โจ",
- "hotdog": "๐ญ",
- "hotel": "๐จ",
- "hotsprings": "โจ๏ธ",
- "hourglass": "โ",
- "hourglass_flowing_sand": "โณ",
- "house": "๐ ",
- "house_with_garden": "๐ก",
- "houses": "๐",
- "hugging": "๐ค",
- "hundred_points": "๐ฏ",
- "hushed": "๐ฏ",
- "ice": "๐ง",
- "ice_cream": "๐จ",
- "ice_hockey": "๐",
- "ice_skate": "โธ๏ธ",
- "icecream": "๐ฆ",
- "id": "๐",
- "ideograph_advantage": "๐",
- "imp": "๐ฟ",
- "inbox_tray": "๐ฅ",
- "incoming_envelope": "๐จ",
- "index_pointing_up": "โ",
- "infinity": "โพ",
- "information": "โน๏ธ",
- "information_desk_person": "๐",
- "information_source": "โน",
- "innocent": "๐",
- "input_numbers": "๐ข",
- "interrobang": "โ๏ธ",
- "iphone": "๐ฑ",
- "izakaya_lantern": "๐ฎ",
- "jack_o_lantern": "๐",
- "japan": "๐พ",
- "japanese_castle": "๐ฏ",
- "japanese_congratulations_button": "ใ๏ธ",
- "japanese_free_of_charge_button": "๐",
- "japanese_goblin": "๐บ",
- "japanese_ogre": "๐น",
- "japanese_reserved_button": "๐ฏ",
- "japanese_secret_button": "ใ๏ธ",
- "japanese_service_charge_button": "๐",
- "jeans": "๐",
- "joy": "๐",
- "joy_cat": "๐น",
- "joystick": "๐น",
- "kaaba": "๐",
- "kangaroo": "๐ฆ",
- "key": "๐",
- "keyboard": "โจ๏ธ",
- "keycap_ten": "๐",
- "kick_scooter": "๐ด",
- "kimono": "๐",
- "kiss": "๐",
- "kissing": "๐",
- "kissing_cat": "๐ฝ",
- "kissing_closed_eyes": "๐",
- "kissing_heart": "๐",
- "kissing_smiling_eyes": "๐",
- "kitchen_knife": "๐ช",
- "kite": "๐ช",
- "kiwi": "๐ฅ",
- "kiwi_fruit": "๐ฅ",
- "knife": "๐ช",
- "koala": "๐จ",
- "koko": "๐",
- "lab_coat": "๐ฅผ",
- "label": "๐ท",
- "lacrosse": "๐ฅ",
- "large_blue_diamond": "๐ท",
- "large_orange_diamond": "๐ถ",
- "last_quarter_moon": "๐",
- "last_quarter_moon_with_face": "๐",
- "last_track_button": "โฎ๏ธ",
- "latin_cross": "โ",
- "laughing": "๐",
- "leafy_green": "๐ฅฌ",
- "leaves": "๐",
- "ledger": "๐",
- "left_arrow": "โฌ
",
- "left_arrow_curving_right": "โช",
- "left_facing_fist": "๐ค",
- "left_luggage": "๐
",
- "left_right_arrow": "โ",
- "leftfacing_fist": "๐ค",
- "leftright_arrow": "โ๏ธ",
- "leftwards_arrow_with_hook": "โฉ๏ธ",
- "leg": "๐ฆต",
- "lemon": "๐",
- "leo": "โ",
- "leopard": "๐",
- "level_slider": "๐",
- "libra": "โ",
- "light_rail": "๐",
- "light_skin_tone": "๐ป",
- "link": "๐",
- "linked_paperclips": "๐",
- "lion_face": "๐ฆ",
- "lips": "๐",
- "lipstick": "๐",
- "lizard": "๐ฆ",
- "llama": "๐ฆ",
- "lobster": "๐ฆ",
- "lock": "๐",
- "lock_with_ink_pen": "๐",
- "lollipop": "๐ญ",
- "loop": "โฟ",
- "lotion_bottle": "๐งด",
- "loud_sound": "๐",
- "loudspeaker": "๐ข",
- "love_hotel": "๐ฉ",
- "love_letter": "๐",
- "love_you_gesture": "๐ค",
- "loveyou_gesture": "๐ค",
- "low_brightness": "๐
",
- "luggage": "๐งณ",
- "lying_face": "๐คฅ",
- "m": "โ๏ธ",
- "mag": "๐",
- "mag_right": "๐",
- "mage": "๐ง",
- "magnet": "๐งฒ",
- "mahjong": "๐",
- "mailbox": "๐ซ",
- "mailbox_closed": "๐ช",
- "mailbox_with_mail": "๐ฌ",
- "mailbox_with_no_mail": "๐ญ",
- "male_sign": "โ",
- "man": "๐จ",
- "man_dancing": "๐บ",
- "man_in_suit": "๐ด",
- "man_in_tuxedo": "๐คต",
- "man_with_chinese_cap": "๐ฒ",
- "man_with_gua_pi_mao": "๐ฒ",
- "man_with_turban": "๐ณ",
- "mango": "๐ฅญ",
- "mans_shoe": "๐",
- "mantelpiece_clock": "๐ฐ",
- "manual_wheelchair": "๐ฆฝ",
- "maple_leaf": "๐",
- "martial_arts_uniform": "๐ฅ",
- "mask": "๐ท",
- "massage": "๐",
- "mate": "๐ง",
- "meat_on_bone": "๐",
- "mechanical_arm": "๐ฆพ",
- "mechanical_leg": "๐ฆฟ",
- "medal": "๐
",
- "medical_symbol": "โ",
- "medium_skin_tone": "๐ฝ",
- "mediumdark_skin_tone": "๐พ",
- "mediumlight_skin_tone": "๐ผ",
- "mega": "๐ฃ",
- "melon": "๐",
- "memo": "๐",
- "menorah": "๐",
- "mens": "๐น",
- "merperson": "๐ง",
- "metal": "๐ค",
- "metro": "๐",
- "microbe": "๐ฆ ",
- "microphone": "๐ค",
- "microscope": "๐ฌ",
- "middle_finger": "๐",
- "military_medal": "๐",
- "milk": "๐ฅ",
- "milky_way": "๐",
- "minibus": "๐",
- "minidisc": "๐ฝ",
- "mobile_phone_off": "๐ด",
- "money_mouth": "๐ค",
- "money_with_wings": "๐ธ",
- "moneybag": "๐ฐ",
- "moneymouth_face": "๐ค",
- "monkey": "๐",
- "monkey_face": "๐ต",
- "monorail": "๐",
- "moon_cake": "๐ฅฎ",
- "mortar_board": "๐",
- "mosque": "๐",
- "mosquito": "๐ฆ",
- "motor_boat": "๐ฅ",
- "motor_scooter": "๐ต",
- "motorcycle": "๐",
- "motorized_wheelchair": "๐ฆผ",
- "motorway": "๐ฃ",
- "mount_fuji": "๐ป",
- "mountain": "โฐ๏ธ",
- "mountain_bicyclist": "๐ต",
- "mountain_cableway": "๐ ",
- "mountain_railway": "๐",
- "mouse": "๐ญ",
- "mouse2": "๐",
- "movie_camera": "๐ฅ",
- "moyai": "๐ฟ",
- "mrs_claus": "๐คถ",
- "multiplication_sign": "โ",
- "muscle": "๐ช",
- "mushroom": "๐",
- "musical_keyboard": "๐น",
- "musical_note": "๐ต",
- "musical_score": "๐ผ",
- "mute": "๐",
- "nail_care": "๐
",
- "name_badge": "๐",
- "national_park": "๐",
- "nauseated_face": "๐คข",
- "nazar_amulet": "๐งฟ",
- "necktie": "๐",
- "negative_squared_cross_mark": "โ",
- "nerd": "๐ค",
- "neutral_face": "๐",
- "new": "๐",
- "new_moon": "๐",
- "new_moon_with_face": "๐",
- "newspaper": "๐ฐ",
- "next_track_button": "โญ๏ธ",
- "ng": "๐",
- "night_with_stars": "๐",
- "nine": "9โฃ",
- "no_bell": "๐",
- "no_bicycles": "๐ณ",
- "no_entry": "โ",
- "no_entry_sign": "๐ซ",
- "no_good": "๐
",
- "no_mobile_phones": "๐ต",
- "no_mouth": "๐ถ",
- "no_pedestrians": "๐ท",
- "no_smoking": "๐ญ",
- "non-potable_water": "๐ฑ",
- "nose": "๐",
- "notebook": "๐",
- "notebook_with_decorative_cover": "๐",
- "notes": "๐ถ",
- "nut_and_bolt": "๐ฉ",
- "o": "โญ",
- "o_button_blood_type": "๐
พ",
- "ocean": "๐",
- "octagonal_sign": "๐",
- "octopus": "๐",
- "oden": "๐ข",
- "office": "๐ข",
- "oil_drum": "๐ข",
- "ok": "๐",
- "ok_hand": "๐",
- "ok_woman": "๐",
- "old_key": "๐",
- "older_adult": "๐ง",
- "older_man": "๐ด",
- "older_person": "๐ง",
- "older_woman": "๐ต",
- "om_symbol": "๐",
- "on": "๐",
- "oncoming_automobile": "๐",
- "oncoming_bus": "๐",
- "oncoming_fist": "๐",
- "oncoming_police_car": "๐",
- "oncoming_taxi": "๐",
- "one": "1โฃ",
- "onepiece_swimsuit": "๐ฉฑ",
- "onion": "๐ง
",
- "open_file_folder": "๐",
- "open_hands": "๐",
- "open_mouth": "๐ฎ",
- "ophiuchus": "โ",
- "orange_book": "๐",
- "orange_circle": "๐ ",
- "orange_heart": "๐งก",
- "orange_square": "๐ง",
- "orangutan": "๐ฆง",
- "orthodox_cross": "โฆ๏ธ",
- "otter": "๐ฆฆ",
- "outbox_tray": "๐ค",
- "owl": "๐ฆ",
- "ox": "๐",
- "oyster": "๐ฆช",
- "p_button": "๐
ฟ",
- "package": "๐ฆ",
- "page_facing_up": "๐",
- "page_with_curl": "๐",
- "pager": "๐",
- "paintbrush": "๐",
- "palm_tree": "๐ด",
- "palms_up_together": "๐คฒ",
- "pancakes": "๐ฅ",
- "panda_face": "๐ผ",
- "paperclip": "๐",
- "parachute": "๐ช",
- "parrot": "๐ฆ",
- "part_alternation_mark": "ใฝ",
- "partly_sunny": "โ
",
- "partying_face": "๐ฅณ",
- "passenger_ship": "๐ณ",
- "passport_control": "๐",
- "pause_button": "โธ๏ธ",
- "peace": "โฎ",
- "peace_symbol": "โฎ๏ธ",
- "peach": "๐",
- "peacock": "๐ฆ",
- "peanuts": "๐ฅ",
- "pear": "๐",
- "pen": "๐",
- "pencil": "๐",
- "pencil2": "โ",
- "penguin": "๐ง",
- "pensive": "๐",
- "people_with_bunny_ears_partying": "๐ฏ",
- "people_wrestling": "๐คผ",
- "performing_arts": "๐ญ",
- "persevere": "๐ฃ",
- "person": "๐ง",
- "person_biking": "๐ด",
- "person_bouncing_ball": "โน๏ธ",
- "person_bowing": "๐",
- "person_cartwheeling": "๐คธ",
- "person_climbing": "๐ง",
- "person_doing_cartwheel": "๐คธ",
- "person_facepalming": "๐คฆ",
- "person_fencing": "๐คบ",
- "person_frowning": "๐",
- "person_gesturing_no": "๐
",
- "person_gesturing_ok": "๐",
- "person_getting_haircut": "๐",
- "person_getting_massage": "๐",
- "person_in_lotus_position": "๐ง",
- "person_in_steamy_room": "๐ง",
- "person_juggling": "๐คน",
- "person_kneeling": "๐ง",
- "person_mountain_biking": "๐ต",
- "person_playing_handball": "๐คพ",
- "person_playing_water_polo": "๐คฝ",
- "person_pouting": "๐",
- "person_raising_hand": "๐",
- "person_rowing_boat": "๐ฃ",
- "person_running": "๐",
- "person_shrugging": "๐คท",
- "person_standing": "๐ง",
- "person_surfing": "๐",
- "person_swimming": "๐",
- "person_tipping_hand": "๐",
- "person_walking": "๐ถ",
- "person_wearing_turban": "๐ณ",
- "person_with_blond_hair": "๐ฑ",
- "person_with_pouting_face": "๐",
- "petri_dish": "๐งซ",
- "pick": "โ๏ธ",
- "pie": "๐ฅง",
- "pig": "๐ท",
- "pig2": "๐",
- "pig_nose": "๐ฝ",
- "pill": "๐",
- "pinching_hand": "๐ค",
- "pineapple": "๐",
- "ping_pong": "๐",
- "pisces": "โ",
- "pizza": "๐",
- "place_of_worship": "๐",
- "play_button": "โถ",
- "play_or_pause_button": "โฏ๏ธ",
- "play_pause": "โฏ",
- "pleading_face": "๐ฅบ",
- "point_down": "๐",
- "point_left": "๐",
- "point_right": "๐",
- "point_up": "โ๏ธ",
- "point_up_2": "๐",
- "police_car": "๐",
- "police_officer": "๐ฎ",
- "poodle": "๐ฉ",
- "poop": "๐ฉ",
- "popcorn": "๐ฟ",
- "post_office": "๐ฃ",
- "postal_horn": "๐ฏ",
- "postbox": "๐ฎ",
- "potable_water": "๐ฐ",
- "potato": "๐ฅ",
- "pouch": "๐",
- "poultry_leg": "๐",
- "pound": "๐ท",
- "pouting_cat": "๐พ",
- "pray": "๐",
- "prayer_beads": "๐ฟ",
- "pregnant_woman": "๐คฐ",
- "pretzel": "๐ฅจ",
- "prince": "๐คด",
- "princess": "๐ธ",
- "printer": "๐จ",
- "probing_cane": "๐ฆฏ",
- "punch": "๐",
- "purple_circle": "๐ฃ",
- "purple_heart": "๐",
- "purse": "๐",
- "pushpin": "๐",
- "put_litter_in_its_place": "๐ฎ",
- "puzzle_piece": "๐งฉ",
- "question": "โ",
- "rabbit": "๐ฐ",
- "rabbit2": "๐",
- "raccoon": "๐ฆ",
- "racehorse": "๐",
- "racing_car": "๐",
- "radio": "๐ป",
- "radio_button": "๐",
- "radioactive": "โข๏ธ",
- "rage": "๐ก",
- "railway_car": "๐",
- "railway_track": "๐ค",
- "rainbow": "๐",
- "raised_back_of_hand": "๐ค",
- "raised_hand": "โ",
- "raised_hands": "๐",
- "raising_hand": "๐",
- "ram": "๐",
- "ramen": "๐",
- "rat": "๐",
- "razor": "๐ช",
- "receipt": "๐งพ",
- "record_button": "โบ๏ธ",
- "recycle": "โป",
- "recycling_symbol": "โป๏ธ",
- "red_car": "๐",
- "red_circle": "๐ด",
- "red_envelope": "๐งง",
- "red_hair": "๐ฆฐ",
- "red_heart": "โค",
- "red_square": "๐ฅ",
- "regional_indicator_a": "๐ฆ",
- "regional_indicator_b": "๐ง",
- "regional_indicator_c": "๐จ",
- "regional_indicator_d": "๐ฉ",
- "regional_indicator_e": "๐ช",
- "regional_indicator_f": "๐ซ",
- "regional_indicator_g": "๐ฌ",
- "regional_indicator_h": "๐ญ",
- "regional_indicator_i": "๐ฎ",
- "regional_indicator_j": "๐ฏ",
- "regional_indicator_k": "๐ฐ",
- "regional_indicator_l": "๐ฑ",
- "regional_indicator_m": "๐ฒ",
- "regional_indicator_n": "๐ณ",
- "regional_indicator_o": "๐ด",
- "regional_indicator_p": "๐ต",
- "regional_indicator_q": "๐ถ",
- "regional_indicator_r": "๐ท",
- "regional_indicator_s": "๐ธ",
- "regional_indicator_t": "๐น",
- "regional_indicator_u": "๐บ",
- "regional_indicator_v": "๐ป",
- "regional_indicator_w": "๐ผ",
- "regional_indicator_x": "๐ฝ",
- "regional_indicator_y": "๐พ",
- "regional_indicator_z": "๐ฟ",
- "registered": "ยฎ",
- "relieved": "๐",
- "reminder_ribbon": "๐",
- "repeat": "๐",
- "repeat_one": "๐",
- "rescue_workerโs_helmet": "โ๏ธ",
- "restroom": "๐ป",
- "reverse_button": "โ",
- "revolving_hearts": "๐",
- "rewind": "โช",
- "rhino": "๐ฆ",
- "rhinoceros": "๐ฆ",
- "ribbon": "๐",
- "rice": "๐",
- "rice_ball": "๐",
- "rice_cracker": "๐",
- "rice_scene": "๐",
- "right_arrow": "โก๏ธ",
- "right_arrow_curving_down": "โคต",
- "right_arrow_curving_left": "โฉ",
- "right_arrow_curving_up": "โคด",
- "right_facing_fist": "๐ค",
- "rightfacing_fist": "๐ค",
- "ring": "๐",
- "ringed_planet": "๐ช",
- "robot": "๐ค",
- "rocket": "๐",
- "rofl": "๐คฃ",
- "roll_of_paper": "๐งป",
- "rolledup_newspaper": "๐",
- "roller_coaster": "๐ข",
- "rolling_eyes": "๐",
- "rolling_on_the_floor_laughing": "๐คฃ",
- "rooster": "๐",
- "rose": "๐น",
- "rosette": "๐ต",
- "rotating_light": "๐จ",
- "round_pushpin": "๐",
- "rowboat": "๐ฃ",
- "rugby_football": "๐",
- "runner": "๐",
- "running_shirt_with_sash": "๐ฝ",
- "safety_pin": "๐งท",
- "safety_vest": "๐ฆบ",
- "sagittarius": "โ",
- "sailboat": "โต",
- "sake": "๐ถ",
- "salad": "๐ฅ",
- "salt": "๐ง",
- "sandal": "๐ก",
- "sandwich": "๐ฅช",
- "santa": "๐
",
- "sari": "๐ฅป",
- "satellite": "๐ก",
- "sauropod": "๐ฆ",
- "saxophone": "๐ท",
- "scales": "โ",
- "scarf": "๐งฃ",
- "school": "๐ซ",
- "school_satchel": "๐",
- "scissors": "โ",
- "scooter": "๐ด",
- "scorpion": "๐ฆ",
- "scorpius": "โ",
- "scream": "๐ฑ",
- "scream_cat": "๐",
- "scroll": "๐",
- "seat": "๐บ",
- "second_place": "๐ฅ",
- "secret": "ใ",
- "see_no_evil": "๐",
- "seedling": "๐ฑ",
- "selfie": "๐คณ",
- "seven": "7โฃ",
- "shallow_pan_of_food": "๐ฅ",
- "shamrock": "โ๏ธ",
- "shark": "๐ฆ",
- "shaved_ice": "๐ง",
- "sheep": "๐",
- "shell": "๐",
- "shield": "๐ก",
- "shinto_shrine": "โฉ๏ธ",
- "ship": "๐ข",
- "shirt": "๐",
- "shopping_bags": "๐",
- "shopping_cart": "๐",
- "shorts": "๐ฉณ",
- "shower": "๐ฟ",
- "shrimp": "๐ฆ",
- "shushing_face": "๐คซ",
- "sign_of_the_horns": "๐ค",
- "signal_strength": "๐ถ",
- "six": "6โฃ",
- "six_pointed_star": "๐ฏ",
- "skateboard": "๐น",
- "ski": "๐ฟ",
- "skier": "โท๏ธ",
- "skull": "๐",
- "skull_and_crossbones": "โ ๏ธ",
- "skull_crossbones": "โ ",
- "skunk": "๐ฆจ",
- "sled": "๐ท",
- "sleeping": "๐ด",
- "sleeping_accommodation": "๐",
- "sleepy": "๐ช",
- "slight_frown": "๐",
- "slight_smile": "๐",
- "slightly_frowning_face": "๐",
- "slot_machine": "๐ฐ",
- "sloth": "๐ฆฅ",
- "small_airplane": "๐ฉ",
- "small_blue_diamond": "๐น",
- "small_orange_diamond": "๐ธ",
- "small_red_triangle": "๐บ",
- "small_red_triangle_down": "๐ป",
- "smile": "๐",
- "smile_cat": "๐ธ",
- "smiley": "๐",
- "smiley_cat": "๐บ",
- "smiling": "โบ๏ธ",
- "smiling_face": "โบ",
- "smiling_face_with_hearts": "๐ฅฐ",
- "smiling_imp": "๐",
- "smirk": "๐",
- "smirk_cat": "๐ผ",
- "smoking": "๐ฌ",
- "snail": "๐",
- "snake": "๐",
- "sneezing_face": "๐คง",
- "snowboarder": "๐",
- "snowcapped_mountain": "๐",
- "snowflake": "โ",
- "snowman": "โ",
- "soap": "๐งผ",
- "sob": "๐ญ",
- "soccer": "โฝ",
- "socks": "๐งฆ",
- "softball": "๐ฅ",
- "soon": "๐",
- "sos": "๐",
- "sound": "๐",
- "space_invader": "๐พ",
- "spade_suit": "โ ๏ธ",
- "spades": "โ ",
- "spaghetti": "๐",
- "sparkle": "โ",
- "sparkler": "๐",
- "sparkles": "โจ",
- "sparkling_heart": "๐",
- "speak_no_evil": "๐",
- "speaker": "๐",
- "speaking_head": "๐ฃ",
- "speech_balloon": "๐ฌ",
- "speech_left": "๐จ",
- "speedboat": "๐ค",
- "spider": "๐ท",
- "spider_web": "๐ธ",
- "spiral_calendar": "๐",
- "spiral_notepad": "๐",
- "sponge": "๐งฝ",
- "spoon": "๐ฅ",
- "squid": "๐ฆ",
- "stadium": "๐",
- "star": "โญ",
- "star2": "๐",
- "star_and_crescent": "โช๏ธ",
- "star_of_david": "โก",
- "star_struck": "๐คฉ",
- "stars": "๐ ",
- "starstruck": "๐คฉ",
- "station": "๐",
- "statue_of_liberty": "๐ฝ",
- "steam_locomotive": "๐",
- "stethoscope": "๐ฉบ",
- "stew": "๐ฒ",
- "stop_button": "โน๏ธ",
- "stopwatch": "โฑ๏ธ",
- "straight_ruler": "๐",
- "strawberry": "๐",
- "stuck_out_tongue": "๐",
- "stuck_out_tongue_closed_eyes": "๐",
- "stuck_out_tongue_winking_eye": "๐",
- "studio_microphone": "๐",
- "stuffed_flatbread": "๐ฅ",
- "sun": "โ",
- "sun_behind_large_cloud": "๐ฅ",
- "sun_behind_rain_cloud": "๐ฆ",
- "sun_behind_small_cloud": "๐ค",
- "sun_with_face": "๐",
- "sunflower": "๐ป",
- "sunglasses": "๐",
- "sunny": "โ๏ธ",
- "sunrise": "๐
",
- "sunrise_over_mountains": "๐",
- "superhero": "๐ฆธ",
- "supervillain": "๐ฆน",
- "surfer": "๐",
- "sushi": "๐ฃ",
- "suspension_railway": "๐",
- "swan": "๐ฆข",
- "sweat": "๐",
- "sweat_drops": "๐ฆ",
- "sweat_smile": "๐
",
- "sweet_potato": "๐ ",
- "swimmer": "๐",
- "symbols": "๐ฃ",
- "synagogue": "๐",
- "syringe": "๐",
- "t_rex": "๐ฆ",
- "taco": "๐ฎ",
- "tada": "๐",
- "takeout_box": "๐ฅก",
- "tanabata_tree": "๐",
- "tangerine": "๐",
- "taurus": "โ",
- "taxi": "๐",
- "tea": "๐ต",
- "teddy_bear": "๐งธ",
- "telephone": "โ",
- "telephone_receiver": "๐",
- "telescope": "๐ญ",
- "tennis": "๐พ",
- "tent": "โบ",
- "test_tube": "๐งช",
- "thermometer": "๐ก",
- "thermometer_face": "๐ค",
- "thinking": "๐ค",
- "third_place": "๐ฅ",
- "thought_balloon": "๐ญ",
- "thread": "๐งต",
- "three": "3โฃ",
- "thumbsdown": "๐",
- "thumbsup": "๐",
- "ticket": "๐ซ",
- "tiger": "๐ฏ",
- "tiger2": "๐
",
- "timer_clock": "โฒ๏ธ",
- "tired_face": "๐ซ",
- "tm": "โข",
- "toilet": "๐ฝ",
- "tokyo_tower": "๐ผ",
- "tomato": "๐
",
- "tone1": "๐ป",
- "tone2": "๐ผ",
- "tone3": "๐ฝ",
- "tone4": "๐พ",
- "tone5": "๐ฟ",
- "tongue": "๐
",
- "toolbox": "๐งฐ",
- "tooth": "๐ฆท",
- "top": "๐",
- "tophat": "๐ฉ",
- "tornado": "๐ช",
- "track_next": "โญ",
- "track_previous": "โฎ",
- "trackball": "๐ฒ",
- "tractor": "๐",
- "trade_mark": "โข๏ธ",
- "traffic_light": "๐ฅ",
- "train": "๐",
- "train2": "๐",
- "tram": "๐",
- "trex": "๐ฆ",
- "triangular_flag_on_post": "๐ฉ",
- "triangular_ruler": "๐",
- "trident": "๐ฑ",
- "triumph": "๐ค",
- "trolleybus": "๐",
- "trophy": "๐",
- "tropical_drink": "๐น",
- "tropical_fish": "๐ ",
- "truck": "๐",
- "trumpet": "๐บ",
- "tulip": "๐ท",
- "tumbler_glass": "๐ฅ",
- "turkey": "๐ฆ",
- "turtle": "๐ข",
- "tv": "๐บ",
- "twisted_rightwards_arrows": "๐",
- "two": "2โฃ",
- "two_hearts": "๐",
- "two_men_holding_hands": "๐ฌ",
- "two_women_holding_hands": "๐ญ",
- "u5272": "๐น",
- "u5408": "๐ด",
- "u55b6": "๐บ",
- "u6307": "๐ฏ",
- "u6708": "๐ท",
- "u6709": "๐ถ",
- "u6e80": "๐ต",
- "u7121": "๐",
- "u7533": "๐ธ",
- "u7981": "๐ฒ",
- "u7a7a": "๐ณ",
- "umbrella": "โ",
- "umbrella_on_ground": "โฑ๏ธ",
- "unamused": "๐",
- "underage": "๐",
- "unicorn": "๐ฆ",
- "unlock": "๐",
- "up": "๐",
- "up_arrow": "โฌ",
- "updown_arrow": "โ๏ธ",
- "upleft_arrow": "โ๏ธ",
- "upright_arrow": "โ",
- "upside_down": "๐",
- "v": "โ๏ธ",
- "vampire": "๐ง",
- "vertical_traffic_light": "๐ฆ",
- "vhs": "๐ผ",
- "vibration_mode": "๐ณ",
- "victory_hand": "โ",
- "video_camera": "๐น",
- "video_game": "๐ฎ",
- "violin": "๐ป",
- "virgo": "โ",
- "volcano": "๐",
- "volleyball": "๐",
- "vs": "๐",
- "vulcan": "๐",
- "vulcan_salute": "๐",
- "waffle": "๐ง",
- "walking": "๐ถ",
- "waning_crescent_moon": "๐",
- "waning_gibbous_moon": "๐",
- "warning": "โ ",
- "wastebasket": "๐",
- "watch": "โ",
- "water_buffalo": "๐",
- "watermelon": "๐",
- "wave": "๐",
- "wavy_dash": "ใฐ๏ธ",
- "waxing_crescent_moon": "๐",
- "waxing_gibbous_moon": "๐",
- "wc": "๐พ",
- "weary": "๐ฉ",
- "wedding": "๐",
- "weightlifter": "๐",
- "whale": "๐ณ",
- "whale2": "๐",
- "wheel_of_dharma": "โธ๏ธ",
- "wheelchair": "โฟ",
- "white_check_mark": "โ
",
- "white_circle": "โช",
- "white_flower": "๐ฎ",
- "white_hair": "๐ฆณ",
- "white_heart": "๐ค",
- "white_large_square": "โฌ",
- "white_medium_small_square": "โฝ",
- "white_medium_square": "โป๏ธ",
- "white_small_square": "โซ๏ธ",
- "white_square_button": "๐ณ",
- "wilted_flower": "๐ฅ",
- "wilted_rose": "๐ฅ",
- "wind_blowing_face": "๐ฌ",
- "wind_chime": "๐",
- "wine_glass": "๐ท",
- "wink": "๐",
- "wolf": "๐บ",
- "woman": "๐ฉ",
- "woman_with_headscarf": "๐ง",
- "womans_clothes": "๐",
- "womans_hat": "๐",
- "womens": "๐บ",
- "woozy_face": "๐ฅด",
- "world_map": "๐บ",
- "worried": "๐",
- "wrench": "๐ง",
- "writing_hand": "โ๏ธ",
- "x": "โ",
- "yarn": "๐งถ",
- "yawning_face": "๐ฅฑ",
- "yellow_circle": "๐ก",
- "yellow_heart": "๐",
- "yellow_square": "๐จ",
- "yen": "๐ด",
- "yin_yang": "โฏ๏ธ",
- "yoyo": "๐ช",
- "yum": "๐",
- "zany_face": "๐คช",
- "zap": "โก",
- "zebra": "๐ฆ",
- "zero": "0โฃ",
- "zipper_mouth": "๐ค",
- "zombie": "๐ง",
- "zzz": "๐ค"
-}
\ No newline at end of file
diff --git a/priv/static/static/img/nsfw.74818f9.png b/priv/static/static/img/nsfw.74818f9.png
deleted file mode 100644
index d251377676..0000000000
Binary files a/priv/static/static/img/nsfw.74818f9.png and /dev/null differ
diff --git a/priv/static/static/js/10.02ffbc25214f297f720f.js b/priv/static/static/js/10.02ffbc25214f297f720f.js
deleted file mode 100644
index fbe4267107..0000000000
Binary files a/priv/static/static/js/10.02ffbc25214f297f720f.js and /dev/null differ
diff --git a/priv/static/static/js/10.02ffbc25214f297f720f.js.map b/priv/static/static/js/10.02ffbc25214f297f720f.js.map
deleted file mode 100644
index 6b230613d1..0000000000
Binary files a/priv/static/static/js/10.02ffbc25214f297f720f.js.map and /dev/null differ
diff --git a/priv/static/static/js/11.c173c6036fb3af5581b3.js b/priv/static/static/js/11.c173c6036fb3af5581b3.js
deleted file mode 100644
index b693d4c538..0000000000
Binary files a/priv/static/static/js/11.c173c6036fb3af5581b3.js and /dev/null differ
diff --git a/priv/static/static/js/11.c173c6036fb3af5581b3.js.map b/priv/static/static/js/11.c173c6036fb3af5581b3.js.map
deleted file mode 100644
index 6fc07fd8a9..0000000000
Binary files a/priv/static/static/js/11.c173c6036fb3af5581b3.js.map and /dev/null differ
diff --git a/priv/static/static/js/12.5ca41e245bb40263bc7f.js b/priv/static/static/js/12.5ca41e245bb40263bc7f.js
deleted file mode 100644
index a22fcc522d..0000000000
Binary files a/priv/static/static/js/12.5ca41e245bb40263bc7f.js and /dev/null differ
diff --git a/priv/static/static/js/12.5ca41e245bb40263bc7f.js.map b/priv/static/static/js/12.5ca41e245bb40263bc7f.js.map
deleted file mode 100644
index 7621724841..0000000000
Binary files a/priv/static/static/js/12.5ca41e245bb40263bc7f.js.map and /dev/null differ
diff --git a/priv/static/static/js/13.99621e6c47936075b44d.js b/priv/static/static/js/13.99621e6c47936075b44d.js
deleted file mode 100644
index ef26b927bb..0000000000
Binary files a/priv/static/static/js/13.99621e6c47936075b44d.js and /dev/null differ
diff --git a/priv/static/static/js/13.99621e6c47936075b44d.js.map b/priv/static/static/js/13.99621e6c47936075b44d.js.map
deleted file mode 100644
index eb79bff038..0000000000
Binary files a/priv/static/static/js/13.99621e6c47936075b44d.js.map and /dev/null differ
diff --git a/priv/static/static/js/14.4e05e7c284119777ecc5.js b/priv/static/static/js/14.4e05e7c284119777ecc5.js
deleted file mode 100644
index 6f5728bf6c..0000000000
Binary files a/priv/static/static/js/14.4e05e7c284119777ecc5.js and /dev/null differ
diff --git a/priv/static/static/js/14.4e05e7c284119777ecc5.js.map b/priv/static/static/js/14.4e05e7c284119777ecc5.js.map
deleted file mode 100644
index d219c6115c..0000000000
Binary files a/priv/static/static/js/14.4e05e7c284119777ecc5.js.map and /dev/null differ
diff --git a/priv/static/static/js/15.23f179cc3adc903bb537.js b/priv/static/static/js/15.23f179cc3adc903bb537.js
deleted file mode 100644
index d87608e34b..0000000000
Binary files a/priv/static/static/js/15.23f179cc3adc903bb537.js and /dev/null differ
diff --git a/priv/static/static/js/15.23f179cc3adc903bb537.js.map b/priv/static/static/js/15.23f179cc3adc903bb537.js.map
deleted file mode 100644
index 15811ea18c..0000000000
Binary files a/priv/static/static/js/15.23f179cc3adc903bb537.js.map and /dev/null differ
diff --git a/priv/static/static/js/16.43dd2c64dcb160dd96a6.js b/priv/static/static/js/16.43dd2c64dcb160dd96a6.js
deleted file mode 100644
index abed0132fd..0000000000
Binary files a/priv/static/static/js/16.43dd2c64dcb160dd96a6.js and /dev/null differ
diff --git a/priv/static/static/js/16.43dd2c64dcb160dd96a6.js.map b/priv/static/static/js/16.43dd2c64dcb160dd96a6.js.map
deleted file mode 100644
index 20ab38e817..0000000000
Binary files a/priv/static/static/js/16.43dd2c64dcb160dd96a6.js.map and /dev/null differ
diff --git a/priv/static/static/js/17.d1deeeb81b7cab98b068.js b/priv/static/static/js/17.d1deeeb81b7cab98b068.js
deleted file mode 100644
index 519a6e2bd8..0000000000
Binary files a/priv/static/static/js/17.d1deeeb81b7cab98b068.js and /dev/null differ
diff --git a/priv/static/static/js/17.d1deeeb81b7cab98b068.js.map b/priv/static/static/js/17.d1deeeb81b7cab98b068.js.map
deleted file mode 100644
index 156fad930f..0000000000
Binary files a/priv/static/static/js/17.d1deeeb81b7cab98b068.js.map and /dev/null differ
diff --git a/priv/static/static/js/18.a4d5b399e228a6a45a7b.js b/priv/static/static/js/18.a4d5b399e228a6a45a7b.js
deleted file mode 100644
index 1b17be977d..0000000000
Binary files a/priv/static/static/js/18.a4d5b399e228a6a45a7b.js and /dev/null differ
diff --git a/priv/static/static/js/18.a4d5b399e228a6a45a7b.js.map b/priv/static/static/js/18.a4d5b399e228a6a45a7b.js.map
deleted file mode 100644
index 5e5264405c..0000000000
Binary files a/priv/static/static/js/18.a4d5b399e228a6a45a7b.js.map and /dev/null differ
diff --git a/priv/static/static/js/19.e513835c3274271258fa.js b/priv/static/static/js/19.e513835c3274271258fa.js
deleted file mode 100644
index 1a4c2d230b..0000000000
Binary files a/priv/static/static/js/19.e513835c3274271258fa.js and /dev/null differ
diff --git a/priv/static/static/js/19.e513835c3274271258fa.js.map b/priv/static/static/js/19.e513835c3274271258fa.js.map
deleted file mode 100644
index d92c8eeac8..0000000000
Binary files a/priv/static/static/js/19.e513835c3274271258fa.js.map and /dev/null differ
diff --git a/priv/static/static/js/2.fec2056b00b4fa3921ba.js b/priv/static/static/js/2.fec2056b00b4fa3921ba.js
deleted file mode 100644
index 483720e2ff..0000000000
Binary files a/priv/static/static/js/2.fec2056b00b4fa3921ba.js and /dev/null differ
diff --git a/priv/static/static/js/2.fec2056b00b4fa3921ba.js.map b/priv/static/static/js/2.fec2056b00b4fa3921ba.js.map
deleted file mode 100644
index 31d328177b..0000000000
Binary files a/priv/static/static/js/2.fec2056b00b4fa3921ba.js.map and /dev/null differ
diff --git a/priv/static/static/js/20.683b112f4dcea887f707.js b/priv/static/static/js/20.683b112f4dcea887f707.js
deleted file mode 100644
index 726530149c..0000000000
Binary files a/priv/static/static/js/20.683b112f4dcea887f707.js and /dev/null differ
diff --git a/priv/static/static/js/20.683b112f4dcea887f707.js.map b/priv/static/static/js/20.683b112f4dcea887f707.js.map
deleted file mode 100644
index 094f913dba..0000000000
Binary files a/priv/static/static/js/20.683b112f4dcea887f707.js.map and /dev/null differ
diff --git a/priv/static/static/js/21.b2844ccdcfc3c8191e8e.js b/priv/static/static/js/21.b2844ccdcfc3c8191e8e.js
deleted file mode 100644
index c363a2197a..0000000000
Binary files a/priv/static/static/js/21.b2844ccdcfc3c8191e8e.js and /dev/null differ
diff --git a/priv/static/static/js/21.b2844ccdcfc3c8191e8e.js.map b/priv/static/static/js/21.b2844ccdcfc3c8191e8e.js.map
deleted file mode 100644
index b5b25eb317..0000000000
Binary files a/priv/static/static/js/21.b2844ccdcfc3c8191e8e.js.map and /dev/null differ
diff --git a/priv/static/static/js/22.68c0a771d79e3383f5e8.js b/priv/static/static/js/22.68c0a771d79e3383f5e8.js
deleted file mode 100644
index f982b241b7..0000000000
Binary files a/priv/static/static/js/22.68c0a771d79e3383f5e8.js and /dev/null differ
diff --git a/priv/static/static/js/22.68c0a771d79e3383f5e8.js.map b/priv/static/static/js/22.68c0a771d79e3383f5e8.js.map
deleted file mode 100644
index 10a44dd2e2..0000000000
Binary files a/priv/static/static/js/22.68c0a771d79e3383f5e8.js.map and /dev/null differ
diff --git a/priv/static/static/js/23.0b6cdf4c9dc52c4291c0.js b/priv/static/static/js/23.0b6cdf4c9dc52c4291c0.js
deleted file mode 100644
index 3d67019894..0000000000
Binary files a/priv/static/static/js/23.0b6cdf4c9dc52c4291c0.js and /dev/null differ
diff --git a/priv/static/static/js/23.0b6cdf4c9dc52c4291c0.js.map b/priv/static/static/js/23.0b6cdf4c9dc52c4291c0.js.map
deleted file mode 100644
index f5200b9dc1..0000000000
Binary files a/priv/static/static/js/23.0b6cdf4c9dc52c4291c0.js.map and /dev/null differ
diff --git a/priv/static/static/js/24.5cfb87799bd882b933dd.js b/priv/static/static/js/24.5cfb87799bd882b933dd.js
deleted file mode 100644
index 811c4fa526..0000000000
Binary files a/priv/static/static/js/24.5cfb87799bd882b933dd.js and /dev/null differ
diff --git a/priv/static/static/js/24.5cfb87799bd882b933dd.js.map b/priv/static/static/js/24.5cfb87799bd882b933dd.js.map
deleted file mode 100644
index c03306f8ac..0000000000
Binary files a/priv/static/static/js/24.5cfb87799bd882b933dd.js.map and /dev/null differ
diff --git a/priv/static/static/js/25.8185e4d775cea9fe47e1.js b/priv/static/static/js/25.8185e4d775cea9fe47e1.js
deleted file mode 100644
index ca0e229579..0000000000
Binary files a/priv/static/static/js/25.8185e4d775cea9fe47e1.js and /dev/null differ
diff --git a/priv/static/static/js/25.8185e4d775cea9fe47e1.js.map b/priv/static/static/js/25.8185e4d775cea9fe47e1.js.map
deleted file mode 100644
index d559ea56ba..0000000000
Binary files a/priv/static/static/js/25.8185e4d775cea9fe47e1.js.map and /dev/null differ
diff --git a/priv/static/static/js/26.34ec129dd8f860ce4a8e.js b/priv/static/static/js/26.34ec129dd8f860ce4a8e.js
deleted file mode 100644
index 7970215778..0000000000
Binary files a/priv/static/static/js/26.34ec129dd8f860ce4a8e.js and /dev/null differ
diff --git a/priv/static/static/js/26.34ec129dd8f860ce4a8e.js.map b/priv/static/static/js/26.34ec129dd8f860ce4a8e.js.map
deleted file mode 100644
index abff4e927a..0000000000
Binary files a/priv/static/static/js/26.34ec129dd8f860ce4a8e.js.map and /dev/null differ
diff --git a/priv/static/static/js/27.0f4a5145681cfb5a896e.js b/priv/static/static/js/27.0f4a5145681cfb5a896e.js
deleted file mode 100644
index 5df92f6ada..0000000000
Binary files a/priv/static/static/js/27.0f4a5145681cfb5a896e.js and /dev/null differ
diff --git a/priv/static/static/js/27.0f4a5145681cfb5a896e.js.map b/priv/static/static/js/27.0f4a5145681cfb5a896e.js.map
deleted file mode 100644
index da741bf417..0000000000
Binary files a/priv/static/static/js/27.0f4a5145681cfb5a896e.js.map and /dev/null differ
diff --git a/priv/static/static/js/28.75c01cd71372c39d5af8.js b/priv/static/static/js/28.75c01cd71372c39d5af8.js
deleted file mode 100644
index 63067ea182..0000000000
Binary files a/priv/static/static/js/28.75c01cd71372c39d5af8.js and /dev/null differ
diff --git a/priv/static/static/js/28.75c01cd71372c39d5af8.js.map b/priv/static/static/js/28.75c01cd71372c39d5af8.js.map
deleted file mode 100644
index 4b21e788e7..0000000000
Binary files a/priv/static/static/js/28.75c01cd71372c39d5af8.js.map and /dev/null differ
diff --git a/priv/static/static/js/29.b53cf1f3bcece005d78a.js b/priv/static/static/js/29.b53cf1f3bcece005d78a.js
deleted file mode 100644
index 3b357be951..0000000000
Binary files a/priv/static/static/js/29.b53cf1f3bcece005d78a.js and /dev/null differ
diff --git a/priv/static/static/js/29.b53cf1f3bcece005d78a.js.map b/priv/static/static/js/29.b53cf1f3bcece005d78a.js.map
deleted file mode 100644
index f3d6781f8e..0000000000
Binary files a/priv/static/static/js/29.b53cf1f3bcece005d78a.js.map and /dev/null differ
diff --git a/priv/static/static/js/3.bde677e65143f0cd1105.js b/priv/static/static/js/3.bde677e65143f0cd1105.js
deleted file mode 100644
index 4bea37abd9..0000000000
Binary files a/priv/static/static/js/3.bde677e65143f0cd1105.js and /dev/null differ
diff --git a/priv/static/static/js/3.bde677e65143f0cd1105.js.map b/priv/static/static/js/3.bde677e65143f0cd1105.js.map
deleted file mode 100644
index 06d4fc3d06..0000000000
Binary files a/priv/static/static/js/3.bde677e65143f0cd1105.js.map and /dev/null differ
diff --git a/priv/static/static/js/30.064c236fa83ac21c252f.js b/priv/static/static/js/30.064c236fa83ac21c252f.js
deleted file mode 100644
index 40d81fbfdc..0000000000
Binary files a/priv/static/static/js/30.064c236fa83ac21c252f.js and /dev/null differ
diff --git a/priv/static/static/js/30.064c236fa83ac21c252f.js.map b/priv/static/static/js/30.064c236fa83ac21c252f.js.map
deleted file mode 100644
index 4d0d88ca94..0000000000
Binary files a/priv/static/static/js/30.064c236fa83ac21c252f.js.map and /dev/null differ
diff --git a/priv/static/static/js/31.226f7a848d733df38095.js b/priv/static/static/js/31.226f7a848d733df38095.js
deleted file mode 100644
index 48131f952f..0000000000
Binary files a/priv/static/static/js/31.226f7a848d733df38095.js and /dev/null differ
diff --git a/priv/static/static/js/31.226f7a848d733df38095.js.map b/priv/static/static/js/31.226f7a848d733df38095.js.map
deleted file mode 100644
index 3d85d770fa..0000000000
Binary files a/priv/static/static/js/31.226f7a848d733df38095.js.map and /dev/null differ
diff --git a/priv/static/static/js/32.19ca50edbb4d711838dc.js b/priv/static/static/js/32.19ca50edbb4d711838dc.js
deleted file mode 100644
index 81bd5064fa..0000000000
Binary files a/priv/static/static/js/32.19ca50edbb4d711838dc.js and /dev/null differ
diff --git a/priv/static/static/js/32.19ca50edbb4d711838dc.js.map b/priv/static/static/js/32.19ca50edbb4d711838dc.js.map
deleted file mode 100644
index 99ad6e0507..0000000000
Binary files a/priv/static/static/js/32.19ca50edbb4d711838dc.js.map and /dev/null differ
diff --git a/priv/static/static/js/4.7077bff64d63355b1635.js b/priv/static/static/js/4.7077bff64d63355b1635.js
deleted file mode 100644
index cb97d38558..0000000000
Binary files a/priv/static/static/js/4.7077bff64d63355b1635.js and /dev/null differ
diff --git a/priv/static/static/js/4.7077bff64d63355b1635.js.map b/priv/static/static/js/4.7077bff64d63355b1635.js.map
deleted file mode 100644
index 83db836c85..0000000000
Binary files a/priv/static/static/js/4.7077bff64d63355b1635.js.map and /dev/null differ
diff --git a/priv/static/static/js/5.cfb722ac8eea8919f749.js b/priv/static/static/js/5.cfb722ac8eea8919f749.js
deleted file mode 100644
index 7d3bca1633..0000000000
Binary files a/priv/static/static/js/5.cfb722ac8eea8919f749.js and /dev/null differ
diff --git a/priv/static/static/js/5.cfb722ac8eea8919f749.js.map b/priv/static/static/js/5.cfb722ac8eea8919f749.js.map
deleted file mode 100644
index c9e701dc61..0000000000
Binary files a/priv/static/static/js/5.cfb722ac8eea8919f749.js.map and /dev/null differ
diff --git a/priv/static/static/js/6.613b0d6b08c3f5f9ef13.js b/priv/static/static/js/6.613b0d6b08c3f5f9ef13.js
deleted file mode 100644
index 499d714750..0000000000
Binary files a/priv/static/static/js/6.613b0d6b08c3f5f9ef13.js and /dev/null differ
diff --git a/priv/static/static/js/6.613b0d6b08c3f5f9ef13.js.map b/priv/static/static/js/6.613b0d6b08c3f5f9ef13.js.map
deleted file mode 100644
index 8b78bd4b3e..0000000000
Binary files a/priv/static/static/js/6.613b0d6b08c3f5f9ef13.js.map and /dev/null differ
diff --git a/priv/static/static/js/7.199d52eb458f775043ed.js b/priv/static/static/js/7.199d52eb458f775043ed.js
deleted file mode 100644
index bf90152505..0000000000
Binary files a/priv/static/static/js/7.199d52eb458f775043ed.js and /dev/null differ
diff --git a/priv/static/static/js/7.199d52eb458f775043ed.js.map b/priv/static/static/js/7.199d52eb458f775043ed.js.map
deleted file mode 100644
index ad860f0790..0000000000
Binary files a/priv/static/static/js/7.199d52eb458f775043ed.js.map and /dev/null differ
diff --git a/priv/static/static/js/8.7f96f22f9f65ad394684.js b/priv/static/static/js/8.7f96f22f9f65ad394684.js
deleted file mode 100644
index 154e634378..0000000000
Binary files a/priv/static/static/js/8.7f96f22f9f65ad394684.js and /dev/null differ
diff --git a/priv/static/static/js/8.7f96f22f9f65ad394684.js.map b/priv/static/static/js/8.7f96f22f9f65ad394684.js.map
deleted file mode 100644
index 74e510286e..0000000000
Binary files a/priv/static/static/js/8.7f96f22f9f65ad394684.js.map and /dev/null differ
diff --git a/priv/static/static/js/9.f8fc2497d5f27a9df682.js b/priv/static/static/js/9.f8fc2497d5f27a9df682.js
deleted file mode 100644
index c86ae4d9ac..0000000000
Binary files a/priv/static/static/js/9.f8fc2497d5f27a9df682.js and /dev/null differ
diff --git a/priv/static/static/js/9.f8fc2497d5f27a9df682.js.map b/priv/static/static/js/9.f8fc2497d5f27a9df682.js.map
deleted file mode 100644
index 50ff032de0..0000000000
Binary files a/priv/static/static/js/9.f8fc2497d5f27a9df682.js.map and /dev/null differ
diff --git a/priv/static/static/js/app.6c972d84b60f601b01f8.js b/priv/static/static/js/app.6c972d84b60f601b01f8.js
deleted file mode 100644
index f00f10017d..0000000000
Binary files a/priv/static/static/js/app.6c972d84b60f601b01f8.js and /dev/null differ
diff --git a/priv/static/static/js/app.6c972d84b60f601b01f8.js.map b/priv/static/static/js/app.6c972d84b60f601b01f8.js.map
deleted file mode 100644
index 2e5c2bd679..0000000000
Binary files a/priv/static/static/js/app.6c972d84b60f601b01f8.js.map and /dev/null differ
diff --git a/priv/static/static/js/vendors~app.cea10ab53f3aa19fc30e.js b/priv/static/static/js/vendors~app.cea10ab53f3aa19fc30e.js
deleted file mode 100644
index 5ffbf5a2b8..0000000000
Binary files a/priv/static/static/js/vendors~app.cea10ab53f3aa19fc30e.js and /dev/null differ
diff --git a/priv/static/static/js/vendors~app.cea10ab53f3aa19fc30e.js.map b/priv/static/static/js/vendors~app.cea10ab53f3aa19fc30e.js.map
deleted file mode 100644
index cd09905ecc..0000000000
Binary files a/priv/static/static/js/vendors~app.cea10ab53f3aa19fc30e.js.map and /dev/null differ
diff --git a/priv/static/static/logo.svg b/priv/static/static/logo.svg
deleted file mode 100644
index 68e647e6ca..0000000000
--- a/priv/static/static/logo.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
diff --git a/priv/static/static/ruffle/LICENSE_APACHE b/priv/static/static/ruffle/LICENSE_APACHE
deleted file mode 100644
index 1b5ec8b78e..0000000000
--- a/priv/static/static/ruffle/LICENSE_APACHE
+++ /dev/null
@@ -1,176 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
diff --git a/priv/static/static/ruffle/LICENSE_MIT b/priv/static/static/ruffle/LICENSE_MIT
deleted file mode 100644
index 63a286b4f1..0000000000
--- a/priv/static/static/ruffle/LICENSE_MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2018 Mike Welsh
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/priv/static/static/ruffle/README.md b/priv/static/static/ruffle/README.md
deleted file mode 100644
index 25636e78fc..0000000000
--- a/priv/static/static/ruffle/README.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# ruffle-selfhosted
-
-ruffle-selfhosted is the intended way to get Ruffle onto your website.
-
-You may either include it and forget about it, and we will polyfill existing Flash content,
-or use our APIs for custom configurations or more advanced usages of the Ruffle player.
-
-## Using ruffle-selfhosted
-
-For more examples and in-depth documentation on how to use Ruffle on your website, please
-[check out our wiki](https://github.com/ruffle-rs/ruffle/wiki/Using-Ruffle#web).
-
-### Host Ruffle
-
-The `selfhosted` package is configured for websites that do not use bundlers or npm and just want
-to get up and running. If you'd prefer to use Ruffle through npm and a bundler, please
-[refer to ruffle core](https://github.com/ruffle-rs/ruffle/tree/master/web/packages/core).
-
-Before you can get started with using Ruffle on your website, you must host its files yourself.
-Either take the [latest build](https://github.com/ruffle-rs/ruffle/releases)
-or [build it yourself](../../README.md), and make these files accessible by your web server.
-
-Please note that the `.wasm` file must be served properly, and some web servers may not do that
-correctly out of the box. Please see [our wiki](https://github.com/ruffle-rs/ruffle/wiki/Using-Ruffle#configure-wasm-mime-type)
-for instructions on how to configure this, if you encounter a `Incorrect response MIME type` error.
-
-### "Plug and Play"
-
-If you have an existing website with flash content, you can simply include Ruffle as a script and
-our polyfill magic will replace everything for you. No fuss, no mess.
-
-```html
-
-```
-
-### Javascript API
-
-If you want to control the Ruffle player, you may use our Javascript API.
-
-```html
-
-
-```
-
-## Building, testing or contributing
-
-Please see [the ruffle-web README](../../README.md).
diff --git a/priv/static/static/ruffle/af9b9e80cef829d41f6454bfef68d005.wasm b/priv/static/static/ruffle/af9b9e80cef829d41f6454bfef68d005.wasm
deleted file mode 100644
index 1d1a00d12d..0000000000
Binary files a/priv/static/static/ruffle/af9b9e80cef829d41f6454bfef68d005.wasm and /dev/null differ
diff --git a/priv/static/static/ruffle/package.json b/priv/static/static/ruffle/package.json
deleted file mode 100644
index 6f3cbfbe2e..0000000000
--- a/priv/static/static/ruffle/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name": "ruffle-mirror", "version": "2021.4.11", "description": "This is an auto npm mirror for ruffle nightly builds.", "repository": {"type": "git", "url": "git+https://github.com/rwv/ruffle-mirror.git"}, "author": "ruffle-rs", "license": "MIT", "bugs": {"url": "https://github.com/rwv/ruffle-mirror/issues"}, "homepage": "https://github.com/rwv/ruffle-mirror#readme"}
\ No newline at end of file
diff --git a/priv/static/static/ruffle/ruffle.js b/priv/static/static/ruffle/ruffle.js
deleted file mode 100644
index d4c5a5dd92..0000000000
Binary files a/priv/static/static/ruffle/ruffle.js and /dev/null differ
diff --git a/priv/static/static/ruffle/ruffle.js.map b/priv/static/static/ruffle/ruffle.js.map
deleted file mode 100644
index dcbb7add8f..0000000000
Binary files a/priv/static/static/ruffle/ruffle.js.map and /dev/null differ
diff --git a/priv/static/static/styles.json b/priv/static/static/styles.json
deleted file mode 100644
index 23f57c65e8..0000000000
--- a/priv/static/static/styles.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "pleroma-dark": "/static/themes/pleroma-dark.json",
- "pleroma-light": "/static/themes/pleroma-light.json",
- "pleroma-amoled": [ "Pleroma Dark AMOLED", "#000000", "#111111", "#b0b0b1", "#d8a070", "#aa0000", "#0fa00f", "#0095ff", "#d59500"],
- "classic-dark": [ "Classic Dark", "#161c20", "#282e32", "#b9b9b9", "#baaa9c", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
- "bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8", "#e0245e", "#17bf63", "#1b95e0", "#fab81e"],
- "ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60", "#FF6C60", "#A8FF60", "#96CBFE", "#FFFFB6" ],
- "monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ],
-
- "redmond-xx": "/static/themes/redmond-xx.json",
- "redmond-xx-se": "/static/themes/redmond-xx-se.json",
- "redmond-xxi": "/static/themes/redmond-xxi.json",
- "breezy-dark": "/static/themes/breezy-dark.json",
- "breezy-light": "/static/themes/breezy-light.json",
- "mammal": "/static/themes/mammal.json",
- "paper": "/static/themes/paper.json"
-}
diff --git a/priv/static/static/themes/breezy-dark.json b/priv/static/static/themes/breezy-dark.json
deleted file mode 100644
index 76b962c569..0000000000
--- a/priv/static/static/themes/breezy-dark.json
+++ /dev/null
@@ -1,131 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Breezy Dark (beta)",
- "source": {
- "themeEngineVersion": 3,
- "fonts": {},
- "shadows": {
- "panel": [
- {
- "x": "1",
- "y": "2",
- "blur": "6",
- "spread": 0,
- "color": "#000000",
- "alpha": 0.6
- }
- ],
- "button": [
- {
- "x": 0,
- "y": "0",
- "blur": "0",
- "spread": "1",
- "color": "--btn,900",
- "alpha": "0.15",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "1",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.3",
- "inset": false
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": "40",
- "blur": "40",
- "spread": "-40",
- "inset": true,
- "color": "--panel,900",
- "alpha": "0.1"
- }
- ],
- "buttonHover": [
- {
- "x": 0,
- "y": "0",
- "blur": 0,
- "spread": "1",
- "color": "--accent",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "1",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.3",
- "inset": false
- }
- ],
- "buttonPressed": [
- {
- "x": 0,
- "y": "0",
- "blur": 0,
- "spread": "1",
- "color": "--btn,900",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": "0.3",
- "inset": false
- }
- ],
- "input": [
- {
- "x": 0,
- "y": "0",
- "blur": 0,
- "spread": "1",
- "color": "--input,900",
- "alpha": "0.2",
- "inset": true
- }
- ]
- },
- "opacity": {},
- "colors": {
- "bg": "#31363b",
- "text": "#eff0f1",
- "link": "#3daee9",
- "fg": "#31363b",
- "panel": "transparent",
- "input": "--bg,-6.47",
- "topBarLink": "--topBarText",
- "btn": "--bg",
- "border": "#4c545b",
- "cRed": "#da4453",
- "cBlue": "#3daee9",
- "cGreen": "#27ae60",
- "cOrange": "#f67400",
- "btnPressed": "--accent",
- "selectedMenu": "--accent",
- "selectedMenuPopover": "--accent"
- },
- "radii": {
- "btn": "2",
- "input": "2",
- "checkbox": "1",
- "panel": "2",
- "avatar": "2",
- "avatarAlt": "2",
- "tooltip": "2",
- "attachment": "2"
- }
- }
-}
diff --git a/priv/static/static/themes/breezy-light.json b/priv/static/static/themes/breezy-light.json
deleted file mode 100644
index 0968fff0cb..0000000000
--- a/priv/static/static/themes/breezy-light.json
+++ /dev/null
@@ -1,131 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Breezy Light (beta)",
- "source": {
- "themeEngineVersion": 3,
- "fonts": {},
- "shadows": {
- "panel": [
- {
- "x": "1",
- "y": "2",
- "blur": "6",
- "spread": 0,
- "color": "#000000",
- "alpha": 0.6
- }
- ],
- "button": [
- {
- "x": 0,
- "y": "0",
- "blur": "0",
- "spread": "1",
- "color": "--btn,900",
- "alpha": "0.3",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "1",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.3",
- "inset": false
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": "40",
- "blur": "40",
- "spread": "-40",
- "inset": true,
- "color": "--panel,900",
- "alpha": "0.1"
- }
- ],
- "buttonHover": [
- {
- "x": 0,
- "y": "0",
- "blur": 0,
- "spread": "1",
- "color": "--accent",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "1",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.3",
- "inset": false
- }
- ],
- "buttonPressed": [
- {
- "x": 0,
- "y": "0",
- "blur": 0,
- "spread": "1",
- "color": "--btn,900",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": "0.3",
- "inset": false
- }
- ],
- "input": [
- {
- "x": 0,
- "y": "0",
- "blur": 0,
- "spread": "1",
- "color": "--input,900",
- "alpha": "0.2",
- "inset": true
- }
- ]
- },
- "opacity": {
- "input": "1"
- },
- "colors": {
- "bg": "#eff0f1",
- "text": "#232627",
- "fg": "#475057",
- "accent": "#2980b9",
- "input": "--bg,-6.47",
- "topBarLink": "--topBarText",
- "btn": "--bg",
- "cRed": "#da4453",
- "cBlue": "#2980b9",
- "cGreen": "#27ae60",
- "cOrange": "#f67400",
- "btnPressed": "--accent",
- "selectedMenu": "--accent",
- "selectedMenuPopover": "--accent"
- },
- "radii": {
- "btn": "2",
- "input": "2",
- "checkbox": "1",
- "panel": "2",
- "avatar": "2",
- "avatarAlt": "2",
- "tooltip": "2",
- "attachment": "2"
- }
- }
-}
diff --git a/priv/static/static/themes/mammal.json b/priv/static/static/themes/mammal.json
deleted file mode 100644
index 50b8e2f002..0000000000
--- a/priv/static/static/themes/mammal.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Mammal",
- "theme": {
- "shadows": {
- "button": [],
- "buttonHover": [
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": 1024,
- "color": "#56a7e1",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonPressed": [
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": 1024,
- "color": "#56a7e1",
- "alpha": "1",
- "inset": true
- }
- ],
- "panel": [],
- "panelHeader": [],
- "topBar": []
- },
- "opacity": { "input": "1" },
- "colors": {
- "bg": "#282c37",
- "text": "#f8f8f8",
- "link": "#9bacc8",
- "fg": "#444b5d",
- "input": "#FFFFFF",
- "inputText": "#282c37",
- "btn": "#2b90d9",
- "btnText": "#FFFFFF",
- "cRed": "#7f3142",
- "cBlue": "#2b90d9",
- "cGreen": "#2bd850",
- "cOrange": "#ca8f04"
- },
- "radii": {
- "btn": 4,
- "input": 4,
- "panel": "0",
- "avatar": "4",
- "avatarAlt": "4",
- "attachment": "4"
- }
- }
-}
diff --git a/priv/static/static/themes/paper.json b/priv/static/static/themes/paper.json
deleted file mode 100644
index a3b90a0a11..0000000000
--- a/priv/static/static/themes/paper.json
+++ /dev/null
@@ -1,172 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Paper",
- "source": {
- "themeEngineVersion": 3,
- "fonts": {},
- "shadows": {
- "panel": [
- {
- "x": "0",
- "y": "2",
- "blur": "9",
- "spread": 0,
- "inset": false,
- "color": "#668bb2",
- "alpha": "0.1"
- },
- {
- "x": "0",
- "y": "1",
- "blur": "2",
- "spread": "-1",
- "inset": false,
- "color": "#668bb2",
- "alpha": "0.1"
- }
- ],
- "topBar": [
- {
- "x": 0,
- "y": "3",
- "blur": "8",
- "spread": 0,
- "inset": false,
- "color": "#3e618e",
- "alpha": "0.1"
- },
- {
- "x": 0,
- "y": "1",
- "blur": "4",
- "spread": 0,
- "inset": false,
- "color": "#3e618e",
- "alpha": "0.1"
- }
- ],
- "button": [
- {
- "x": 0,
- "y": "2",
- "blur": "5",
- "spread": 0,
- "color": "#463f78",
- "alpha": "0.1",
- "inset": false
- }
- ],
- "input": [
- {
- "x": 0,
- "y": "1",
- "blur": "2",
- "spread": 0,
- "inset": true,
- "color": "#6277b7",
- "alpha": "0.1"
- }
- ],
- "buttonHover": [
- {
- "x": 0,
- "y": "2",
- "blur": "5",
- "spread": 0,
- "color": "#494949",
- "alpha": "0.1"
- },
- {
- "x": 0,
- "y": "2",
- "blur": "0",
- "spread": "20",
- "color": "#ffffff",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonPressed": [
- {
- "x": 0,
- "y": 0,
- "blur": "4",
- "spread": "0",
- "color": "#494949",
- "alpha": "0.8",
- "inset": false
- }
- ],
- "avatarStatus": [
- {
- "x": "0",
- "y": "2",
- "blur": "4",
- "spread": "0",
- "inset": false,
- "color": "#3e618e",
- "alpha": "0.1"
- }
- ],
- "avatar": [
- {
- "x": 0,
- "y": "2",
- "blur": "5",
- "spread": "0",
- "color": "#3e618e",
- "alpha": "0.9"
- }
- ],
- "popup": [
- {
- "x": "0",
- "y": "3",
- "blur": "11",
- "spread": 0,
- "color": "#668bb2",
- "alpha": "0.2"
- },
- {
- "x": "0",
- "y": "2",
- "blur": "3",
- "spread": "-1",
- "color": "#668bb2",
- "alpha": "0.2"
- }
- ]
- },
- "opacity": {
- "underlay": "1",
- "border": "0"
- },
- "colors": {
- "bg": "#ffffff",
- "fg": "#f6f6f6",
- "text": "#494949",
- "underlay": "#ffffff",
- "link": "#788ca1",
- "accent": "#97a0aa",
- "cBlue": "#788ca1",
- "cRed": "#eed7ce",
- "cGreen": "#788ca1",
- "cOrange": "#788ca1",
- "postLink": "#788ca1",
- "border": "#ffffff",
- "icon": "#b6c9c4",
- "panel": "#ffffff",
- "topBarText": "#4b4b4b"
- },
- "radii": {
- "btn": "0",
- "input": "0",
- "checkbox": "0",
- "panel": "0",
- "avatar": "2",
- "avatarAlt": "2",
- "tooltip": "0",
- "attachment": "0"
- }
- }
-}
diff --git a/priv/static/static/themes/pleroma-dark.json b/priv/static/static/themes/pleroma-dark.json
deleted file mode 100644
index 2703fba11a..0000000000
--- a/priv/static/static/themes/pleroma-dark.json
+++ /dev/null
@@ -1,191 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Pleroma Dark",
- "source": {
- "themeEngineVersion": 3,
- "fonts": {},
- "shadows": {
- "buttonHover": [
- {
- "x": 0,
- "y": 0,
- "blur": "1",
- "spread": "2",
- "color": "#b9b9ba",
- "alpha": "0.4",
- "inset": true
- },
- {
- "x": 0,
- "y": 1,
- "blur": 0,
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": 0.2,
- "inset": true
- }
- ],
- "buttonPressed": [
- {
- "x": 0,
- "y": 0,
- "blur": 4,
- "spread": 0,
- "color": "#000000",
- "alpha": 1,
- "inset": true
- },
- {
- "x": 0,
- "y": 1,
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": 0,
- "y": 0,
- "blur": "2",
- "spread": 0,
- "inset": false,
- "color": "#000000",
- "alpha": 1
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": "1",
- "blur": "3",
- "spread": 0,
- "inset": false,
- "color": "#000000",
- "alpha": "0.4"
- },
- {
- "x": "0",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "inset": true,
- "color": "#ffffff",
- "alpha": "0.2"
- }
- ],
- "panel": [
- {
- "x": "0",
- "y": "0",
- "blur": "3",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.5"
- },
- {
- "x": "0",
- "y": "4",
- "blur": "6",
- "spread": "3",
- "inset": false,
- "color": "#000000",
- "alpha": "0.3"
- }
- ],
- "button": [
- {
- "x": 0,
- "y": 0,
- "blur": 2,
- "spread": 0,
- "color": "#000000",
- "alpha": 1
- },
- {
- "x": 0,
- "y": 1,
- "blur": 0,
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": 0.2,
- "inset": true
- }
- ],
- "topBar": [
- {
- "x": 0,
- "y": "1",
- "blur": 4,
- "spread": 0,
- "color": "#000000",
- "alpha": "0.4"
- },
- {
- "x": 0,
- "y": "2",
- "blur": "7",
- "spread": 0,
- "inset": false,
- "color": "#000000",
- "alpha": "0.3"
- }
- ]
- },
- "opacity": {
- "underlay": "0.6"
- },
- "colors": {
- "bg": "#0f161e",
- "fg": "#151e2b",
- "text": "#b9b9ba",
- "underlay": "#090e14",
- "accent": "#e2b188",
- "cBlue": "#81beea",
- "cRed": "#d31014",
- "cGreen": "#5dc94a",
- "cOrange": "#ffc459",
- "border": "--fg,3",
- "topBarText": "--text,-9.75",
- "topBarLink": "--topBarText",
- "btnToggled": "--accent,-24.2",
- "alertErrorText": "--text,21.2",
- "badgeNotification": "#e15932",
- "badgeNotificationText": "#ffffff"
- },
- "radii": {
- "btn": "3",
- "input": "3",
- "panel": "3",
- "avatar": "3",
- "attachment": "3"
- }
- }
-}
diff --git a/priv/static/static/themes/pleroma-light.json b/priv/static/static/themes/pleroma-light.json
deleted file mode 100644
index 05fc300aa7..0000000000
--- a/priv/static/static/themes/pleroma-light.json
+++ /dev/null
@@ -1,219 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Pleroma Light",
- "source": {
- "themeEngineVersion": 3,
- "fonts": {},
- "shadows": {
- "button": [
- {
- "x": 0,
- "y": 0,
- "blur": 2,
- "spread": 0,
- "color": "#000000",
- "alpha": "0.2"
- },
- {
- "x": 0,
- "y": 1,
- "blur": 0,
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "0.5",
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": 0.2,
- "inset": true
- }
- ],
- "buttonHover": [
- {
- "x": 0,
- "y": 0,
- "blur": "2",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.2"
- },
- {
- "x": 0,
- "y": "0",
- "blur": "1",
- "spread": "2",
- "color": "#ffc39f",
- "alpha": "1",
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": 0.2,
- "inset": true
- }
- ],
- "input": [
- {
- "x": 0,
- "y": 1,
- "blur": 0,
- "spread": 0,
- "color": "#000000",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": 0.2,
- "inset": true
- },
- {
- "x": 0,
- "y": 0,
- "blur": "2",
- "inset": true,
- "spread": 0,
- "color": "#000000",
- "alpha": "0.15"
- }
- ],
- "panel": [
- {
- "x": "0",
- "y": 1,
- "blur": "3",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.5"
- },
- {
- "x": "0",
- "y": "3",
- "blur": "6",
- "spread": "1",
- "inset": false,
- "color": "#000000",
- "alpha": "0.2"
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": "1",
- "blur": 0,
- "spread": 0,
- "inset": true,
- "color": "#ffffff",
- "alpha": "0.5"
- },
- {
- "x": 0,
- "y": "1",
- "blur": "3",
- "spread": 0,
- "inset": false,
- "color": "#000000",
- "alpha": "0.3"
- }
- ],
- "buttonPressed": [
- {
- "x": 0,
- "y": 0,
- "blur": 4,
- "spread": 0,
- "color": "#000000",
- "alpha": "0.2"
- },
- {
- "x": 0,
- "y": 1,
- "blur": "1",
- "spread": "2",
- "color": "#000000",
- "alpha": "0.3",
- "inset": true
- },
- {
- "x": 0,
- "y": -1,
- "blur": 0,
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": 0.2,
- "inset": true
- }
- ],
- "popup": [
- {
- "x": "1",
- "y": "2",
- "blur": "2",
- "spread": 0,
- "color": "#000000",
- "alpha": "0.2"
- },
- {
- "x": "1",
- "y": "3",
- "blur": "7",
- "spread": "0",
- "inset": false,
- "color": "#000000",
- "alpha": "0.2"
- }
- ],
- "avatarStatus": [
- {
- "x": 0,
- "y": "1",
- "blur": "4",
- "spread": "0",
- "inset": false,
- "color": "#000000",
- "alpha": "0.2"
- }
- ]
- },
- "opacity": {
- "underlay": "0.4"
- },
- "colors": {
- "bg": "#f2f6f9",
- "fg": "#d6dfed",
- "text": "#304055",
- "underlay": "#5d6086",
- "accent": "#f55b1b",
- "cBlue": "#0095ff",
- "cRed": "#d31014",
- "cGreen": "#0fa00f",
- "cOrange": "#ffa500",
- "border": "#d8e6f9",
- "topBarText": "#304055",
- "topBarLink": "--topBarText",
- "btnToggled": "--accent,-24.2",
- "input": "#dee3ed",
- "badgeNotification": "#e83802"
- },
- "radii": {
- "btn": "3",
- "input": "3",
- "panel": "3",
- "avatar": "3",
- "attachment": "3"
- }
- }
-}
diff --git a/priv/static/static/themes/redmond-xx-se.json b/priv/static/static/themes/redmond-xx-se.json
deleted file mode 100644
index b62769dbc7..0000000000
--- a/priv/static/static/themes/redmond-xx-se.json
+++ /dev/null
@@ -1,305 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Redmond XX SE",
- "source": {
- "themeEngineVersion": 3,
- "shadows": {
- "panel": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": 0,
- "blur": 0,
- "spread": "3",
- "inset": true,
- "color": "#c0c0c0",
- "alpha": 1
- },
- {
- "x": "-2200",
- "y": 0,
- "blur": "200",
- "spread": "-2000",
- "inset": true,
- "color": "#1084d0",
- "alpha": 1
- }
- ],
- "button": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonHover": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonPressed": [
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "input": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--input",
- "alpha": "1",
- "inset": true
- }
- ]
- },
- "fonts": {},
- "opacity": {
- "input": "1",
- "faint": "1"
- },
- "colors": {
- "bg": "#c0c0c0",
- "wallpaper": "#008080",
- "text": "#000000",
- "link": "#0000ff",
- "accent": "#000080",
- "fg": "#c0c0c0",
- "panel": "#000080",
- "panelFaint": "#c0c0c0",
- "input": "#ffffff",
- "topBar": "#000080",
- "topBarLink": "#ffffff",
- "btn": "#c0c0c0",
- "btnToggled": "--btn",
- "faint": "#3f3f3f",
- "faintLink": "#404080",
- "border": "#808080",
- "cRed": "#FF0000",
- "cBlue": "#008080",
- "cGreen": "#008000",
- "cOrange": "#808000",
- "highlight": "--accent",
- "selectedPost": "--bg,-10",
- "selectedMenu": "--accent",
- "selectedMenuPopover": "--accent"
- },
- "radii": {
- "btn": "0",
- "input": "0",
- "checkbox": "0",
- "panel": "0",
- "avatar": "0",
- "avatarAlt": "0",
- "tooltip": "0",
- "attachment": "0"
- }
- }
-}
diff --git a/priv/static/static/themes/redmond-xx.json b/priv/static/static/themes/redmond-xx.json
deleted file mode 100644
index 83b591091d..0000000000
--- a/priv/static/static/themes/redmond-xx.json
+++ /dev/null
@@ -1,296 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Redmond XX",
- "source": {
- "themeEngineVersion": 3,
- "shadows": {
- "panel": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": 0,
- "blur": 0,
- "spread": "3",
- "inset": true,
- "color": "#c0c0c0",
- "alpha": 1
- }
- ],
- "button": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonHover": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonPressed": [
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "input": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#000000",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--input",
- "alpha": "1",
- "inset": true
- }
- ]
- },
- "fonts": {},
- "opacity": {
- "input": "1",
- "faint": "1"
- },
- "colors": {
- "bg": "#c0c0c0",
- "wallpaper": "#008080",
- "text": "#000000",
- "link": "#0000ff",
- "accent": "#000080",
- "fg": "#c0c0c0",
- "panel": "#000080",
- "panelFaint": "#c0c0c0",
- "input": "#ffffff",
- "topBar": "#000080",
- "topBarLink": "#ffffff",
- "btn": "#c0c0c0",
- "btnToggled": "--btn",
- "faint": "#3f3f3f",
- "faintLink": "#404080",
- "border": "#808080",
- "cRed": "#FF0000",
- "cBlue": "#008080",
- "cGreen": "#008000",
- "cOrange": "#808000",
- "highlight": "--accent",
- "selectedPost": "--bg,-10",
- "selectedMenu": "--accent",
- "selectedMenuPopover": "--accent"
- },
- "radii": {
- "btn": "0",
- "input": "0",
- "checkbox": "0",
- "panel": "0",
- "avatar": "0",
- "avatarAlt": "0",
- "tooltip": "0",
- "attachment": "0"
- }
- }
-}
diff --git a/priv/static/static/themes/redmond-xxi.json b/priv/static/static/themes/redmond-xxi.json
deleted file mode 100644
index 60ceae7c2c..0000000000
--- a/priv/static/static/themes/redmond-xxi.json
+++ /dev/null
@@ -1,278 +0,0 @@
-{
- "_pleroma_theme_version": 2,
- "name": "Redmond XXI",
- "source": {
- "themeEngineVersion": 3,
- "shadows": {
- "panel": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#404040",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#dfdfdf",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "panelHeader": [
- {
- "x": 0,
- "y": 0,
- "blur": 0,
- "spread": "3",
- "inset": true,
- "color": "#d6d6ce",
- "alpha": 1
- },
- {
- "x": "-2200",
- "y": 0,
- "blur": "200",
- "spread": "-2000",
- "inset": true,
- "color": "#a5cef7",
- "alpha": 1
- }
- ],
- "button": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#404040",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonHover": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#404040",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "buttonPressed": [
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#404040",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--bg",
- "alpha": "1",
- "inset": true
- }
- ],
- "input": [
- {
- "x": "-1",
- "y": "-1",
- "blur": "0",
- "spread": 0,
- "color": "#FFFFFF",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "1",
- "y": "1",
- "blur": "0",
- "spread": 0,
- "color": "#848484",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "-2",
- "y": "-2",
- "blur": "0",
- "spread": 0,
- "color": "#d4d0c8",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "2",
- "y": "2",
- "blur": "0",
- "spread": 0,
- "color": "#404040",
- "alpha": "1",
- "inset": true
- },
- {
- "x": "0",
- "y": "0",
- "blur": "0",
- "spread": "3",
- "color": "--input",
- "alpha": "1",
- "inset": true
- }
- ]
- },
- "fonts": {},
- "opacity": {
- "input": "1",
- "faint": "1"
- },
- "colors": {
- "bg": "#d6d6ce",
- "wallpaper": "#396ba5",
- "text": "#000000",
- "link": "#0000ff",
- "accent": "#0a246a",
- "fg": "#d6d6ce",
- "panel": "#042967",
- "panelFaint": "#FFFFFF",
- "input": "#ffffff",
- "topBar": "#042967",
- "topBarLink": "#ffffff",
- "btn": "#d6d6ce",
- "btnToggled": "--btn",
- "faint": "#3f3f3f",
- "faintLink": "#404080",
- "border": "#808080",
- "cRed": "#c42726",
- "cBlue": "#6699cc",
- "cGreen": "#669966",
- "cOrange": "#cc6633",
- "highlight": "--accent",
- "selectedPost": "--bg,-10",
- "selectedMenu": "--accent",
- "selectedMenuPopover": "--accent"
- },
- "radii": {
- "btn": "0",
- "input": "0",
- "checkbox": "0",
- "panel": "0",
- "avatar": "0",
- "avatarAlt": "0",
- "tooltip": "0",
- "attachment": "0"
- }
- }
-}
diff --git a/priv/static/sw-pleroma.js b/priv/static/sw-pleroma.js
deleted file mode 100644
index b1699a5a91..0000000000
Binary files a/priv/static/sw-pleroma.js and /dev/null differ
diff --git a/priv/static/sw-pleroma.js.map b/priv/static/sw-pleroma.js.map
deleted file mode 100644
index 06813ad0ee..0000000000
Binary files a/priv/static/sw-pleroma.js.map and /dev/null differ
diff --git a/rebased.png b/rebased.png
new file mode 100644
index 0000000000..a4601ed829
Binary files /dev/null and b/rebased.png differ
diff --git a/restarter/lib/pleroma.ex b/restarter/lib/pleroma.ex
index 149a569ce4..a7186cec48 100644
--- a/restarter/lib/pleroma.ex
+++ b/restarter/lib/pleroma.ex
@@ -61,6 +61,12 @@ def handle_cast(:refresh, _state) do
{:noreply, @init_state}
end
+ # Don't actually restart during tests.
+ # We just check if the correct call has been done.
+ # If we actually restart, we get errors during the tests like
+ # (RuntimeError) could not lookup Ecto repo Pleroma.Repo because it was not started or
+ # it does not exist
+ # See tests in Pleroma.Config.TransferTaskTest
def handle_cast({:restart, :test, _}, state) do
Logger.debug("pleroma manually restarted")
{:noreply, Map.put(state, :need_reboot, false)}
@@ -74,6 +80,12 @@ def handle_cast({:restart, _, delay}, state) do
def handle_cast({:after_boot, _}, %{after_boot: true} = state), do: {:noreply, state}
+ # Don't actually restart during tests.
+ # We just check if the correct call has been done.
+ # If we actually restart, we get errors during the tests like
+ # (RuntimeError) could not lookup Ecto repo Pleroma.Repo because it was not started or
+ # it does not exist
+ # See tests in Pleroma.Config.TransferTaskTest
def handle_cast({:after_boot, :test}, state) do
Logger.debug("pleroma restarted after boot")
state = %{state | after_boot: true, rebooted: true}
diff --git a/restarter/mix.exs b/restarter/mix.exs
index b0908aecec..9f26f5f649 100644
--- a/restarter/mix.exs
+++ b/restarter/mix.exs
@@ -13,7 +13,8 @@ def project do
def application do
[
- mod: {Restarter, []}
+ mod: {Restarter, []},
+ extra_applications: [:logger]
]
end
diff --git a/test/pleroma/config/transfer_task_test.exs b/test/pleroma/config/transfer_task_test.exs
index 927744add5..3dc917362d 100644
--- a/test/pleroma/config/transfer_task_test.exs
+++ b/test/pleroma/config/transfer_task_test.exs
@@ -79,35 +79,70 @@ test "transfer config values with full subkey update" do
describe "pleroma restart" do
setup do
- on_exit(fn -> Restarter.Pleroma.refresh() end)
+ on_exit(fn ->
+ Restarter.Pleroma.refresh()
+
+ # Restarter.Pleroma.refresh/0 is an asynchronous call.
+ # A GenServer will first finish the previous call before starting a new one.
+ # Here we do a synchronous call.
+ # That way we are sure that the previous call has finished before we continue.
+ # See https://stackoverflow.com/questions/51361856/how-to-use-task-await-with-genserver
+ Restarter.Pleroma.rebooted?()
+ end)
end
- @tag :erratic
test "don't restart if no reboot time settings were changed" do
clear_config(:emoji)
insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]])
refute String.contains?(
- capture_log(fn -> TransferTask.start_link([]) end),
+ capture_log(fn ->
+ TransferTask.start_link([])
+
+ # TransferTask.start_link/1 is an asynchronous call.
+ # A GenServer will first finish the previous call before starting a new one.
+ # Here we do a synchronous call.
+ # That way we are sure that the previous call has finished before we continue.
+ Restarter.Pleroma.rebooted?()
+ end),
"pleroma restarted"
)
end
- @tag :erratic
test "on reboot time key" do
clear_config(:shout)
insert(:config, key: :shout, value: [enabled: false])
- assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted"
+
+ # Note that we don't actually restart Pleroma.
+ # See module Restarter.Pleroma
+ assert capture_log(fn ->
+ TransferTask.start_link([])
+
+ # TransferTask.start_link/1 is an asynchronous call.
+ # A GenServer will first finish the previous call before starting a new one.
+ # Here we do a synchronous call.
+ # That way we are sure that the previous call has finished before we continue.
+ Restarter.Pleroma.rebooted?()
+ end) =~ "pleroma restarted"
end
- @tag :erratic
test "on reboot time subkey" do
clear_config(Pleroma.Captcha)
insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60])
- assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted"
+
+ # Note that we don't actually restart Pleroma.
+ # See module Restarter.Pleroma
+ assert capture_log(fn ->
+ TransferTask.start_link([])
+
+ # TransferTask.start_link/1 is an asynchronous call.
+ # A GenServer will first finish the previous call before starting a new one.
+ # Here we do a synchronous call.
+ # That way we are sure that the previous call has finished before we continue.
+ Restarter.Pleroma.rebooted?()
+ end) =~ "pleroma restarted"
end
- @tag :erratic
test "don't restart pleroma on reboot time key and subkey if there is false flag" do
clear_config(:shout)
clear_config(Pleroma.Captcha)
@@ -116,7 +151,15 @@ test "don't restart pleroma on reboot time key and subkey if there is false flag
insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60])
refute String.contains?(
- capture_log(fn -> TransferTask.load_and_update_env([], false) end),
+ capture_log(fn ->
+ TransferTask.load_and_update_env([], false)
+
+ # TransferTask.start_link/1 is an asynchronous call.
+ # A GenServer will first finish the previous call before starting a new one.
+ # Here we do a synchronous call.
+ # That way we are sure that the previous call has finished before we continue.
+ Restarter.Pleroma.rebooted?()
+ end),
"pleroma restarted"
)
end
diff --git a/test/pleroma/conversation/participation_test.exs b/test/pleroma/conversation/participation_test.exs
index 6f71cc0408..a84437677d 100644
--- a/test/pleroma/conversation/participation_test.exs
+++ b/test/pleroma/conversation/participation_test.exs
@@ -122,11 +122,11 @@ test "recreating an existing participations sets it to unread" do
end
test "it marks a participation as read" do
- participation = insert(:participation, %{read: false})
+ participation = insert(:participation, %{updated_at: ~N[2017-07-17 17:09:58], read: false})
{:ok, updated_participation} = Participation.mark_as_read(participation)
assert updated_participation.read
- assert updated_participation.updated_at == participation.updated_at
+ assert :gt = NaiveDateTime.compare(updated_participation.updated_at, participation.updated_at)
end
test "it marks a participation as unread" do
diff --git a/test/pleroma/user_relationship_test.exs b/test/pleroma/user_relationship_test.exs
index 2811aff4c9..7d205a746a 100644
--- a/test/pleroma/user_relationship_test.exs
+++ b/test/pleroma/user_relationship_test.exs
@@ -5,8 +5,9 @@
defmodule Pleroma.UserRelationshipTest do
alias Pleroma.UserRelationship
- use Pleroma.DataCase, async: true
+ use Pleroma.DataCase, async: false
+ import Mock
import Pleroma.Factory
describe "*_exists?/2" do
@@ -79,7 +80,12 @@ test "creates user relationship record if it doesn't exist", %{users: [user1, us
end
test "if record already exists, returns it", %{users: [user1, user2]} do
- user_block = UserRelationship.create_block(user1, user2)
+ user_block =
+ with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
+ {:ok, %{inserted_at: ~N[2017-03-17 17:09:58]}} =
+ UserRelationship.create_block(user1, user2)
+ end
+
assert user_block == UserRelationship.create_block(user1, user2)
end
end
diff --git a/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs
index d22ec400dc..66f8499faf 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs
@@ -173,4 +173,23 @@ test "accepts a Question with no content" do
assert {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
end
+
+ test "it strips voters list and displays voters count instead" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "???",
+ poll: %{expires_in: 10, options: ["yes", "no"]}
+ })
+
+ object = Object.normalize(activity, fetch: false)
+ {:ok, _, _} = CommonAPI.vote(other_user, object, [1])
+
+ {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
+
+ refute Map.has_key?(modified["object"], "voters")
+ assert modified["object"]["votersCount"] == 1
+ end
end
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index 7caccc501a..e483a0fbe2 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -62,9 +62,11 @@ test "it posts a poll" do
describe "blocking" do
setup do
blocker = insert(:user)
- blocked = insert(:user)
- User.follow(blocker, blocked)
- User.follow(blocked, blocker)
+ blocked = insert(:user, local: false)
+ CommonAPI.follow(blocker, blocked)
+ CommonAPI.follow(blocked, blocker)
+ CommonAPI.accept_follow_request(blocker, blocked)
+ CommonAPI.accept_follow_request(blocked, blocked)
%{blocker: blocker, blocked: blocked}
end
@@ -73,6 +75,9 @@ test "it blocks and federates", %{blocker: blocker, blocked: blocked} do
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
+ assert User.get_follow_state(blocker, blocked) == :follow_accept
+ refute is_nil(Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked))
+
assert {:ok, block} = CommonAPI.block(blocker, blocked)
assert block.local
@@ -80,6 +85,11 @@ test "it blocks and federates", %{blocker: blocker, blocked: blocked} do
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
+ refute User.get_follow_state(blocker, blocked)
+
+ assert %{data: %{"state" => "reject"}} =
+ Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked)
+
assert called(Pleroma.Web.Federator.publish(block))
end
end
diff --git a/test/pleroma/web/federator_test.exs b/test/pleroma/web/federator_test.exs
index 5120bf57c4..41d1c5d5e8 100644
--- a/test/pleroma/web/federator_test.exs
+++ b/test/pleroma/web/federator_test.exs
@@ -153,7 +153,7 @@ test "rejects incoming AP docs with incorrect origin" do
}
assert {:ok, job} = Federator.incoming_ap_doc(params)
- assert {:error, :origin_containment_failed} = ObanHelpers.perform(job)
+ assert {:cancel, :origin_containment_failed} = ObanHelpers.perform(job)
end
test "it does not crash if MRF rejects the post" do
@@ -169,7 +169,7 @@ test "it does not crash if MRF rejects the post" do
|> Jason.decode!()
assert {:ok, job} = Federator.incoming_ap_doc(params)
- assert {:error, _} = ObanHelpers.perform(job)
+ assert {:cancel, _} = ObanHelpers.perform(job)
end
end
end
diff --git a/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
index ba4628fc5f..faa35f1990 100644
--- a/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
@@ -3,9 +3,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
- use Pleroma.Web.ConnCase, async: true
+ use Pleroma.Web.ConnCase, async: false
use Oban.Testing, repo: Pleroma.Repo
+ import Mock
import Pleroma.Factory
alias Pleroma.Filter
@@ -53,24 +54,19 @@ test "a filter with expires_in", %{conn: conn, user: user} do
in_seconds = 600
response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/filters", %{
- "phrase" => "knights",
- context: ["home"],
- expires_in: in_seconds
- })
- |> json_response_and_validate_schema(200)
+ with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/filters", %{
+ "phrase" => "knights",
+ context: ["home"],
+ expires_in: in_seconds
+ })
+ |> json_response_and_validate_schema(200)
+ end
assert response["irreversible"] == false
-
- expected_expiration =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(in_seconds)
-
- {:ok, actual_expiration} = NaiveDateTime.from_iso8601(response["expires_at"])
-
- assert abs(NaiveDateTime.diff(expected_expiration, actual_expiration)) <= 5
+ assert response["expires_at"] == "2017-03-17T17:19:58.000Z"
filter = Filter.get(response["id"], user)
@@ -177,28 +173,25 @@ test "common" do
assert response["whole_word"] == true
end
- @tag :erratic
test "with adding expires_at", %{conn: conn, user: user} do
filter = insert(:filter, user: user)
in_seconds = 600
response =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/v1/filters/#{filter.filter_id}", %{
- phrase: "nii",
- context: ["public"],
- expires_in: in_seconds,
- irreversible: true
- })
- |> json_response_and_validate_schema(200)
+ with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> put("/api/v1/filters/#{filter.filter_id}", %{
+ phrase: "nii",
+ context: ["public"],
+ expires_in: in_seconds,
+ irreversible: true
+ })
+ |> json_response_and_validate_schema(200)
+ end
assert response["irreversible"] == true
-
- assert response["expires_at"] ==
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(in_seconds)
- |> Pleroma.Web.CommonAPI.Utils.to_masto_date()
+ assert response["expires_at"] == "2017-03-17T17:19:58.000Z"
filter = Filter.get(response["id"], user)
diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
index 43282b549c..7dbe52c816 100644
--- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
@@ -11,6 +11,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
import Pleroma.Factory
test "get instance information", %{conn: conn} do
+ clear_config([:auth, :oauth_consumer_strategies], [])
+
conn = get(conn, "/api/v1/instance")
assert result = json_response_and_validate_schema(conn, 200)
@@ -45,12 +47,14 @@ test "get instance information", %{conn: conn} do
"rules" => _
} = result
+ assert result["version"] =~ "Pleroma"
assert result["pleroma"]["metadata"]["account_activation_required"] != nil
assert result["pleroma"]["metadata"]["features"]
assert result["pleroma"]["metadata"]["federation"]
assert result["pleroma"]["metadata"]["fields_limits"]
assert result["pleroma"]["vapid_public_key"]
assert result["pleroma"]["stats"]["mau"] == 0
+ assert result["pleroma"]["oauth_consumer_strategies"] == []
assert result["soapbox"]["version"] =~ "."
assert email == from_config_email
@@ -119,4 +123,14 @@ test "get instance configuration", %{conn: conn} do
assert result["configuration"]["statuses"]["max_characters"] == 476
end
+
+ test "get oauth_consumer_strategies", %{conn: conn} do
+ clear_config([:auth, :oauth_consumer_strategies], ["keycloak"])
+
+ conn = get(conn, "/api/v1/instance")
+
+ assert result = json_response_and_validate_schema(conn, 200)
+
+ assert result["pleroma"]["oauth_consumer_strategies"] == ["keycloak"]
+ end
end
diff --git a/test/pleroma/web/mastodon_api/views/poll_view_test.exs b/test/pleroma/web/mastodon_api/views/poll_view_test.exs
index 3aa73c224e..4c0e2ed41a 100644
--- a/test/pleroma/web/mastodon_api/views/poll_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/poll_view_test.exs
@@ -167,7 +167,21 @@ test "doesn't strips HTML tags" do
} = PollView.render("show.json", %{object: object})
end
- test "that poll is non anonymous" do
+ test "displays correct voters count" do
+ object = Object.normalize("https://friends.grishka.me/posts/54642", fetch: true)
+ result = PollView.render("show.json", %{object: object})
+
+ assert result[:voters_count] == 14
+ end
+
+ test "displays correct voters count basing on voters array" do
+ object = Object.normalize("https://patch.cx/objects/tesla_mock/poll_attachment", fetch: true)
+ result = PollView.render("show.json", %{object: object})
+
+ assert result[:voters_count] == 4
+ end
+
+ test "detects that poll is non anonymous" do
object = Object.normalize("https://friends.grishka.me/posts/54642", fetch: true)
result = PollView.render("show.json", %{object: object})
diff --git a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
index 5ace2eee97..5246bf0c4b 100644
--- a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
+++ b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
@@ -158,7 +158,7 @@ test "responds with 424 Failed Dependency if HEAD request to media proxy fails",
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 500, body: ""}
end)
@@ -173,7 +173,7 @@ test "redirects to media proxy URI on unsupported content type", %{
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
end)
@@ -193,7 +193,7 @@ test "with `static=true` and GIF image preview requested, responds with JPEG ima
clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{
status: 200,
body: "",
@@ -218,7 +218,7 @@ test "with GIF image preview requested and no `static` param, redirects to media
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
end)
@@ -236,7 +236,7 @@ test "with `static` param and non-GIF image preview requested, " <>
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
end)
@@ -256,7 +256,7 @@ test "with :min_content_length setting not matched by Content-Length header, " <
clear_config([:media_preview_proxy, :min_content_length], 100_000)
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{
status: 200,
body: "",
@@ -278,7 +278,7 @@ test "thumbnails PNG images into PNG", %{
assert_dependencies_installed()
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
%{method: :get, url: ^media_proxy_url} ->
@@ -300,7 +300,7 @@ test "thumbnails JPEG images into JPEG", %{
assert_dependencies_installed()
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} ->
@@ -320,7 +320,7 @@ test "redirects to media proxy URI in case of thumbnailing error", %{
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
- %{method: "head", url: ^media_proxy_url} ->
+ %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} ->
diff --git a/test/pleroma/web/node_info_test.exs b/test/pleroma/web/node_info_test.exs
index 247ad7501a..830ebf5ef0 100644
--- a/test/pleroma/web/node_info_test.exs
+++ b/test/pleroma/web/node_info_test.exs
@@ -64,6 +64,12 @@ test "returns software.repository field in nodeinfo 2.1", %{conn: conn} do
assert Pleroma.Application.repository() == result["software"]["repository"]
end
+ test "returns Pleroma as software name", %{conn: conn} do
+ conn = get(conn, "/nodeinfo/2.1.json")
+ assert result = json_response(conn, 200)
+ assert result["software"]["name"] == "pleroma"
+ end
+
test "returns fieldsLimits field", %{conn: conn} do
clear_config([:instance, :max_account_fields], 10)
clear_config([:instance, :max_remote_account_fields], 15)
diff --git a/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
index aa44cf473b..ba40a9a6e1 100644
--- a/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
@@ -134,6 +134,7 @@ test "returns key and provisioning_uri", %{conn: conn} do
end
describe "GET /api/pleroma/accounts/mfa/confirm/totp" do
+ @tag :erratic
test "returns success result", %{conn: conn} do
secret = TOTP.generate_secret()
code = TOTP.generate_token(secret)
diff --git a/test/pleroma/web/plugs/rate_limiter_test.exs b/test/pleroma/web/plugs/rate_limiter_test.exs
index b1ac76120d..19cee8aeef 100644
--- a/test/pleroma/web/plugs/rate_limiter_test.exs
+++ b/test/pleroma/web/plugs/rate_limiter_test.exs
@@ -48,38 +48,42 @@ test "it is enabled if remote_ip_found flag doesn't exist" do
refute RateLimiter.disabled?(build_conn())
end
- @tag :erratic
test "it restricts based on config values" do
limiter_name = :test_plug_opts
scale = 80
limit = 5
- clear_config([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+ clear_config([Pleroma.Web.Endpoint, :http, :ip], {127, 0, 0, 1})
clear_config([:rate_limit, limiter_name], {scale, limit})
plug_opts = RateLimiter.init(name: limiter_name)
conn = build_conn(:get, "/")
- for i <- 1..5 do
- conn = RateLimiter.call(conn, plug_opts)
- assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- Process.sleep(10)
+ for _ <- 1..5 do
+ conn_limited = RateLimiter.call(conn, plug_opts)
+
+ refute conn_limited.status == Conn.Status.code(:too_many_requests)
+ refute conn_limited.resp_body
+ refute conn_limited.halted
end
- conn = RateLimiter.call(conn, plug_opts)
- assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
- assert conn.halted
+ conn_limited = RateLimiter.call(conn, plug_opts)
+ assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests)
+ assert conn_limited.halted
- Process.sleep(50)
+ expire_ttl(conn, limiter_name)
- conn = build_conn(:get, "/")
+ for _ <- 1..5 do
+ conn_limited = RateLimiter.call(conn, plug_opts)
- conn = RateLimiter.call(conn, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ refute conn_limited.status == Conn.Status.code(:too_many_requests)
+ refute conn_limited.resp_body
+ refute conn_limited.halted
+ end
- refute conn.status == Conn.Status.code(:too_many_requests)
- refute conn.resp_body
- refute conn.halted
+ conn_limited = RateLimiter.call(conn, plug_opts)
+ assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests)
+ assert conn_limited.halted
end
describe "options" do
@@ -263,4 +267,12 @@ test "doesn't crash due to a race condition when multiple requests are made at t
refute {:err, :not_found} == RateLimiter.inspect_bucket(conn, limiter_name, opts)
end
+
+ def expire_ttl(%{remote_ip: remote_ip} = _conn, bucket_name_root) do
+ bucket_name = "anon:#{bucket_name_root}" |> String.to_atom()
+ key_name = "ip::#{remote_ip |> Tuple.to_list() |> Enum.join(".")}"
+
+ {:ok, bucket_value} = Cachex.get(bucket_name, key_name)
+ Cachex.put(bucket_name, key_name, bucket_value, ttl: -1)
+ end
end
diff --git a/test/pleroma/web/utils/colors_test.exs b/test/pleroma/web/utils/colors_test.exs
new file mode 100644
index 0000000000..91d23f6265
--- /dev/null
+++ b/test/pleroma/web/utils/colors_test.exs
@@ -0,0 +1,39 @@
+# Pleroma: A lightweight social networking server
+# Copyright ยฉ 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Utils.ColorsTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Web.Utils.Colors
+
+ @base_color "#457d7b"
+
+ describe "get_shades/1" do
+ test "generates tints from a base color" do
+ assert %{
+ 50 => "246, 249, 248",
+ 100 => "236, 242, 242",
+ 200 => "209, 223, 222",
+ 300 => "125, 164, 163",
+ 400 => "106, 151, 149",
+ 500 => "69, 125, 123",
+ 600 => "62, 113, 111",
+ 700 => "52, 94, 92",
+ 800 => "21, 38, 37",
+ 900 => "13, 24, 23"
+ } == Colors.get_shades(@base_color)
+ end
+
+ test "uses soapbox blue if invalid color provided" do
+ assert %{
+ 500 => "4, 130, 216"
+ } = Colors.get_shades("255, 255, 127")
+ end
+ end
+
+ test "shades_to_css/2" do
+ result = Colors.shades_to_css("primary")
+ assert String.contains?(result, "--color-primary-500: 4, 130, 216;")
+ end
+end
diff --git a/test/pleroma/workers/receiver_worker_test.exs b/test/pleroma/workers/receiver_worker_test.exs
new file mode 100644
index 0000000000..283beee4d5
--- /dev/null
+++ b/test/pleroma/workers/receiver_worker_test.exs
@@ -0,0 +1,25 @@
+# Pleroma: A lightweight social networking server
+# Copyright ยฉ 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.ReceiverWorkerTest do
+ use Pleroma.DataCase, async: true
+ use Oban.Testing, repo: Pleroma.Repo
+
+ import Mock
+ import Pleroma.Factory
+
+ alias Pleroma.Workers.ReceiverWorker
+
+ test "it ignores MRF reject" do
+ params = insert(:note).data
+
+ with_mock Pleroma.Web.ActivityPub.Transmogrifier,
+ handle_incoming: fn _ -> {:reject, "MRF"} end do
+ assert {:cancel, "MRF"} =
+ ReceiverWorker.perform(%Oban.Job{
+ args: %{"op" => "incoming_ap_doc", "params" => params}
+ })
+ end
+ end
+end