]> Untitled Git - lemmy.git/commitdiff
Merge branch 'master' into federation_merge_from_master_2
authorDessalines <tyhou13@gmx.com>
Wed, 24 Jun 2020 01:11:38 +0000 (21:11 -0400)
committerDessalines <tyhou13@gmx.com>
Wed, 24 Jun 2020 01:11:38 +0000 (21:11 -0400)
61 files changed:
CODE_OF_CONDUCT.md
RELEASES.md
ansible/VERSION
ansible/ansible.cfg
ansible/lemmy.yml
ansible/lemmy_dev.yml
ansible/templates/docker-compose.yml
ansible/templates/nginx.conf
docker/dev/Dockerfile
docker/dev/Dockerfile.aarch64 [deleted file]
docker/dev/Dockerfile.armv7hf [deleted file]
docker/dev/Dockerfile.libc [deleted file]
docker/dev/docker-compose.yml
docker/dev/docker_update.sh
docker/dev/test_deploy.sh
docker/federation/docker-compose.yml
docker/federation/nginx.conf
docker/federation/run-federation-test.bash
docker/prod/Dockerfile [new file with mode: 0644]
docker/prod/deploy.sh [moved from docker/dev/deploy.sh with 52% similarity]
docker/prod/docker-compose.yml
docker/prod/migrate-pictshare-to-pictrs.bash [new file with mode: 0644]
docs/src/administration_install_docker.md
docs/src/contributing.md
docs/src/contributing_docker_development.md
docs/src/contributing_local_development.md
server/Cargo.lock
server/Cargo.toml
server/src/api/community.rs
server/src/api/mod.rs
server/src/api/post.rs
server/src/apub/activities.rs
server/src/apub/extensions/signatures.rs
server/src/apub/fetcher.rs
server/src/apub/mod.rs
server/src/lib.rs
server/src/version.rs
ui/assets/css/themes/_variables.litely.scss [new file with mode: 0644]
ui/assets/css/themes/litely.min.css [new file with mode: 0644]
ui/src/components/comment-form.tsx
ui/src/components/comment-node.tsx
ui/src/components/community-form.tsx
ui/src/components/inbox.tsx
ui/src/components/login.tsx
ui/src/components/navbar.tsx
ui/src/components/post-form.tsx
ui/src/components/post-listing.tsx
ui/src/components/private-message-form.tsx
ui/src/components/private-message.tsx
ui/src/components/site-form.tsx
ui/src/components/user-listing.tsx
ui/src/components/user.tsx
ui/src/index.html
ui/src/services/UserService.ts
ui/src/utils.ts
ui/src/version.ts
ui/translations/en.json
ui/translations/es.json
ui/translations/fr.json
ui/translations/hu.json
ui/translations/zh.json

index e0270d4c7d2f889a68629acee1ba8f9f707c33df..71d4455d46b74d2ea610273c6a2845b618aa20e4 100644 (file)
@@ -30,6 +30,6 @@ In the Lemmy community we strive to go the extra step to look out for each other
 
 And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make others comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
 
-The enforcement policies listed above apply to all official Lemmy venues; including git repositories under [github.com/LemmyNet/lemmy](https://github.com/LemmyNet/lemmy) and [yerbamate.dev/dessalines/lemmy](https://yerbamate.dev/dessalines/lemmy), the [Matrix channel](https://matrix.to/#/!BZVTUuEiNmRcbFeLeI:matrix.org?via=matrix.org&via=privacytools.io&via=permaweb.io); and all instances under lemmy.ml. For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
+The enforcement policies listed above apply to all official Lemmy venues; including git repositories under [github.com/LemmyNet/lemmy](https://github.com/LemmyNet/lemmy) and [yerbamate.dev/LemmyNet/lemmy](https://yerbamate.dev/LemmyNet/lemmy), the [Matrix channel](https://matrix.to/#/!BZVTUuEiNmRcbFeLeI:matrix.org?via=matrix.org&via=privacytools.io&via=permaweb.io); and all instances under lemmy.ml. For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
 
 Adapted from the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct), which is based on the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).
index 5a4c7645ee18f56bc9673d9c42f69a6c4c9d4aa1..9946ae32184f3b512a0c46fe51de5ca6de319cd4 100644 (file)
@@ -1,3 +1,66 @@
+# Lemmy v0.7.0 Release (2020-06-23)
+
+This release replaces [pictshare](https://github.com/HaschekSolutions/pictshare)
+with [pict-rs](https://git.asonix.dog/asonix/pict-rs), which improves performance
+and security.
+
+Overall, since our last major release in January (v0.6.0), we have closed over
+[100 issues!](https://github.com/LemmyNet/lemmy/milestone/16?closed=1)
+
+- Site-wide list of recent comments
+- Reconnecting websockets
+- Many more themes, including a default light one.
+- Expandable embeds for post links (and thumbnails), from
+[iframely](https://github.com/itteco/iframely)
+- Better icons
+- Emoji autocomplete to post and message bodies, and an Emoji Picker
+- Post body now searchable
+- Community title and description is now searchable
+- Simplified cross-posts
+- Better documentation
+- LOTS more languages
+- Lots of bugs squashed
+- And more ...
+
+## Upgrading
+
+Before starting the upgrade, make sure that you have a working backup of your
+database and image files. See our
+[documentation](https://dev.lemmy.ml/docs/administration_backup_and_restore.html)
+for backup instructions.
+
+**With Ansible:**
+
+```
+# deploy with ansible from your local lemmy git repo
+git pull
+cd ansible
+ansible-playbook lemmy.yml
+# connect via ssh to run the migration script
+ssh your-server
+cd /lemmy/
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/prod/migrate-pictshare-to-pictrs.bash
+chmod +x migrate-pictshare-to-pictrs.bash
+sudo ./migrate-pictshare-to-pictrs.bash
+```
+
+**With manual Docker installation:**
+```
+# run these commands on your server
+cd /lemmy
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/ansible/templates/nginx.conf
+# Replace the {{ vars }}
+sudo mv nginx.conf /etc/nginx/sites-enabled/lemmy.conf
+sudo nginx -s reload
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/prod/docker-compose.yml
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/prod/migrate-pictshare-to-pictrs.bash
+chmod +x migrate-pictshare-to-pictrs.bash
+sudo bash migrate-pictshare-to-pictrs.bash
+```
+
+**Note:** After upgrading, all users need to reload the page, then logout and
+login again, so that images are loaded correctly.
+
 # Lemmy v0.6.0 Release (2020-01-16)
 
 `v0.6.0` is here, and we've closed [41 issues!](https://github.com/LemmyNet/lemmy/milestone/15?closed=1) 
index e31dcbc4276d03baab6643f70ea22014d5828492..8b20e48523e572ecc3221c210f9befbf524c19b4 100644 (file)
@@ -1 +1 @@
-v0.6.71
+v0.7.0
index 960a7c40fd58f72b093e88b620a40b401affae52..74b6ab2f1955975f7c50530ebc43eb802f2d3278 100644 (file)
@@ -1,5 +1,6 @@
 [defaults]
 inventory=inventory
+interpreter_python=/usr/bin/python3
 
 [ssh_connection]
 pipelining = True
index bc01623fc55cea14e7a37f3b7bbb4196cd7a170b..7b78ab8d35fbd6ae4be115d99d6ac66d93a6401c 100644 (file)
       creates: '/etc/letsencrypt/live/{{domain}}/privkey.pem'
 
   - name: create lemmy folder
-    file: path={{item.path}} state=directory
+    file: path={{item.path}} {{item.owner}} state=directory
     with_items:
-      - { path: '/lemmy/' }
-      - { path: '/lemmy/volumes/' }
+      - { path: '/lemmy/', owner: 'root' }
+      - { path: '/lemmy/volumes/', owner: 'root' }
+      - { path: '/lemmy/volumes/pictrs/', owner: '991' }
 
   - block:
     - name:  add template files
@@ -59,6 +60,7 @@
       project_src: /lemmy/
       state: present
       pull: yes
+      remove_orphans: yes
 
   - name: reload nginx with new config
     shell: nginx -s reload
index e9b8364f386a85357ca89d16de83f15ec650bfcd..7a3683610ec04a3098cb045b3ef52aabcf7be694 100644 (file)
       creates: '/etc/letsencrypt/live/{{domain}}/privkey.pem'
 
   - name: create lemmy folder
-    file: path={{item.path}} state=directory
+    file: path={{item.path}} owner={{item.owner}} state=directory
     with_items:
-      - { path: '/lemmy/' }
-      - { path: '/lemmy/volumes/' }
+      - { path: '/lemmy/', owner: 'root' }
+      - { path: '/lemmy/volumes/', owner: 'root' }
+      - { path: '/lemmy/volumes/pictrs/', owner: '991' }
 
   - block:
     - name:  add template files
@@ -88,6 +89,7 @@
       project_src: /lemmy/
       state: present
       recreate: always
+      remove_orphans: yes
     ignore_errors: yes
 
   - name: reload nginx with new config
index 9ec1bfbc22d701849a6bacf04670e69ab4d31925..f4c94fd71dba5536bc4a1a74d28027f540239ee9 100644 (file)
@@ -12,7 +12,7 @@ services:
       - ./lemmy.hjson:/config/config.hjson:ro
     depends_on:
       - postgres
-      - pictshare
+      - pictrs
       - iframely
 
   postgres:
@@ -25,12 +25,13 @@ services:
       - ./volumes/postgres:/var/lib/postgresql/data
     restart: always
 
-  pictshare:
-    image: hascheksolutions/pictshare:latest
+  pictrs:
+    image: asonix/pictrs:amd64-v0.1.0-r9
+    user: 991:991
     ports:
-      - "127.0.0.1:8537:80"
+      - "127.0.0.1:8537:8080"
     volumes:
-      - ./volumes/pictshare:/usr/share/nginx/html/data
+      - ./volumes/pictrs:/mnt
     restart: always
 
   iframely:
index a978c18999a755efd31663d56b59bf82b9ef1c66..b710fdb30bde9bf543afd572ccf44d1c70c10c9c 100644 (file)
@@ -48,8 +48,8 @@ server {
     add_header X-Frame-Options "DENY";
     add_header X-XSS-Protection "1; mode=block";
 
-    # Upload limit for pictshare
-    client_max_body_size 50M;
+    # Upload limit for pictrs
+    client_max_body_size 20M;
 
     location / {
         proxy_pass http://0.0.0.0:8536;
@@ -70,15 +70,21 @@ server {
         proxy_cache_min_uses    5;
     }    
 
-    location /pictshare/ {
-      proxy_pass http://0.0.0.0:8537/;
-      proxy_set_header X-Real-IP $remote_addr;
-      proxy_set_header Host $host;
-      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    # Redirect pictshare images to pictrs
+    location ~ /pictshare/(.*)$ {
+      return 301 /pictrs/image/$1;
+    }
 
-      if ($request_uri ~ \.(?:ico|gif|jpe?g|png|webp|bmp|mp4)$) {
-        add_header Cache-Control "public, max-age=31536000, immutable";
-      }   
+    # pict-rs images
+    location /pictrs {
+      location /pictrs/image {
+        proxy_pass http://0.0.0.0:8537/image;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header Host $host;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+      }
+      # Block the import
+      return 403;
     }
 
     location /iframely/ {
index d9ffc2f3855c92c32979fff3d173923a25b7e0fe..82a03f3c954c46a922727d544148237645e455d8 100644 (file)
@@ -21,17 +21,13 @@ COPY server/Cargo.toml server/Cargo.lock ./
 RUN sudo chown -R rust:rust .
 RUN mkdir -p ./src/bin \
   && echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs 
-RUN cargo build --release
+RUN cargo build
 RUN rm -f ./target/x86_64-unknown-linux-musl/release/deps/lemmy_server*
 COPY server/src ./src/
 COPY server/migrations ./migrations/
 
-# Build for release
-RUN cargo build --frozen --release
-
-# Get diesel-cli on there just in case
-# RUN cargo install diesel_cli --no-default-features --features postgres
-
+# Build for debug
+RUN cargo build
 
 FROM ekidd/rust-musl-builder:1.42.0-openssl11 as docs
 WORKDIR /app
@@ -39,15 +35,14 @@ COPY docs ./docs
 RUN sudo chown -R rust:rust .
 RUN mdbook build docs/
 
-
-FROM alpine:3.10
+FROM alpine:3.12
 
 # Install libpq for postgres
 RUN apk add libpq
 
 # Copy resources
 COPY server/config/defaults.hjson /config/defaults.hjson
-COPY --from=rust /app/server/target/x86_64-unknown-linux-musl/release/lemmy_server /app/lemmy
+COPY --from=rust /app/server/target/x86_64-unknown-linux-musl/debug/lemmy_server /app/lemmy
 COPY --from=docs /app/docs/book/ /app/dist/documentation/
 COPY --from=node /app/ui/dist /app/dist
 
diff --git a/docker/dev/Dockerfile.aarch64 b/docker/dev/Dockerfile.aarch64
deleted file mode 100644 (file)
index 9636a59..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-FROM node:10-jessie as node
-
-WORKDIR /app/ui
-
-# Cache deps
-COPY ui/package.json ui/yarn.lock ./
-RUN yarn install --pure-lockfile
-
-# Build
-COPY ui /app/ui
-RUN yarn build
-
-
-# contains qemu-*-static for cross-compilation
-FROM multiarch/qemu-user-static as qemu
-
-
-FROM arm64v8/rust:1.40-buster as rust
-
-COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
-#COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
-
-
-# Install musl
-#RUN apt-get update && apt-get install -y mc
-#RUN apt-get install -y musl-tools mc
-#libpq-dev mc
-#RUN rustup target add ${TARGET}
-
-# Cache deps
-WORKDIR /app
-RUN USER=root cargo new server
-WORKDIR /app/server
-COPY server/Cargo.toml server/Cargo.lock ./
-RUN  mkdir -p ./src/bin \
-  && echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
-RUN cargo build --release
-# RUN cargo build
-COPY server/src ./src/
-COPY server/migrations ./migrations/
-RUN rm -f ./target/release/deps/lemmy_server* ; rm -f ./target/debug/deps/lemmy_server*
-
-
-# build for release
-RUN cargo build --frozen --release
-# RUN cargo build --frozen
-
-# Get diesel-cli on there just in case
-# RUN cargo install diesel_cli --no-default-features --features postgres
-
-# RUN cp /app/server/target/debug/lemmy_server /app/server/ready
-RUN cp /app/server/target/release/lemmy_server /app/server/ready
-
-#FROM alpine:3.10
-# debian because build with dynamic linking with debian:buster
-FROM arm64v8/debian:buster-slim as lemmy
-
-#COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
-COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
-
-# Install libpq for postgres
-#RUN apk add libpq
-RUN apt-get update && apt-get install -y libpq5
-
-RUN addgroup --gid 1000 lemmy
-# for alpine
-#RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
-# for debian
-RUN adduser --disabled-password --shell /bin/sh --uid 1000 --ingroup lemmy lemmy
-
-# Copy resources
-COPY server/config/defaults.hjson /config/defaults.hjson
-COPY --from=rust /app/server/ready /app/lemmy
-COPY --from=node /app/ui/dist /app/dist
-
-RUN chown lemmy:lemmy /app/lemmy
-USER lemmy
-EXPOSE 8536
-CMD ["/app/lemmy"]
diff --git a/docker/dev/Dockerfile.armv7hf b/docker/dev/Dockerfile.armv7hf
deleted file mode 100644 (file)
index c2c9084..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-FROM node:10-jessie as node
-
-WORKDIR /app/ui
-
-# Cache deps
-COPY ui/package.json ui/yarn.lock ./
-RUN yarn install --pure-lockfile
-
-# Build
-COPY ui /app/ui
-RUN yarn build
-
-
-# contains qemu-*-static for cross-compilation
-FROM multiarch/qemu-user-static as qemu
-
-
-FROM arm32v7/rust:1.37-buster as rust
-
-#COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
-COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
-
-
-# Install musl
-#RUN apt-get update && apt-get install -y mc
-#RUN apt-get install -y musl-tools mc
-#libpq-dev mc
-#RUN rustup target add ${TARGET}
-
-# Cache deps
-WORKDIR /app
-RUN USER=root cargo new server
-WORKDIR /app/server
-COPY server/Cargo.toml server/Cargo.lock ./
-RUN  mkdir -p ./src/bin \
-  && echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
-#RUN cargo build --release
-# RUN cargo build
-  RUN RUSTFLAGS='-Ccodegen-units=1' cargo build
-COPY server/src ./src/
-COPY server/migrations ./migrations/
-RUN rm -f ./target/release/deps/lemmy_server* ; rm -f ./target/debug/deps/lemmy_server*
-
-
-# build for release
-#RUN cargo build --frozen --release
-RUN cargo build --frozen
-
-# Get diesel-cli on there just in case
-# RUN cargo install diesel_cli --no-default-features --features postgres
-
-RUN cp /app/server/target/debug/lemmy_server /app/server/ready
-#RUN cp /app/server/target/release/lemmy_server /app/server/ready
-
-#FROM alpine:3.10
-# debian because build with dynamic linking with debian:buster
-FROM arm32v7/debian:buster-slim as lemmy
-
-COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
-
-# Install libpq for postgres
-#RUN apk add libpq
-RUN apt-get update && apt-get install -y libpq5
-
-RUN addgroup --gid 1000 lemmy
-# for alpine
-#RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
-# for debian
-RUN adduser --disabled-password --shell /bin/sh --uid 1000 --ingroup lemmy lemmy
-
-# Copy resources
-COPY server/config/defaults.hjson /config/defaults.hjson
-COPY --from=rust /app/server/ready /app/lemmy
-COPY --from=node /app/ui/dist /app/dist
-
-RUN chown lemmy:lemmy /app/lemmy
-USER lemmy
-EXPOSE 8536
-CMD ["/app/lemmy"]
diff --git a/docker/dev/Dockerfile.libc b/docker/dev/Dockerfile.libc
deleted file mode 100644 (file)
index 6348342..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-# can be build on x64, arm32, arm64 platforms
-# to build on target platform run 
-# docker build -f Dockerfile.libc -t dessalines/lemmy:version ../..
-#
-# to use docker buildx run
-# docker buildx build --platform linux/amd64,linux/arm64 -f Dockerfile.libc -t YOURNAME/lemmy --push ../..
-
-FROM node:12-buster as node
-# use this if use docker buildx 
-#FROM --platform=$BUILDPLATFORM node:12-buster as node
-
-WORKDIR /app/ui
-
-# Cache deps
-COPY ui/package.json ui/yarn.lock ./
-RUN yarn install --pure-lockfile --network-timeout 100000
-
-# Build
-COPY ui /app/ui
-RUN yarn build
-
-
-FROM rust:1.42 as rust
-
-# Cache deps
-WORKDIR /app
-
-RUN USER=root cargo new server
-WORKDIR /app/server
-COPY server/Cargo.toml server/Cargo.lock ./
-RUN  mkdir -p ./src/bin \
-  && echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
-
-
-RUN cargo build --release
-#RUN cargo build && \
-#    rm -f ./target/release/deps/lemmy_server* ; rm -f ./target/debug/deps/lemmy_server*
-COPY server/src ./src/
-COPY server/migrations ./migrations/
-
-
-# build for release
-# workaround for https://github.com/rust-lang/rust/issues/62896
-#RUN RUSTFLAGS='-Ccodegen-units=1' cargo build --release
-RUN cargo build --release --frozen
-#RUN cargo build --frozen
-
-# Get diesel-cli on there just in case
-# RUN cargo install diesel_cli --no-default-features --features postgres
-
-# make result place always the same for lemmy container
-RUN cp /app/server/target/release/lemmy_server /app/server/ready
-#RUN cp /app/server/target/debug/lemmy_server /app/server/ready
-
-
-FROM rust:1.42 as docs
-
-WORKDIR /app
-
-# Build docs
-COPY docs ./docs
-RUN cargo install mdbook
-RUN mdbook build docs/
-
-
-#FROM alpine:3.10
-# debian because build with dynamic linking with debian:buster
-FROM debian:buster as lemmy
-
-# Install libpq for postgres
-#RUN apk add libpq
-RUN apt-get update && apt-get install -y libpq5
-RUN addgroup --gid 1000 lemmy
-# for alpine
-#RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
-# for debian
-RUN adduser --disabled-password --shell /bin/sh --uid 1000 --ingroup lemmy lemmy
-
-# Copy resources
-COPY server/config/defaults.hjson /config/defaults.hjson
-COPY --from=node /app/ui/dist /app/dist
-COPY --from=docs /app/docs/book/ /app/dist/documentation/
-COPY --from=rust /app/server/ready /app/lemmy
-
-RUN chown lemmy:lemmy /app/lemmy
-USER lemmy
-EXPOSE 8536
-CMD ["/app/lemmy"]
index 3fc94099044821bd60530fe77354ab2f7f4fccc7..bdcb4308ab4bdbf80491d2ed7e60a7f6ff46e886 100644 (file)
@@ -1,15 +1,6 @@
 version: '3.3'
 
 services:
-  postgres:
-    image: postgres:12-alpine
-    environment:
-      - POSTGRES_USER=lemmy
-      - POSTGRES_PASSWORD=password
-      - POSTGRES_DB=lemmy
-    volumes:
-      - ./volumes/postgres:/var/lib/postgresql/data
-    restart: always
 
   lemmy:
     build: 
@@ -22,17 +13,28 @@ services:
       - RUST_LOG=debug
     volumes:
       - ../lemmy.hjson:/config/config.hjson
-    depends_on:
+    depends_on: 
+      - pictrs
       - postgres
-      - pictshare
       - iframely
 
-  pictshare:
-    image: hascheksolutions/pictshare:latest
-    ports:
-      - "127.0.0.1:8537:80"
+  postgres:
+    image: postgres:12-alpine
+    environment:
+      - POSTGRES_USER=lemmy
+      - POSTGRES_PASSWORD=password
+      - POSTGRES_DB=lemmy
+    volumes:
+      - ./volumes/postgres:/var/lib/postgresql/data
+    restart: always
+
+  pictrs:
+    image: asonix/pictrs:v0.1.13-r0
+    ports: 
+      - "127.0.0.1:8537:8080"
+    user: 991:991
     volumes:
-      - ./volumes/pictshare:/usr/share/nginx/html/data
+      - ./volumes/pictrs:/mnt
     restart: always
 
   iframely:
index 9d0f45429952c5b44ba073fc3c725f5e6d262862..21e92ba88f811a6a8035815b80fc714a02731d07 100755 (executable)
@@ -1,2 +1,6 @@
 #!/bin/sh
+set -e
+
+export COMPOSE_DOCKER_CLI_BUILD=1
+export DOCKER_BUILDKIT=1
 docker-compose up -d --no-deps --build
index fb09e4f11588fc57c6fe7056f633e7ad049885c5..c2ecc0c897578f4837d9830fd57350e1265a5a62 100755 (executable)
@@ -4,7 +4,9 @@ set -e
 BRANCH=$1
 
 git checkout $BRANCH
-cd ../../
+
+export COMPOSE_DOCKER_CLI_BUILD=1
+export DOCKER_BUILDKIT=1
 
 # Rebuilding dev docker
 sudo docker build . -f "docker/dev/Dockerfile" -t "dessalines/lemmy:$BRANCH"
index 4379eb386c6b3db44468cb89848e6661e4c8a84d..585f2b4b56f24af28a0bc9015f9d05389c0218a0 100644 (file)
@@ -12,11 +12,11 @@ services:
       - ../federation/nginx.conf:/etc/nginx/nginx.conf
     depends_on:
       - lemmy_alpha
-      - pictshare_alpha
+      - pictrs_alpha
       - lemmy_beta
-      - pictshare_beta
+      - pictrs_beta
       - lemmy_gamma
-      - pictshare_gamma
+      - pictrs_gamma
       - iframely
     restart: "always"
 
@@ -48,10 +48,11 @@ services:
     volumes:
       - ./volumes/postgres_alpha:/var/lib/postgresql/data
     restart: always
-  pictshare_alpha:
-    image: shtripok/pictshare:latest
+  pictrs_alpha:
+    image: asonix/pictrs:v0.1.13-r0
+    user: 991:991
     volumes:
-      - ./volumes/pictshare_alpha:/usr/share/nginx/html/data
+      - ./volumes/pictrs_alpha:/mnt
     restart: always
 
   lemmy_beta:
@@ -82,10 +83,11 @@ services:
     volumes:
       - ./volumes/postgres_beta:/var/lib/postgresql/data
     restart: always
-  pictshare_beta:
-    image: shtripok/pictshare:latest
+  pictrs_beta:
+    image: asonix/pictrs:v0.1.13-r0
+    user: 991:991
     volumes:
-      - ./volumes/pictshare_beta:/usr/share/nginx/html/data
+      - ./volumes/pictrs_beta:/mnt
     restart: always
 
   lemmy_gamma:
@@ -116,10 +118,11 @@ services:
     volumes:
       - ./volumes/postgres_gamma:/var/lib/postgresql/data
     restart: always
-  pictshare_gamma:
-    image: shtripok/pictshare:latest
+  pictrs_gamma:
+    image: asonix/pictrs:v0.1.13-r0
+    user: 991:991
     volumes:
-      - ./volumes/pictshare_gamma:/usr/share/nginx/html/data
+      - ./volumes/pictrs_gamma:/mnt
     restart: always
 
   iframely:
index a73b0954e24fc18e7d4f0a005c783fb10a8de838..25160eb6c497db913414efdf95df32b10f1ac17d 100644 (file)
@@ -23,11 +23,16 @@ http {
             proxy_set_header Connection "upgrade";
         }
 
-        location /pictshare/ {
-            proxy_pass http://pictshare_alpha:80/;
+        # pict-rs images
+        location /pictrs {
+          location /pictrs/image {
+            proxy_pass http://pictrs_alpha:8080/image;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header Host $host;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+          }
+          # Block the import
+          return 403;
         }
 
         location /iframely/ {
@@ -58,11 +63,16 @@ http {
             proxy_set_header Connection "upgrade";
         }
 
-        location /pictshare/ {
-            proxy_pass http://pictshare_beta:80/;
+        # pict-rs images
+        location /pictrs {
+          location /pictrs/image {
+            proxy_pass http://pictrs_beta:8080/image;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header Host $host;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+          }
+          # Block the import
+          return 403;
         }
 
         location /iframely/ {
@@ -93,11 +103,16 @@ http {
             proxy_set_header Connection "upgrade";
         }
 
-        location /pictshare/ {
-            proxy_pass http://pictshare_gamma:80/;
+        # pict-rs images
+        location /pictrs {
+          location /pictrs/image {
+            proxy_pass http://pictrs_gamma:8080/image;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header Host $host;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+          }
+          # Block the import
+          return 403;
         }
 
         location /iframely/ {
index 206a324021b2dcb33b98f4249e7caecada50a70a..bc73fff63140093df71368a67997f97de96f9b98 100755 (executable)
@@ -20,4 +20,9 @@ popd || exit
 
 sudo docker build ../../ --file Dockerfile -t lemmy-federation:latest
 
+for Item in alpha beta gamma ; do
+  sudo mkdir -p volumes/pictrs_$Item
+  sudo chown -R 991:991 volumes/pictrs_$Item
+done
+
 sudo docker-compose up
diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile
new file mode 100644 (file)
index 0000000..54485a3
--- /dev/null
@@ -0,0 +1,64 @@
+ARG RUST_BUILDER_IMAGE=shtripok/rust-musl-builder:arm
+
+FROM $RUST_BUILDER_IMAGE as rust
+
+#ARG RUSTRELEASEDIR="debug"
+ARG RUSTRELEASEDIR="release"
+
+# Cache deps
+WORKDIR /app
+RUN sudo chown -R rust:rust .
+RUN USER=root cargo new server
+WORKDIR /app/server
+COPY --chown=rust:rust server/Cargo.toml server/Cargo.lock ./
+#RUN sudo chown -R rust:rust .
+RUN mkdir -p ./src/bin \
+   && echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
+RUN cargo build --release
+RUN rm -f ./target/$CARGO_BUILD_TARGET/$RUSTRELEASEDIR/deps/lemmy_server*
+COPY --chown=rust:rust server/src ./src/
+COPY --chown=rust:rust server/migrations ./migrations/
+
+# build for release
+# workaround for https://github.com/rust-lang/rust/issues/62896
+RUN cargo build --frozen --release
+
+# reduce binary size
+RUN strip ./target/$CARGO_BUILD_TARGET/$RUSTRELEASEDIR/lemmy_server
+
+RUN cp ./target/$CARGO_BUILD_TARGET/$RUSTRELEASEDIR/lemmy_server /app/server/
+
+FROM $RUST_BUILDER_IMAGE as docs
+WORKDIR /app
+COPY --chown=rust:rust docs ./docs
+RUN mdbook build docs/
+
+FROM node:12-buster as node
+
+WORKDIR /app/ui
+
+# Cache deps
+COPY ui/package.json ui/yarn.lock ./
+RUN yarn install --pure-lockfile --network-timeout 600000
+
+# Build
+COPY ui /app/ui
+RUN yarn build
+
+FROM alpine:3.12 as lemmy
+
+# Install libpq for postgres
+RUN apk add libpq
+RUN addgroup -g 1000 lemmy
+RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
+
+# Copy resources
+COPY --chown=lemmy:lemmy server/config/defaults.hjson /config/defaults.hjson
+COPY --chown=lemmy:lemmy --from=rust /app/server/lemmy_server /app/lemmy
+COPY --chown=lemmy:lemmy --from=docs /app/docs/book/ /app/dist/documentation/
+COPY --chown=lemmy:lemmy --from=node /app/ui/dist /app/dist
+
+RUN chown lemmy:lemmy /app/lemmy
+USER lemmy
+EXPOSE 8536
+CMD ["/app/lemmy"]
similarity index 52%
rename from docker/dev/deploy.sh
rename to docker/prod/deploy.sh
index 09b21b0b7aa35a4525b23e4fed348b36a7f1ea74..2c6e3d312758b583eec6212724af909468b326d6 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/sh
+set -e
 git checkout master
 
 # Import translations
@@ -20,7 +21,7 @@ git add "server/src/version.rs"
 echo $new_tag > "ansible/VERSION"
 git add "ansible/VERSION"
 
-cd docker/dev || exit
+cd docker/prod || exit
 
 # Changing the docker-compose prod
 sed -i "s/dessalines\/lemmy:.*/dessalines\/lemmy:$new_tag/" ../prod/docker-compose.yml
@@ -32,41 +33,24 @@ git add ../../ansible/templates/docker-compose.yml
 git commit -m"Version $new_tag"
 git tag $new_tag
 
-# Rebuilding docker
-docker-compose build
-docker tag dev_lemmy:latest dessalines/lemmy:x64-$new_tag
-docker push dessalines/lemmy:x64-$new_tag
-
-# Build for Raspberry Pi / other archs
-
-# Arm currently not working
-# docker build -t lemmy:armv7hf -f Dockerfile.armv7hf ../../
-# docker tag lemmy:armv7hf dessalines/lemmy:armv7hf-$new_tag
-# docker push dessalines/lemmy:armv7hf-$new_tag
-
-# aarch64
-# Only do this on major releases (IE the third semver is 0)
-if [ $third_semver -eq 0 ]; then
-  # Registering qemu binaries
-  docker run --rm --privileged multiarch/qemu-user-static:register --reset
+export COMPOSE_DOCKER_CLI_BUILD=1
+export DOCKER_BUILDKIT=1
 
-  docker build -t lemmy:aarch64 -f Dockerfile.aarch64 ../../
-  docker tag lemmy:aarch64 dessalines/lemmy:arm64-$new_tag
-  docker push dessalines/lemmy:arm64-$new_tag
-fi
-
-# Creating the manifest for the multi-arch build
+# Rebuilding docker
 if [ $third_semver -eq 0 ]; then
-  docker manifest create dessalines/lemmy:$new_tag \
-  dessalines/lemmy:x64-$new_tag \
-  dessalines/lemmy:arm64-$new_tag
+  # TODO get linux/arm/v7 build working
+  # Build for Raspberry Pi / other archs too
+  docker buildx build --platform linux/amd64,linux/arm64 ../../ \
+    --file Dockerfile \
+    --tag dessalines/lemmy:$new_tag \
+    --push
 else
-  docker manifest create dessalines/lemmy:$new_tag \
-  dessalines/lemmy:x64-$new_tag
+  docker buildx build --platform linux/amd64 ../../ \
+    --file Dockerfile \
+    --tag dessalines/lemmy:$new_tag \
+    --push
 fi
 
-docker manifest push dessalines/lemmy:$new_tag
-
 # Push
 git push origin $new_tag
 git push
index db6e4004569dd03d8bc34b209241f898a24f5200..e2774d64dce2abf70fe9864618a1b28b06364494 100644 (file)
@@ -12,7 +12,7 @@ services:
     restart: always
 
   lemmy:
-    image: dessalines/lemmy:v0.6.71
+    image: dessalines/lemmy:v0.7.0
     ports:
       - "127.0.0.1:8536:8536"
     restart: always
@@ -22,17 +22,17 @@ services:
       - ./lemmy.hjson:/config/config.hjson
     depends_on:
       - postgres
-      - pictshare
+      - pictrs
       - iframely
 
-  pictshare:
-    image: hascheksolutions/pictshare:latest
-    ports:
-      - "127.0.0.1:8537:80"
+  pictrs:
+    image: asonix/pictrs:v0.1.13-r0
+    ports: 
+      - "127.0.0.1:8537:8080"
+    user: 991:991
     volumes:
-      - ./volumes/pictshare:/usr/share/nginx/html/data
+      - ./volumes/pictrs:/mnt
     restart: always
-    mem_limit: 100m
 
   iframely:
     image: dogbin/iframely:latest
diff --git a/docker/prod/migrate-pictshare-to-pictrs.bash b/docker/prod/migrate-pictshare-to-pictrs.bash
new file mode 100644 (file)
index 0000000..8229eb2
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/bash
+set -e
+
+if [[ $(id -u) != 0 ]]; then 
+    echo "This migration needs to be run as root"
+    exit
+fi
+
+if [[ ! -f docker-compose.yml ]]; then 
+    echo "No docker-compose.yml found in current directory. Is this the right folder?"
+    exit
+fi
+
+# Fixing pictrs permissions
+mkdir -p volumes/pictrs
+sudo chown -R 991:991 volumes/pictrs
+
+echo "Restarting docker-compose, making sure that pictrs is started and pictshare is removed"
+docker-compose up -d --remove-orphans
+
+if [[ -z $(docker-compose ps | grep pictrs) ]]; then
+    echo "Pict-rs is not running, make sure you update Lemmy first"
+    exit
+fi
+
+# echo "Stopping Lemmy so that users dont upload new images during the migration"
+# docker-compose stop lemmy
+
+pushd volumes/pictshare/
+echo "Importing pictshare images to pict-rs..."
+IMAGE_NAMES=*
+for image in $IMAGE_NAMES; do
+    IMAGE_PATH="$(pwd)/$image/$image"
+    if [[ ! -f $IMAGE_PATH ]]; then
+        continue
+    fi
+    echo -e "\nImporting $IMAGE_PATH"
+    ret=0
+    curl --silent --fail -F "images[]=@$IMAGE_PATH" http://127.0.0.1:8537/import || ret=$?
+    if [[ $ret != 0 ]]; then
+      echo "Error for $IMAGE_PATH : $ret"
+    fi
+done
+
+echo "Fixing permissions on pictshare folder"
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod 644 {} \;
+
+popd
+
+echo "Rewrite image links in Lemmy database"
+docker-compose exec -u  postgres postgres psql -U lemmy -c "UPDATE user_ SET avatar = REPLACE(avatar, 'pictshare', 'pictrs/image') WHERE avatar is not null;"
+docker-compose exec -u  postgres postgres psql -U lemmy -c "UPDATE post SET url = REPLACE(url, 'pictshare', 'pictrs/image') WHERE url is not null;"
+
+echo "Moving pictshare data folder to pictshare_backup"
+mv volumes/pictshare volumes/pictshare_backup
+
+echo "Migration done, starting Lemmy again"
+echo "If everything went well, you can delete ./volumes/pictshare_backup/"
+docker-compose start lemmy
index 236faa6bde895a83d6193e09029fa59e2dc4d04c..a2bed794f9fb0a0d4a0b34c1441574d5f5f0710a 100644 (file)
@@ -6,20 +6,25 @@ Make sure you have both docker and docker-compose(>=`1.24.0`) installed. On Ubun
 # create a folder for the lemmy files. the location doesnt matter, you can put this anywhere you want
 mkdir /lemmy
 cd /lemmy
+
 # download default config files
-wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/prod/docker-compose.yml
-wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/lemmy.hjson
-wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/iframely.config.local.js
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/prod/docker-compose.yml
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/lemmy.hjson
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/iframely.config.local.js
+
+# Set correct permissions for pictrs folder
+mkdir -p volumes/pictrs
+sudo chown -R 991:991 volumes/pictrs
 ```
 
 After this, have a look at the [config file](administration_configuration.md) named `lemmy.hjson`, and adjust it, in particular the hostname, and possibly the db password. Then run:
 
 `docker-compose up -d`
 
-To make Lemmy available outside the server, you need to setup a reverse proxy, like Nginx. [A sample nginx config](https://raw.githubusercontent.com/dessalines/lemmy/master/ansible/templates/nginx.conf), could be setup with:
+To make Lemmy available outside the server, you need to setup a reverse proxy, like Nginx. [A sample nginx config](https://raw.githubusercontent.com/LemmyNet/lemmy/master/ansible/templates/nginx.conf), could be setup with:
 
 ```bash
-wget https://raw.githubusercontent.com/dessalines/lemmy/master/ansible/templates/nginx.conf
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/ansible/templates/nginx.conf
 # Replace the {{ vars }}
 sudo mv nginx.conf /etc/nginx/sites-enabled/lemmy.conf
 ```
@@ -31,6 +36,6 @@ You will also need to setup TLS, for example with [Let's Encrypt](https://letsen
 To update to the newest version, you can manually change the version in `docker-compose.yml`. Alternatively, fetch the latest version from our git repo:
 
 ```bash
-wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/prod/docker-compose.yml
+wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/prod/docker-compose.yml
 docker-compose up -d
 ```
index 4eabd6fc71a5fc38ab2c31dbbe4fb9fbdf4d48ef..69d2f42ead2b7f0b8b03b831af824f630136a303 100644 (file)
@@ -5,7 +5,7 @@ Information about contributing to Lemmy, whether it is translating, testing, des
 ## Issue tracking / Repositories
 
 - [GitHub (for issues)](https://github.com/LemmyNet/lemmy)
-- [Gitea](https://yerbamate.dev/dessalines/lemmy)
+- [Gitea](https://yerbamate.dev/LemmyNet/lemmy)
 - [GitLab](https://gitlab.com/dessalines/lemmy)
 
 ## Translating
index 092398219ba34ac29d6755bdb7fad4dd42c4f183..afa05107281c355775cd99903539736422f43cb1 100644 (file)
@@ -3,11 +3,22 @@
 ## Running
 
 ```bash
+sudo apt install git docker-compose
 git clone https://github.com/LemmyNet/lemmy
 cd lemmy/docker/dev
-./docker_update.sh # This builds and runs it, updating for your changes
+sudo docker-compose up --no-deps --build
 ```
 
 and go to http://localhost:8536.
 
-Note that compile times when changing `Cargo.toml` are relatively long with Docker, because builds can't be incrementally cached. If this is a problem for you, you should use [Local Development](contributing_local_development.md).
+To speed up the Docker compile, add the following to `/etc/docker/daemon.json` and restart Docker.
+```
+{
+  "features": {
+    "buildkit": true
+  }
+}
+```
+
+If the build is still too slow, you will have to use a
+[local build](contributing_local_development.md) instead.
index e823c9d1b8cc18704b633c80bd66f1aecd33bdbf..066386f50747eac553368c0ec998e7e7ca77a98f 100644 (file)
@@ -1,31 +1,67 @@
-#### Requirements
+### Ubuntu
 
-- [Rust](https://www.rust-lang.org/)
-- [Yarn](https://yarnpkg.com/en/)
-- [Postgres](https://www.postgresql.org/)
 
-#### Set up Postgres DB
+#### Build requirements:
+```
+sudo apt install git cargo libssl-dev pkg-config libpq-dev yarn curl gnupg2 git
+# install yarn
+curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
+echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
+sudo apt update && sudo apt install yarn
+```
+
+#### Get the source code
+```
+git clone https://github.com/LemmyNet/lemmy.git
+# or alternatively from gitea
+# git clone https://yerbamate.dev/LemmyNet/lemmy.git
+```
+
+All the following commands need to be run either in `lemmy/server` or `lemmy/ui`, as indicated
+by the `cd` command.
 
-```bash
+#### Build the backend (Rust)
+```
 cd server
-./db-init.sh
+cargo build
+# for development, use `cargo check` instead)
 ```
 
-Or run the commands manually:
+#### Build the frontend (Typescript)
+```
+cd ui
+yarn
+yarn build
+```
 
-```bash
-psql -c "create user lemmy with password 'password' superuser;" -U postgres
-psql -c 'create database lemmy with owner lemmy;' -U postgres
+#### Setup postgresql
+```
+sudo apt install postgresql
+sudo systemctl start postgresql
+# initialize postgres database
+sudo -u postgres psql -c "create user lemmy with password 'password' superuser;" -U postgres
+sudo -u postgres psql -c 'create database lemmy with owner lemmy;' -U postgres
 export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
+# or execute server/db-init.sh
 ```
 
-#### Running
+#### Run a local development instance
+```
+# run each of these in a seperate terminal
+cd server && cargo run
+ui & yarn start
+```
 
-```bash
-git clone https://github.com/LemmyNet/lemmy
-cd lemmy
-./install.sh
-# For live coding, where both the front and back end, automagically reload on any save, do:
-# cd ui && yarn start
-# cd server && cargo watch -x run
+Then open [localhost:4444](http://localhost:4444) in your browser. It will auto-refresh if you edit
+any frontend files. For backend coding, you will have to rerun `cargo run`. You can use
+`cargo check` as a faster way to find compilation errors.
+
+To speed up incremental builds, you can add the following to `~/.cargo/config`:
+```
+[target.x86_64-unknown-linux-gnu]
+rustflags = ["-Clink-arg=-fuse-ld=lld"]
 ```
+
+Note that this setup doesn't include image uploads or link previews (provided by pict-rs and
+iframely respectively). If you want to test those, you should use the
+[Docker development](contributing_docker_development.md).
index 55ec0509b3a6b02e4e328413cfcecb182a1c9369..f124396b7e3200ab361bfbe9b4976cc4da9fa38b 100644 (file)
@@ -9,8 +9,8 @@ dependencies = [
  "activitystreams-derive",
  "chrono",
  "mime",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "serde 1.0.114",
+ "serde_json",
  "thiserror",
  "url",
 ]
@@ -32,18 +32,18 @@ version = "0.1.0"
 source = "git+https://git.asonix.dog/asonix/activitystreams-ext#e5c97f4ea9f60e49bc7ff27fb0fb515d3190fd25"
 dependencies = [
  "activitystreams-new",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "serde 1.0.114",
+ "serde_json",
 ]
 
 [[package]]
 name = "activitystreams-new"
 version = "0.1.0"
-source = "git+https://git.asonix.dog/asonix/activitystreams-sketch#05a2bdc98d5595b0a74fd79b7e1b19f382ad3139"
+source = "git+https://git.asonix.dog/asonix/activitystreams-sketch#99c7e9aa5596eda846a1ebd5978ca72d11d4c08a"
 dependencies = [
  "activitystreams",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "serde 1.0.114",
+ "serde_json",
  "typed-builder",
 ]
 
@@ -61,7 +61,7 @@ dependencies = [
  "crossbeam-channel",
  "derive_more",
  "futures",
- "lazy_static 1.4.0",
+ "lazy_static",
  "log",
  "parking_lot",
  "pin-project",
@@ -159,15 +159,15 @@ dependencies = [
  "httparse",
  "indexmap",
  "language-tags",
- "lazy_static 1.4.0",
+ "lazy_static",
  "log",
  "mime",
  "percent-encoding",
  "pin-project",
  "rand 0.7.3",
- "regex 1.3.9",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "regex",
+ "serde 1.0.114",
+ "serde_json",
  "serde_urlencoded",
  "sha1",
  "slab",
@@ -193,8 +193,8 @@ dependencies = [
  "bytestring",
  "http",
  "log",
- "regex 1.3.9",
- "serde 1.0.111",
+ "regex",
+ "serde 1.0.114",
 ]
 
 [[package]]
@@ -264,7 +264,7 @@ checksum = "91164716d956745c79dcea5e66d2aa04506549958accefcede5368c70f2fd4ff"
 dependencies = [
  "derive_more",
  "futures-channel",
- "lazy_static 1.4.0",
+ "lazy_static",
  "log",
  "num_cpus",
  "parking_lot",
@@ -333,9 +333,9 @@ dependencies = [
  "mime",
  "net2",
  "pin-project",
- "regex 1.3.9",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "regex",
+ "serde 1.0.114",
+ "serde_json",
  "serde_urlencoded",
  "time",
  "url",
@@ -380,35 +380,26 @@ dependencies = [
 
 [[package]]
 name = "addr2line"
-version = "0.12.1"
+version = "0.12.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543"
+checksum = "602d785912f476e480434627e8732e6766b760c045bbf897d9dfaa9f4fbd399c"
 dependencies = [
  "gimli",
 ]
 
 [[package]]
 name = "adler32"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
-
-[[package]]
-name = "aho-corasick"
-version = "0.5.3"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
-dependencies = [
- "memchr 0.1.11",
-]
+checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.10"
+version = "0.7.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
+checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
 dependencies = [
- "memchr 2.3.3",
+ "memchr",
 ]
 
 [[package]]
@@ -422,18 +413,15 @@ dependencies = [
 
 [[package]]
 name = "arc-swap"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62"
+checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
 
 [[package]]
 name = "arrayvec"
-version = "0.4.12"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
-dependencies = [
- "nodrop",
-]
+checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
 
 [[package]]
 name = "ascii_utils"
@@ -443,15 +431,29 @@ checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
 
 [[package]]
 name = "async-trait"
-version = "0.1.32"
+version = "0.1.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0eb7f9ad01405feb3c1dac82463038945cf88eea4569acaf3ad662233496dd96"
+checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
+[[package]]
+name = "attohttpc"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93610ce1c035e8a273fe56a19852e42798f3c019ca2726e52d2971197f116525"
+dependencies = [
+ "http",
+ "log",
+ "rustls",
+ "url",
+ "webpki",
+ "webpki-roots",
+]
+
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -493,20 +495,21 @@ dependencies = [
  "mime",
  "percent-encoding",
  "rand 0.7.3",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "serde 1.0.114",
+ "serde_json",
  "serde_urlencoded",
 ]
 
 [[package]]
 name = "backtrace"
-version = "0.3.48"
+version = "0.3.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130"
+checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c"
 dependencies = [
  "addr2line",
  "cfg-if",
  "libc",
+ "miniz_oxide",
  "object",
  "rustc-demangle",
 ]
@@ -538,9 +541,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 
 [[package]]
 name = "base64"
-version = "0.12.1"
+version = "0.12.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
+checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67"
 
 [[package]]
 name = "bcrypt"
@@ -548,7 +551,7 @@ version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "41b70db86f3c560199b0dada79a22b9a924622384abb2a756a9707ffcce077f2"
 dependencies = [
- "base64 0.12.1",
+ "base64 0.12.2",
  "blowfish",
  "byteorder",
  "getrandom",
@@ -647,9 +650,12 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
 
 [[package]]
 name = "bytes"
-version = "0.5.4"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
+checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b"
+dependencies = [
+ "loom",
+]
 
 [[package]]
 name = "bytestring"
@@ -679,8 +685,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
 dependencies = [
  "num-integer",
- "num-traits 0.2.11",
- "serde 1.0.111",
+ "num-traits 0.2.12",
+ "serde 1.0.114",
  "time",
 ]
 
@@ -716,10 +722,10 @@ checksum = "e17058cc536cf290563e88787d7b9e6030ce4742943017cc2ffb71f88034021c"
 dependencies = [
  "clap",
  "entities",
- "lazy_static 1.4.0",
+ "lazy_static",
  "pest",
  "pest_derive",
- "regex 1.3.9",
+ "regex",
  "twoway",
  "typed-arena",
  "unicode_categories",
@@ -731,14 +737,10 @@ version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3"
 dependencies = [
- "lazy_static 1.4.0",
- "nom 5.1.1",
- "rust-ini",
- "serde 1.0.111",
- "serde-hjson 0.9.1",
- "serde_json 1.0.53",
- "toml",
- "yaml-rust",
+ "lazy_static",
+ "nom 5.1.2",
+ "serde 1.0.114",
+ "serde-hjson",
 ]
 
 [[package]]
@@ -790,38 +792,7 @@ checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
 dependencies = [
  "autocfg 1.0.0",
  "cfg-if",
- "lazy_static 1.4.0",
-]
-
-[[package]]
-name = "curl"
-version = "0.4.29"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "762e34611d2d5233a506a79072be944fddd057db2f18e04c0d6fa79e3fd466fd"
-dependencies = [
- "curl-sys",
- "libc",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "socket2",
- "winapi 0.3.8",
-]
-
-[[package]]
-name = "curl-sys"
-version = "0.4.31+curl-7.70.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcd62757cc4f5ab9404bc6ca9f0ae447e729a1403948ce5106bd588ceac6a3b0"
-dependencies = [
- "cc",
- "libc",
- "libnghttp2-sys",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
- "vcpkg",
- "winapi 0.3.8",
+ "lazy_static",
 ]
 
 [[package]]
@@ -886,9 +857,9 @@ dependencies = [
 
 [[package]]
 name = "derive_more"
-version = "0.99.7"
+version = "0.99.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d"
+checksum = "bc655351f820d774679da6cdc23355a93de496867d8203496675162e17b1d671"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -897,9 +868,9 @@ dependencies = [
 
 [[package]]
 name = "diesel"
-version = "1.4.4"
+version = "1.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33d7ca63eb2efea87a7f56a283acc49e2ce4b2bd54adf7465dc1d81fef13d8fc"
+checksum = "3e2de9deab977a153492a1468d1b1c0662c1cf39e5ea87d0c060ecd59ef18d8c"
 dependencies = [
  "bitflags",
  "byteorder",
@@ -907,7 +878,7 @@ dependencies = [
  "diesel_derives",
  "pq-sys",
  "r2d2",
- "serde_json 1.0.53",
+ "serde_json",
 ]
 
 [[package]]
@@ -940,18 +911,6 @@ dependencies = [
  "generic-array",
 ]
 
-[[package]]
-name = "docopt"
-version = "0.6.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
-dependencies = [
- "lazy_static 0.2.11",
- "regex 0.1.80",
- "rustc-serialize",
- "strsim 0.5.2",
-]
-
 [[package]]
 name = "dotenv"
 version = "0.15.0"
@@ -960,15 +919,9 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
 
 [[package]]
 name = "dtoa"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d"
-
-[[package]]
-name = "dtoa"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
+checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
 
 [[package]]
 name = "either"
@@ -985,7 +938,7 @@ dependencies = [
  "base64 0.9.3",
  "chrono",
  "encoding",
- "lazy_static 1.4.0",
+ "lazy_static",
  "rand 0.4.6",
  "time",
  "version_check 0.1.5",
@@ -1091,7 +1044,7 @@ dependencies = [
  "atty",
  "humantime",
  "log",
- "regex 1.3.9",
+ "regex",
  "termcolor",
 ]
 
@@ -1274,7 +1227,7 @@ dependencies = [
  "futures-macro",
  "futures-sink",
  "futures-task",
- "memchr 2.3.3",
+ "memchr",
  "pin-project",
  "pin-utils",
  "proc-macro-hack",
@@ -1291,6 +1244,19 @@ dependencies = [
  "byteorder",
 ]
 
+[[package]]
+name = "generator"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68"
+dependencies = [
+ "cc",
+ "libc",
+ "log",
+ "rustc_version",
+ "winapi 0.3.8",
+]
+
 [[package]]
 name = "generic-array"
 version = "0.12.3"
@@ -1347,25 +1313,13 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.13"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
+checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909"
 dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "hjson"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0849d73a64ec77d1c8354aff489cf31943c4b4d3716de1eabfba572c70fde530"
-dependencies = [
- "docopt",
- "serde 0.8.23",
- "serde-hjson 0.8.2",
- "serde_json 0.8.6",
-]
-
 [[package]]
 name = "hostname"
 version = "0.1.5"
@@ -1401,7 +1355,7 @@ checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
 dependencies = [
  "bytes",
  "fnv",
- "itoa 0.4.5",
+ "itoa",
 ]
 
 [[package]]
@@ -1476,31 +1430,6 @@ dependencies = [
  "winreg",
 ]
 
-[[package]]
-name = "isahc"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "098c47b6176a9b667292810105999d6029d8338819f299584677e8a125e549c2"
-dependencies = [
- "bytes",
- "crossbeam-channel",
- "crossbeam-utils",
- "curl",
- "curl-sys",
- "encoding_rs",
- "futures-channel",
- "futures-io",
- "futures-util",
- "http",
- "lazy_static 1.4.0",
- "log",
- "mime",
- "slab",
- "sluice",
- "tracing",
- "tracing-futures",
-]
-
 [[package]]
 name = "itertools"
 version = "0.9.0"
@@ -1512,15 +1441,9 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1"
-
-[[package]]
-name = "itoa"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
+checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
 
 [[package]]
 name = "js-sys"
@@ -1533,15 +1456,15 @@ dependencies = [
 
 [[package]]
 name = "jsonwebtoken"
-version = "7.1.0"
+version = "7.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d11f9e80a85927748a334df8e4f6782a04033517bb28f3863a563daad882da7f"
+checksum = "b1f325ae57ddcf609f02d891486ce740f5bbd0cc3e93f9bffaacdf6594b21404"
 dependencies = [
- "base64 0.11.0",
+ "base64 0.12.2",
  "pem",
  "ring",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "serde 1.0.114",
+ "serde_json",
  "simple_asn1",
 ]
 
@@ -1561,12 +1484,6 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
 
-[[package]]
-name = "lazy_static"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
-
 [[package]]
 name = "lazy_static"
 version = "1.4.0"
@@ -1585,7 +1502,8 @@ dependencies = [
  "actix-rt",
  "actix-web",
  "actix-web-actors",
- "base64 0.12.1",
+ "attohttpc",
+ "base64 0.12.2",
  "bcrypt",
  "chrono",
  "comrak",
@@ -1596,24 +1514,22 @@ dependencies = [
  "env_logger",
  "failure",
  "futures",
- "hjson",
  "htmlescape",
  "http",
  "http-signature-normalization",
- "isahc",
  "itertools",
  "jsonwebtoken",
- "lazy_static 1.4.0",
+ "lazy_static",
  "lettre",
  "lettre_email",
  "log",
  "openssl",
  "percent-encoding",
  "rand 0.7.3",
- "regex 1.3.9",
+ "regex",
  "rss",
- "serde 1.0.111",
- "serde_json 1.0.53",
+ "serde 1.0.114",
+ "serde_json",
  "sha2",
  "strum",
  "strum_macros",
@@ -1635,9 +1551,9 @@ dependencies = [
  "log",
  "native-tls",
  "nom 4.2.3",
- "serde 1.0.111",
+ "serde 1.0.114",
  "serde_derive",
- "serde_json 1.0.53",
+ "serde_json",
 ]
 
 [[package]]
@@ -1656,13 +1572,13 @@ dependencies = [
 
 [[package]]
 name = "lexical-core"
-version = "0.6.2"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7043aa5c05dd34fb73b47acb8c3708eac428de4545ea3682ed2f11293ebd890"
+checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
 dependencies = [
  "arrayvec",
+ "bitflags",
  "cfg-if",
- "rustc_version",
  "ryu",
  "static_assertions",
 ]
@@ -1673,28 +1589,6 @@ version = "0.2.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
 
-[[package]]
-name = "libnghttp2-sys"
-version = "0.1.4+1.41.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03624ec6df166e79e139a2310ca213283d6b3c30810c54844f307086d4488df1"
-dependencies = [
- "cc",
- "libc",
-]
-
-[[package]]
-name = "libz-sys"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
 [[package]]
 name = "linked-hash-map"
 version = "0.3.0"
@@ -1729,6 +1623,17 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "loom"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7"
+dependencies = [
+ "cfg-if",
+ "generator",
+ "scoped-tls",
+]
+
 [[package]]
 name = "lru-cache"
 version = "0.1.2"
@@ -1762,15 +1667,6 @@ version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
 
-[[package]]
-name = "memchr"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
-dependencies = [
- "libc",
-]
-
 [[package]]
 name = "memchr"
 version = "2.3.3"
@@ -1816,9 +1712,9 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
+checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
 dependencies = [
  "adler32",
 ]
@@ -1871,7 +1767,7 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
 dependencies = [
- "lazy_static 1.4.0",
+ "lazy_static",
  "libc",
  "log",
  "openssl",
@@ -1894,30 +1790,24 @@ dependencies = [
  "winapi 0.3.8",
 ]
 
-[[package]]
-name = "nodrop"
-version = "0.1.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
-
 [[package]]
 name = "nom"
 version = "4.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
 dependencies = [
- "memchr 2.3.3",
+ "memchr",
  "version_check 0.1.5",
 ]
 
 [[package]]
 name = "nom"
-version = "5.1.1"
+version = "5.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
+checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
 dependencies = [
  "lexical-core",
- "memchr 2.3.3",
+ "memchr",
  "version_check 0.9.2",
 ]
 
@@ -1929,17 +1819,17 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
 dependencies = [
  "autocfg 1.0.0",
  "num-integer",
- "num-traits 0.2.11",
+ "num-traits 0.2.12",
 ]
 
 [[package]]
 name = "num-integer"
-version = "0.1.42"
+version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
+checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
 dependencies = [
  "autocfg 1.0.0",
- "num-traits 0.2.11",
+ "num-traits 0.2.12",
 ]
 
 [[package]]
@@ -1948,14 +1838,14 @@ version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
 dependencies = [
- "num-traits 0.2.11",
+ "num-traits 0.2.12",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.11"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
+checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
 dependencies = [
  "autocfg 1.0.0",
 ]
@@ -1972,9 +1862,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.19.0"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
+checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
 
 [[package]]
 name = "once_cell"
@@ -1997,7 +1887,7 @@ dependencies = [
  "bitflags",
  "cfg-if",
  "foreign-types",
- "lazy_static 1.4.0",
+ "lazy_static",
  "libc",
  "openssl-sys",
 ]
@@ -2010,9 +1900,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.57"
+version = "0.9.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7410fef80af8ac071d4f63755c0ab89ac3df0fd1ea91f1d1f37cf5cec4395990"
+checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
 dependencies = [
  "autocfg 1.0.0",
  "cc",
@@ -2047,13 +1937,13 @@ dependencies = [
 
 [[package]]
 name = "pem"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1581760c757a756a41f0ee3ff01256227bdf64cb752839779b95ffb01c59793"
+checksum = "59698ea79df9bf77104aefd39cc3ec990cb9693fb59c3b0a70ddf2646fdffb4b"
 dependencies = [
- "base64 0.11.0",
- "lazy_static 1.4.0",
- "regex 1.3.9",
+ "base64 0.12.2",
+ "once_cell",
+ "regex",
 ]
 
 [[package]]
@@ -2107,18 +1997,18 @@ dependencies = [
 
 [[package]]
 name = "pin-project"
-version = "0.4.17"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc93aeee735e60ecb40cf740eb319ff23eab1c5748abfdb5c180e4ce49f7791"
+checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17"
 dependencies = [
  "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "0.4.17"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40"
+checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2127,9 +2017,9 @@ dependencies = [
 
 [[package]]
 name = "pin-project-lite"
-version = "0.1.6"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9df32da11d84f3a7d70205549562966279adb900e080fad3dccd8e64afccf0ad"
+checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
 
 [[package]]
 name = "pin-utils"
@@ -2166,9 +2056,9 @@ checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
 
 [[package]]
 name = "proc-macro-nested"
-version = "0.1.4"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
+checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
 
 [[package]]
 name = "proc-macro2"
@@ -2192,14 +2082,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fe1e430bdcf30c9fdc25053b9c459bb1a4672af4617b6c783d7d91dc17c6bbb0"
 dependencies = [
  "encoding_rs",
- "memchr 2.3.3",
+ "memchr",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.6"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
+checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
 dependencies = [
  "proc-macro2",
 ]
@@ -2390,37 +2280,18 @@ version = "0.1.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
 
-[[package]]
-name = "regex"
-version = "0.1.80"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
-dependencies = [
- "aho-corasick 0.5.3",
- "memchr 0.1.11",
- "regex-syntax 0.3.9",
- "thread_local 0.2.7",
- "utf8-ranges",
-]
-
 [[package]]
 name = "regex"
 version = "1.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
 dependencies = [
- "aho-corasick 0.7.10",
- "memchr 2.3.3",
- "regex-syntax 0.6.18",
- "thread_local 1.0.1",
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+ "thread_local",
 ]
 
-[[package]]
-name = "regex-syntax"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
-
 [[package]]
 name = "regex-syntax"
 version = "0.6.18"
@@ -2429,9 +2300,9 @@ checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
 
 [[package]]
 name = "remove_dir_all"
-version = "0.5.2"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
 dependencies = [
  "winapi 0.3.8",
 ]
@@ -2448,9 +2319,9 @@ dependencies = [
 
 [[package]]
 name = "ring"
-version = "0.16.14"
+version = "0.16.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06b3fefa4f12272808f809a0af618501fdaba41a58963c5fb72238ab0be09603"
+checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
 dependencies = [
  "cc",
  "libc",
@@ -2471,24 +2342,12 @@ dependencies = [
  "quick-xml",
 ]
 
-[[package]]
-name = "rust-ini"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
-
 [[package]]
 name = "rustc-demangle"
 version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 
-[[package]]
-name = "rustc-serialize"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
-
 [[package]]
 name = "rustc_version"
 version = "0.2.3"
@@ -2498,6 +2357,19 @@ dependencies = [
  "semver",
 ]
 
+[[package]]
+name = "rustls"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1"
+dependencies = [
+ "base64 0.11.0",
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
 [[package]]
 name = "ryu"
 version = "1.0.5"
@@ -2516,7 +2388,7 @@ version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
 dependencies = [
- "lazy_static 1.4.0",
+ "lazy_static",
  "winapi 0.3.8",
 ]
 
@@ -2529,12 +2401,28 @@ dependencies = [
  "parking_lot",
 ]
 
+[[package]]
+name = "scoped-tls"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
+
 [[package]]
 name = "scopeguard"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
+[[package]]
+name = "sct"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
 [[package]]
 name = "security-framework"
 version = "0.4.4"
@@ -2581,44 +2469,31 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
 
 [[package]]
 name = "serde"
-version = "1.0.111"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
+checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
 dependencies = [
  "serde_derive",
 ]
 
-[[package]]
-name = "serde-hjson"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153"
-dependencies = [
- "lazy_static 0.2.11",
- "linked-hash-map 0.3.0",
- "num-traits 0.1.43",
- "regex 1.3.9",
- "serde 0.8.23",
-]
-
 [[package]]
 name = "serde-hjson"
 version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
 dependencies = [
- "lazy_static 1.4.0",
+ "lazy_static",
  "linked-hash-map 0.3.0",
  "num-traits 0.1.43",
- "regex 1.3.9",
+ "regex",
  "serde 0.8.23",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.111"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
+checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2627,26 +2502,14 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67f7d2e9edc3523a9c8ec8cd6ec481b3a27810aafee3e625d311febd3e656b4c"
-dependencies = [
- "dtoa 0.2.2",
- "itoa 0.1.1",
- "num-traits 0.1.43",
- "serde 0.8.23",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.53"
+version = "1.0.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
+checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
 dependencies = [
  "indexmap",
- "itoa 0.4.5",
+ "itoa",
  "ryu",
- "serde 1.0.111",
+ "serde 1.0.114",
 ]
 
 [[package]]
@@ -2664,9 +2527,9 @@ version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
 dependencies = [
- "dtoa 0.4.5",
- "itoa 0.4.5",
- "serde 1.0.111",
+ "dtoa",
+ "itoa",
+ "serde 1.0.114",
  "url",
 ]
 
@@ -2718,7 +2581,7 @@ checksum = "2b25ecba7165254f0c97d6c22a64b1122a03634b18d20a34daf21e18f892e618"
 dependencies = [
  "chrono",
  "num-bigint",
- "num-traits 0.2.11",
+ "num-traits 0.2.12",
 ]
 
 [[package]]
@@ -2727,18 +2590,6 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 
-[[package]]
-name = "sluice"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fed13b7cb46f13a15db2c4740f087a848acc8b31af89f95844d40137451f89b1"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-util",
-]
-
 [[package]]
 name = "smallvec"
 version = "1.4.0"
@@ -2765,15 +2616,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
 [[package]]
 name = "static_assertions"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
-
-[[package]]
-name = "strsim"
-version = "0.5.2"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67f84c44fbb2f91db7fef94554e6b2ac05909c9c0b0bc23bb98d3a1aebfe7f7c"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 
 [[package]]
 name = "strsim"
@@ -2807,9 +2652,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "1.0.30"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2"
+checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2818,9 +2663,9 @@ dependencies = [
 
 [[package]]
 name = "synstructure"
-version = "0.12.3"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
+checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2862,50 +2707,31 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.19"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344"
+checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.19"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
+checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
-[[package]]
-name = "thread-id"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
-dependencies = [
- "kernel32-sys",
- "libc",
-]
-
-[[package]]
-name = "thread_local"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
-dependencies = [
- "thread-id",
-]
-
 [[package]]
 name = "thread_local"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
 dependencies = [
- "lazy_static 1.4.0",
+ "lazy_static",
 ]
 
 [[package]]
@@ -2927,6 +2753,12 @@ dependencies = [
  "winapi 0.3.8",
 ]
 
+[[package]]
+name = "tinyvec"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
+
 [[package]]
 name = "tokio"
 version = "0.2.21"
@@ -2937,9 +2769,9 @@ dependencies = [
  "fnv",
  "futures-core",
  "iovec",
- "lazy_static 1.4.0",
+ "lazy_static",
  "libc",
- "memchr 2.3.3",
+ "memchr",
  "mio",
  "mio-uds",
  "pin-project-lite",
@@ -2976,57 +2808,6 @@ dependencies = [
  "tokio",
 ]
 
-[[package]]
-name = "toml"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
-dependencies = [
- "serde 1.0.111",
-]
-
-[[package]]
-name = "tracing"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a41f40ed0e162c911ac6fcb53ecdc8134c46905fdbbae8c50add462a538b495f"
-dependencies = [
- "cfg-if",
- "log",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99bbad0de3fd923c9c3232ead88510b783e5a4d16a6154adffa3d53308de984c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715"
-dependencies = [
- "lazy_static 1.4.0",
-]
-
-[[package]]
-name = "tracing-futures"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
-dependencies = [
- "pin-project",
- "tracing",
-]
-
 [[package]]
 name = "trust-dns-proto"
 version = "0.18.0-alpha.2"
@@ -3038,7 +2819,7 @@ dependencies = [
  "failure",
  "futures",
  "idna",
- "lazy_static 1.4.0",
+ "lazy_static",
  "log",
  "rand 0.7.3",
  "smallvec",
@@ -3057,7 +2838,7 @@ dependencies = [
  "failure",
  "futures",
  "ipconfig",
- "lazy_static 1.4.0",
+ "lazy_static",
  "log",
  "lru-cache",
  "resolv-conf",
@@ -3072,7 +2853,7 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc"
 dependencies = [
- "memchr 2.3.3",
+ "memchr",
  "unchecked-index",
 ]
 
@@ -3131,11 +2912,11 @@ dependencies = [
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.12"
+version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
+checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
 dependencies = [
- "smallvec",
+ "tinyvec",
 ]
 
 [[package]]
@@ -3177,15 +2958,9 @@ dependencies = [
  "idna",
  "matches",
  "percent-encoding",
- "serde 1.0.111",
+ "serde 1.0.114",
 ]
 
-[[package]]
-name = "utf8-ranges"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
-
 [[package]]
 name = "uuid"
 version = "0.7.4"
@@ -3202,7 +2977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
 dependencies = [
  "rand 0.7.3",
- "serde 1.0.111",
+ "serde 1.0.114",
 ]
 
 [[package]]
@@ -3238,9 +3013,9 @@ dependencies = [
 
 [[package]]
 name = "vcpkg"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c"
+checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
 
 [[package]]
 name = "vec_map"
@@ -3283,7 +3058,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101"
 dependencies = [
  "bumpalo",
- "lazy_static 1.4.0",
+ "lazy_static",
  "log",
  "proc-macro2",
  "quote",
@@ -3330,11 +3105,30 @@ dependencies = [
  "wasm-bindgen",
 ]
 
+[[package]]
+name = "webpki"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739"
+dependencies = [
+ "webpki",
+]
+
 [[package]]
 name = "widestring"
-version = "0.4.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6"
+checksum = "a763e303c0e0f23b0da40888724762e802a8ffefbc22de4127ef42493c2ea68c"
 
 [[package]]
 name = "winapi"
@@ -3406,12 +3200,3 @@ dependencies = [
  "winapi 0.2.8",
  "winapi-build",
 ]
-
-[[package]]
-name = "yaml-rust"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
-dependencies = [
- "linked-hash-map 0.5.3",
-]
index 47be3239ebd3f12c317d573c0b0800fc0438ff41..52a9bae8e9e041a986a5faf250597931bbf1b198 100644 (file)
@@ -4,6 +4,9 @@ version = "0.0.1"
 authors = ["Dessalines <tyhou13@gmx.com>"]
 edition = "2018"
 
+[profile.release]
+lto = true
+
 [dependencies]
 diesel = { version = "1.4.4", features = ["postgres","chrono","r2d2","64-column-tables","serde_json"] }
 diesel_migrations = "1.4.0"
@@ -13,7 +16,7 @@ activitystreams-new = { git = "https://git.asonix.dog/asonix/activitystreams-ske
 activitystreams-ext = { git = "https://git.asonix.dog/asonix/activitystreams-ext" }
 bcrypt = "0.8.0"
 chrono = { version = "0.4.7", features = ["serde"] }
-serde_json = { version = "1.0.48", features = ["preserve_order"]}
+serde_json = { version = "1.0.52", features = ["preserve_order"]}
 failure = "0.1.8"
 serde = { version = "1.0.105", features = ["derive"] }
 actix = "0.9.0"
@@ -34,11 +37,10 @@ lettre_email = "0.9.4"
 sha2 = "0.8.1"
 rss = "1.9.0"
 htmlescape = "0.3.1"
-config = "0.10.1"
-hjson = "0.8.2"
 url = { version = "2.1.1", features = ["serde"] }
+config = {version = "0.10.1", default-features = false, features = ["hjson"] }
 percent-encoding = "2.1.0"
-isahc = "0.9.2"
+attohttpc = { version = "0.14.0", default-features = false, features = ["tls-rustls"] }
 comrak = "0.7"
 openssl = "0.10"
 http = "0.2.1"
index cb412fccade6b45174f3a72b81fac99cd1064cb3..3fc67eb348f766905ea14e0b701bed2e9009a50d 100644 (file)
@@ -1,3 +1,4 @@
+use super::*;
 use crate::{
   api::{APIError, Oper, Perform},
   apub::{
@@ -6,19 +7,8 @@ use crate::{
     ActorType,
     EndpointType,
   },
-  db::{
-    community::*,
-    community_view::*,
-    moderator::*,
-    site::*,
-    user::*,
-    user_view::*,
-    Bannable,
-    Crud,
-    Followable,
-    Joinable,
-    SortType,
-  },
+  db::{Bannable, Crud, Followable, Joinable, SortType},
+  is_valid_community_name,
   naive_from_unix,
   naive_now,
   slur_check,
@@ -259,6 +249,10 @@ impl Perform for Oper<CreateCommunity> {
       }
     }
 
+    if !is_valid_community_name(&data.name) {
+      return Err(APIError::err("invalid_community_name").into());
+    }
+
     let user_id = claims.id;
 
     let conn = pool.get()?;
@@ -353,6 +347,10 @@ impl Perform for Oper<EditCommunity> {
       Err(_e) => return Err(APIError::err("not_logged_in").into()),
     };
 
+    if !is_valid_community_name(&data.name) {
+      return Err(APIError::err("invalid_community_name").into());
+    }
+
     let user_id = claims.id;
 
     let conn = pool.get()?;
index 5120e9bc949fb5b9bc9cbe54a082f015802423ad..afd62aff8011a524cb45e0b748fb96c3af8c5c81 100644 (file)
@@ -1,4 +1,7 @@
-use crate::websocket::WebsocketInfo;
+use crate::{
+  db::{community::*, community_view::*, moderator::*, site::*, user::*, user_view::*},
+  websocket::WebsocketInfo,
+};
 use diesel::{
   r2d2::{ConnectionManager, Pool},
   PgConnection,
index 9bbde791977b8f4f16b2010b85a66616f311473b..420bef1f6211e648fe449b1f876c7a8e94d22c27 100644 (file)
@@ -17,7 +17,7 @@ use crate::{
     Saveable,
     SortType,
   },
-  fetch_iframely_and_pictshare_data,
+  fetch_iframely_and_pictrs_data,
   naive_now,
   slur_check,
   slurs_vec_to_str,
@@ -152,9 +152,9 @@ impl Perform for Oper<CreatePost> {
       return Err(APIError::err("site_ban").into());
     }
 
-    // Fetch Iframely and Pictshare cached image
-    let (iframely_title, iframely_description, iframely_html, pictshare_thumbnail) =
-      fetch_iframely_and_pictshare_data(data.url.to_owned());
+    // Fetch Iframely and pictrs cached image
+    let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
+      fetch_iframely_and_pictrs_data(data.url.to_owned());
 
     let post_form = PostForm {
       name: data.name.to_owned(),
@@ -171,7 +171,7 @@ impl Perform for Oper<CreatePost> {
       embed_title: iframely_title,
       embed_description: iframely_description,
       embed_html: iframely_html,
-      thumbnail_url: pictshare_thumbnail,
+      thumbnail_url: pictrs_thumbnail,
       ap_id: "changeme".into(),
       local: true,
       published: None,
@@ -507,9 +507,9 @@ impl Perform for Oper<EditPost> {
       return Err(APIError::err("site_ban").into());
     }
 
-    // Fetch Iframely and Pictshare cached image
-    let (iframely_title, iframely_description, iframely_html, pictshare_thumbnail) =
-      fetch_iframely_and_pictshare_data(data.url.to_owned());
+    // Fetch Iframely and Pictrs cached image
+    let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
+      fetch_iframely_and_pictrs_data(data.url.to_owned());
 
     let read_post = Post::read(&conn, data.edit_id)?;
 
@@ -528,7 +528,7 @@ impl Perform for Oper<EditPost> {
       embed_title: iframely_title,
       embed_description: iframely_description,
       embed_html: iframely_html,
-      thumbnail_url: pictshare_thumbnail,
+      thumbnail_url: pictrs_thumbnail,
       ap_id: read_post.ap_id,
       local: read_post.local,
       published: None,
index b5bb9d76c7dffff589c05e65186f0e3514d1c05a..3c4034c96979718254f147b51395cb3a44b1c937 100644 (file)
@@ -5,7 +5,6 @@ use crate::{
 use activitystreams::{context, object::properties::ObjectProperties, public, Activity, Base};
 use diesel::PgConnection;
 use failure::{Error, _core::fmt::Debug};
-use isahc::prelude::*;
 use log::debug;
 use serde::Serialize;
 use url::Url;
@@ -57,16 +56,18 @@ where
   for t in to {
     let to_url = Url::parse(&t)?;
     if !is_apub_id_valid(&to_url) {
-      debug!("Not sending activity to {} (invalid or blocklisted)", t);
+      debug!("Not sending activity to {} (invalid or blacklisted)", t);
       continue;
     }
-    let request = Request::post(t).header("Host", to_url.domain().unwrap());
-    let signature = sign(&request, actor)?;
+    let mut request = attohttpc::post(t).header("Host", to_url.domain().unwrap());
+    let signature = sign(&mut request, actor)?;
     let res = request
       .header("Signature", signature)
       .header("Content-Type", "application/json")
-      .body(json.to_owned())?
-      .send()?;
+      .text(json.to_owned())
+      .send()?
+      .text()?;
+
     debug!("Result for activity send: {:?}", res);
   }
   Ok(())
index 4156f0b3f84a567e67db063cfe81d002bfc9c1e2..7aa9489c3cf432b921755ccea522dd5345cc0306 100644 (file)
@@ -1,8 +1,8 @@
 use crate::apub::ActorType;
 use activitystreams::ext::Extension;
 use actix_web::HttpRequest;
+use attohttpc::RequestBuilder;
 use failure::Error;
-use http::request::Builder;
 use http_signature_normalization::Config;
 use log::debug;
 use openssl::{
@@ -35,28 +35,29 @@ pub fn generate_actor_keypair() -> Result<Keypair, Error> {
   })
 }
 
+// TODO is it possible to create this signature, with just the url and actor?
 /// Signs request headers with the given keypair.
-pub fn sign(request: &Builder, actor: &dyn ActorType) -> Result<String, Error> {
+pub fn sign(request: &mut RequestBuilder, actor: &dyn ActorType) -> Result<String, Error> {
   let signing_key_id = format!("{}#main-key", actor.actor_id());
 
   let headers = request
-    .headers_ref()
-    .unwrap()
+    .inspect()
+    .headers()
     .iter()
     .map(|h| -> Result<(String, String), Error> {
       Ok((h.0.as_str().to_owned(), h.1.to_str()?.to_owned()))
     })
     .collect::<Result<BTreeMap<String, String>, Error>>()?;
 
+  let mut path_and_query = request.inspect().url().path().to_owned();
+  if let Some(query) = request.inspect().url().query() {
+    path_and_query.push_str(query);
+  }
+
   let signature_header_value = HTTP_SIG_CONFIG
     .begin_sign(
-      request.method_ref().unwrap().as_str(),
-      request
-        .uri_ref()
-        .unwrap()
-        .path_and_query()
-        .unwrap()
-        .as_str(),
+      request.inspect().method().as_str(),
+      &path_and_query,
       headers,
     )?
     .sign(signing_key_id, |signing_string| {
index 7f7a3f971751821ee3e6de66ac2120ac92ebdbff..20bab4e2636648f84f493a30fa7b6201f32fa424 100644 (file)
@@ -2,7 +2,6 @@ use activitystreams::object::Note;
 use actix_web::Result;
 use diesel::{result::Error::NotFound, PgConnection};
 use failure::{Error, _core::fmt::Debug};
-use isahc::prelude::*;
 use log::debug;
 use serde::Deserialize;
 use std::time::Duration;
@@ -64,11 +63,11 @@ where
   }
   // TODO: this function should return a future
   let timeout = Duration::from_secs(60);
-  let text = Request::get(url.as_str())
+  let text: String = attohttpc::get(url.as_str())
     .header("Accept", APUB_JSON_CONTENT_TYPE)
     .connect_timeout(timeout)
     .timeout(timeout)
-    .body(())?
+    // .body(())
     .send()?
     .text()?;
   let res: Response = serde_json::from_str(&text)?;
index 6a2d6cffb385b7a12a427fff7a9170a5c50125aa..7d2aee65c9101afc113ed27487489ac5218a2910 100644 (file)
@@ -32,7 +32,6 @@ use actix_web::{body::Body, HttpResponse, Result};
 use chrono::NaiveDateTime;
 use diesel::PgConnection;
 use failure::Error;
-use isahc::prelude::*;
 use log::debug;
 use serde::Serialize;
 use url::Url;
@@ -253,7 +252,7 @@ pub fn fetch_webfinger_url(mention: &MentionData) -> Result<String, Error> {
     mention.domain
   );
   debug!("Fetching webfinger url: {}", &fetch_url);
-  let text = isahc::get(&fetch_url)?.text()?;
+  let text: String = attohttpc::get(&fetch_url).send()?.text()?;
   let res: WebFingerResponse = serde_json::from_str(&text)?;
   let link = res
     .links
index 32c374390e8bc37769cdbaa30ec2e0d5136393e4..2391449caf818155ebc3c500c6d15537030259d8 100644 (file)
@@ -39,7 +39,6 @@ pub mod websocket;
 use crate::settings::Settings;
 use actix_web::dev::ConnectionInfo;
 use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, Utc};
-use isahc::prelude::*;
 use itertools::Itertools;
 use lettre::{
   smtp::{
@@ -86,7 +85,8 @@ pub fn is_email_regex(test: &str) -> bool {
 }
 
 pub fn is_image_content_type(test: &str) -> Result<(), failure::Error> {
-  if isahc::get(test)?
+  if attohttpc::get(test)
+    .send()?
     .headers()
     .get("Content-Type")
     .ok_or_else(|| format_err!("No Content-Type header"))?
@@ -180,30 +180,40 @@ pub struct IframelyResponse {
 
 pub fn fetch_iframely(url: &str) -> Result<IframelyResponse, failure::Error> {
   let fetch_url = format!("http://iframely/oembed?url={}", url);
-  let text = isahc::get(&fetch_url)?.text()?;
+  let text: String = attohttpc::get(&fetch_url).send()?.text()?;
   let res: IframelyResponse = serde_json::from_str(&text)?;
   Ok(res)
 }
 
-#[derive(Deserialize, Debug)]
-pub struct PictshareResponse {
-  status: String,
-  url: String,
+#[derive(Deserialize, Debug, Clone)]
+pub struct PictrsResponse {
+  files: Vec<PictrsFile>,
+  msg: String,
+}
+
+#[derive(Deserialize, Debug, Clone)]
+pub struct PictrsFile {
+  file: String,
+  delete_token: String,
 }
 
-pub fn fetch_pictshare(image_url: &str) -> Result<PictshareResponse, failure::Error> {
+pub fn fetch_pictrs(image_url: &str) -> Result<PictrsResponse, failure::Error> {
   is_image_content_type(image_url)?;
 
   let fetch_url = format!(
-    "http://pictshare/api/geturl.php?url={}",
-    utf8_percent_encode(image_url, NON_ALPHANUMERIC)
+    "http://pictrs:8080/image/download?url={}",
+    utf8_percent_encode(image_url, NON_ALPHANUMERIC) // TODO this might not be needed
   );
-  let text = isahc::get(&fetch_url)?.text()?;
-  let res: PictshareResponse = serde_json::from_str(&text)?;
-  Ok(res)
+  let text = attohttpc::get(&fetch_url).send()?.text()?;
+  let res: PictrsResponse = serde_json::from_str(&text)?;
+  if res.msg == "ok" {
+    Ok(res)
+  } else {
+    Err(format_err!("{}", &res.msg))
+  }
 }
 
-fn fetch_iframely_and_pictshare_data(
+fn fetch_iframely_and_pictrs_data(
   url: Option<String>,
 ) -> (
   Option<String>,
@@ -223,20 +233,20 @@ fn fetch_iframely_and_pictshare_data(
           }
         };
 
-      // Fetch pictshare thumbnail
-      let pictshare_thumbnail = match iframely_thumbnail_url {
-        Some(iframely_thumbnail_url) => match fetch_pictshare(&iframely_thumbnail_url) {
-          Ok(res) => Some(res.url),
+      // Fetch pictrs thumbnail
+      let pictrs_thumbnail = match iframely_thumbnail_url {
+        Some(iframely_thumbnail_url) => match fetch_pictrs(&iframely_thumbnail_url) {
+          Ok(res) => Some(res.files[0].file.to_owned()),
           Err(e) => {
-            error!("pictshare err: {}", e);
+            error!("pictrs err: {}", e);
             None
           }
         },
         // Try to generate a small thumbnail if iframely is not supported
-        None => match fetch_pictshare(&url) {
-          Ok(res) => Some(res.url),
+        None => match fetch_pictrs(&url) {
+          Ok(res) => Some(res.files[0].file.to_owned()),
           Err(e) => {
-            error!("pictshare err: {}", e);
+            error!("pictrs err: {}", e);
             None
           }
         },
@@ -246,7 +256,7 @@ fn fetch_iframely_and_pictshare_data(
         iframely_title,
         iframely_description,
         iframely_html,
-        pictshare_thumbnail,
+        pictrs_thumbnail,
       )
     }
     None => (None, None, None, None),
@@ -298,11 +308,16 @@ pub fn is_valid_username(name: &str) -> bool {
   VALID_USERNAME_REGEX.is_match(name)
 }
 
+pub fn is_valid_community_name(name: &str) -> bool {
+  VALID_COMMUNITY_NAME_REGEX.is_match(name)
+}
+
 #[cfg(test)]
 mod tests {
   use crate::{
     is_email_regex,
     is_image_content_type,
+    is_valid_community_name,
     is_valid_username,
     remove_slurs,
     scrape_text_for_mentions,
@@ -344,6 +359,15 @@ mod tests {
     assert!(!is_valid_username(""));
   }
 
+  #[test]
+  fn test_valid_community_name() {
+    assert!(is_valid_community_name("example"));
+    assert!(is_valid_community_name("example_community"));
+    assert!(!is_valid_community_name("Example"));
+    assert!(!is_valid_community_name("Ex"));
+    assert!(!is_valid_community_name(""));
+  }
+
   #[test]
   fn test_slur_filter() {
     let test =
@@ -402,4 +426,5 @@ lazy_static! {
   // static ref WEBFINGER_USER_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)").unwrap();
   static ref WEBFINGER_USER_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._:-]+)").unwrap();
   static ref VALID_USERNAME_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9_]{3,20}$").unwrap();
+  static ref VALID_COMMUNITY_NAME_REGEX: Regex = Regex::new(r"^[a-z0-9_]{3,20}$").unwrap();
 }
index 354b86b40b43ce56b6378444a1a793f221501165..22de3471051ee00b3dfec7d747482ec1fa25e1c0 100644 (file)
@@ -1 +1 @@
-pub const VERSION: &str = "v0.6.71";
+pub const VERSION: &str = "v0.7.0";
diff --git a/ui/assets/css/themes/_variables.litely.scss b/ui/assets/css/themes/_variables.litely.scss
new file mode 100644 (file)
index 0000000..4ebd5de
--- /dev/null
@@ -0,0 +1,30 @@
+
+$white: #ffffff;
+$orange: #faa077;
+$cyan: #02bdc2;
+$green: #d4e9d7;
+$secondary: $green;
+$body-color: $gray-700;
+$link-color: theme-color("danger");;
+$primary: $orange;
+$red: #d8486a;
+$border-radius: 1.5rem;
+$border-radius-lg: 1.5rem;
+$border-radius-sm: 1rem;
+$font-family-sans-serif: Guardian-EgypTT,serif,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+$headings-color: $gray-700;
+$input-btn-focus-color: rgba($component-active-bg, .75);
+$form-feedback-valid-color: theme-color("info");
+$navbar-light-color: $gray-600;
+$black: #222222;
+$navbar-dark-toggler-border-color: rgba($black, .1);
+$navbar-light-active-color: $gray-900;
+$card-color: $gray-700;
+$card-cap-color: $gray-700;
+$info: darken($green, 25%);;
+$body-bg: #f2f0f0;
+$success: darken($green, 25%);;
+$danger: darken($primary, 25%);
+$navbar-light-hover-color: $gray-900;
+$card-bg: $gray-100;
+$border-color: $gray-700;
\ No newline at end of file
diff --git a/ui/assets/css/themes/litely.min.css b/ui/assets/css/themes/litely.min.css
new file mode 100644 (file)
index 0000000..949e710
--- /dev/null
@@ -0,0 +1 @@
+:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#d8486a;--orange:#fcd49d;--yellow:#ffc107;--green:#bad2be;--teal:#20c997;--cyan:#02bdc2;--white:#ffffff;--gray:#6c757d;--gray-dark:#343a40;--primary:#fcd49d;--secondary:#bad2be;--success:#38553d;--info:#38553d;--warning:#ffc107;--danger:#f89e21;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Droid Sans","Segoe UI","Helvetica",Arial,sans-serif;--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(34,34,34,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Droid Sans","Segoe UI",Helvetica,Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:left;background-color:#f2f0f0}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#f89e21;text-decoration:none;background-color:transparent}a:hover{color:#c77606;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2;color:#495057}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(34,34,34,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fffcef}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#f2f0f0;border:1px solid #dee2e6;border-radius:1.5rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:1rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#495057}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #495057}.table thead th{vertical-align:bottom;border-bottom:2px solid #495057}.table tbody+tbody{border-top:2px solid #495057}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #495057}.table-bordered td,.table-bordered th{border:1px solid #495057}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(34,34,34,.05)}.table-hover tbody tr:hover{color:#495057;background-color:rgba(34,34,34,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#fef3e4}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#fde9cc}.table-hover .table-primary:hover{background-color:#fde8cb}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#fde8cb}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#ecf2ed}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#dbe8dd}.table-hover .table-secondary:hover{background-color:#dde8df}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#dde8df}.table-success,.table-success>td,.table-success>th{background-color:#c7cfc9}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#97a79a}.table-hover .table-success:hover{background-color:#b9c3bc}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b9c3bc}.table-info,.table-info>td,.table-info>th{background-color:#c7cfc9}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#97a79a}.table-hover .table-info:hover{background-color:#b9c3bc}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#b9c3bc}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#fde4c1}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#fbcc8c}.table-hover .table-danger:hover{background-color:#fcd9a8}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#fcd9a8}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(34,34,34,.075)}.table-hover .table-active:hover{background-color:rgba(21,21,21,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(21,21,21,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#495057}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:1.5rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#fff;outline:0;box-shadow:0 0 0 .2rem rgba(252,212,157,.75)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#495057;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:1rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:1.5rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#38553d}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(56,85,61,.9);border-radius:1.5rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#38553d;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2338553d' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#38553d;box-shadow:0 0 0 .2rem rgba(56,85,61,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#38553d;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2338553d' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#38553d;box-shadow:0 0 0 .2rem rgba(56,85,61,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#38553d}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#38553d}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#38553d}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#4c7453;background-color:#4c7453}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(56,85,61,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#38553d}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#38553d}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#38553d;box-shadow:0 0 0 .2rem rgba(56,85,61,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#f89e21}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#212529;background-color:rgba(248,158,33,.9);border-radius:1.5rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#f89e21;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23f89e21' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23f89e21' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#f89e21;box-shadow:0 0 0 .2rem rgba(248,158,33,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#f89e21;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23f89e21' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23f89e21' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#f89e21;box-shadow:0 0 0 .2rem rgba(248,158,33,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#f89e21}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#f89e21}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#f89e21}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#fab353;background-color:#fab353}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(248,158,33,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#f89e21}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#f89e21}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#f89e21;box-shadow:0 0 0 .2rem rgba(248,158,33,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#495057;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:1.5rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#495057;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(252,212,157,.75)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#212529;background-color:#fcd49d;border-color:#fcd49d}.btn-primary:hover{color:#212529;background-color:#fbc478;border-color:#fabe6c}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(219,186,140,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#212529;background-color:#fcd49d;border-color:#fcd49d}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#212529;background-color:#fabe6c;border-color:#fab95f}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(219,186,140,.5)}.btn-secondary{color:#212529;background-color:#bad2be;border-color:#bad2be}.btn-secondary:hover{color:#212529;background-color:#a3c3a8;border-color:#9bbea1}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(163,184,168,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#212529;background-color:#bad2be;border-color:#bad2be}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#212529;background-color:#9bbea1;border-color:#93b99a}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(163,184,168,.5)}.btn-success{color:#fff;background-color:#38553d;border-color:#38553d}.btn-success:hover{color:#fff;background-color:#293e2c;border-color:#243627}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(86,111,90,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#38553d;border-color:#38553d}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#243627;border-color:#1e2f21}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(86,111,90,.5)}.btn-info{color:#fff;background-color:#38553d;border-color:#38553d}.btn-info:hover{color:#fff;background-color:#293e2c;border-color:#243627}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(86,111,90,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#38553d;border-color:#38553d}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#243627;border-color:#1e2f21}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(86,111,90,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#212529;background-color:#f89e21;border-color:#f89e21}.btn-danger:hover{color:#212529;background-color:#ec8c07;border-color:#e08407}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(216,140,34,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#212529;background-color:#f89e21;border-color:#f89e21}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#e08407;border-color:#d37d06}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,140,34,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#fcd49d;border-color:#fcd49d}.btn-outline-primary:hover{color:#212529;background-color:#fcd49d;border-color:#fcd49d}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(252,212,157,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#fcd49d;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#212529;background-color:#fcd49d;border-color:#fcd49d}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(252,212,157,.5)}.btn-outline-secondary{color:#bad2be;border-color:#bad2be}.btn-outline-secondary:hover{color:#212529;background-color:#bad2be;border-color:#bad2be}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(186,210,190,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#bad2be;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#212529;background-color:#bad2be;border-color:#bad2be}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(186,210,190,.5)}.btn-outline-success{color:#38553d;border-color:#38553d}.btn-outline-success:hover{color:#fff;background-color:#38553d;border-color:#38553d}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(56,85,61,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#38553d;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#38553d;border-color:#38553d}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(56,85,61,.5)}.btn-outline-info{color:#38553d;border-color:#38553d}.btn-outline-info:hover{color:#fff;background-color:#38553d;border-color:#38553d}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(56,85,61,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#38553d;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#38553d;border-color:#38553d}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(56,85,61,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#f89e21;border-color:#f89e21}.btn-outline-danger:hover{color:#212529;background-color:#f89e21;border-color:#f89e21}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(248,158,33,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#f89e21;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#212529;background-color:#f89e21;border-color:#f89e21}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,158,33,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#f89e21;text-decoration:none}.btn-link:hover{color:#c77606;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:1.5rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:1rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#495057;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(34,34,34,.15);border-radius:1.5rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#fcd49d}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:1.5rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:1.5rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:1rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#fcd49d;background-color:#fcd49d}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(252,212,157,.75)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#fff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#fff;border-color:#fff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:1.5rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#fcd49d;background-color:#fcd49d}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23ffffff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(252,212,157,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(252,212,157,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23ffffff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(252,212,157,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(252,212,157,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:1.5rem;appearance:none}.custom-select:focus{border-color:#fff;outline:0;box-shadow:0 0 0 .2rem rgba(252,212,157,.75)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#fff;box-shadow:0 0 0 .2rem rgba(252,212,157,.75)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:1.5rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 1.5rem 1.5rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #f2f0f0,0 0 0 .2rem rgba(252,212,157,.75)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #f2f0f0,0 0 0 .2rem rgba(252,212,157,.75)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #f2f0f0,0 0 0 .2rem rgba(252,212,157,.75)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#fcd49d;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#fff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#fcd49d;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#fff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#fcd49d;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#fff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#f2f0f0;border-color:#dee2e6 #dee2e6 #f2f0f0}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:1.5rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#fcd49d}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:1.5rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:#212529}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:#212529}.navbar-light .navbar-nav .nav-link{color:#6c757d}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:#212529}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(34,34,34,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:#212529}.navbar-light .navbar-toggler{color:#6c757d;border-color:rgba(34,34,34,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='%236c757d' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:#6c757d}.navbar-light .navbar-text a{color:#212529}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:#212529}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(34,34,34,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#f8f9fa;background-clip:border-box;border:1px solid rgba(34,34,34,.125);border-radius:1.5rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.card-body{flex:1 1 auto;padding:1.25rem;color:#495057}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;color:#495057;background-color:rgba(34,34,34,.03);border-bottom:1px solid rgba(34,34,34,.125)}.card-header:first-child{border-radius:calc(1.5rem - 1px) calc(1.5rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(34,34,34,.03);border-top:1px solid rgba(34,34,34,.125)}.card-footer:last-child{border-radius:0 0 calc(1.5rem - 1px) calc(1.5rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(1.5rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(1.5rem - 1px);border-top-right-radius:calc(1.5rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(1.5rem - 1px);border-bottom-left-radius:calc(1.5rem - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:flex;flex:1 0 0%;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:1.5rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:1.5rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#f89e21;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#c77606;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(252,212,157,.75)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.page-item:last-child .page-link{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#fcd49d;border-color:#fcd49d}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1.5rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#212529;background-color:#fcd49d}a.badge-primary:focus,a.badge-primary:hover{color:#212529;background-color:#fabe6c}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(252,212,157,.5)}.badge-secondary{color:#212529;background-color:#bad2be}a.badge-secondary:focus,a.badge-secondary:hover{color:#212529;background-color:#9bbea1}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(186,210,190,.5)}.badge-success{color:#fff;background-color:#38553d}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#243627}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(56,85,61,.5)}.badge-info{color:#fff;background-color:#38553d}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#243627}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(56,85,61,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#212529;background-color:#f89e21}a.badge-danger:focus,a.badge-danger:hover{color:#212529;background-color:#e08407}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,158,33,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:1.5rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:1.5rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#937f62;background-color:#fef6eb;border-color:#fef3e4}.alert-primary hr{border-top-color:#fde8cb}.alert-primary .alert-link{color:#74654e}.alert-secondary{color:#717e73;background-color:#f1f6f2;border-color:#ecf2ed}.alert-secondary hr{border-top-color:#dde8df}.alert-secondary .alert-link{color:#59635a}.alert-success{color:#2d3d30;background-color:#d7ddd8;border-color:#c7cfc9}.alert-success hr{border-top-color:#b9c3bc}.alert-success .alert-link{color:#172019}.alert-info{color:#2d3d30;background-color:#d7ddd8;border-color:#c7cfc9}.alert-info hr{border-top-color:#b9c3bc}.alert-info .alert-link{color:#172019}.alert-warning{color:#957514;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#68520e}.alert-danger{color:#916222;background-color:#feecd3;border-color:#fde4c1}.alert-danger hr{border-top-color:#fcd9a8}.alert-danger .alert-link{color:#684618}.alert-light{color:#919292;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#777979}.alert-dark{color:#2b2e32;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#131517}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:1.5rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#fcd49d;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#495057;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(34,34,34,.125)}.list-group-item:first-child{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#fcd49d;border-color:#fcd49d}.list-group-horizontal{flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#937f62;background-color:#fef3e4}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#937f62;background-color:#fde8cb}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#937f62;border-color:#937f62}.list-group-item-secondary{color:#717e73;background-color:#ecf2ed}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#717e73;background-color:#dde8df}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#717e73;border-color:#717e73}.list-group-item-success{color:#2d3d30;background-color:#c7cfc9}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#2d3d30;background-color:#b9c3bc}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#2d3d30;border-color:#2d3d30}.list-group-item-info{color:#2d3d30;background-color:#c7cfc9}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#2d3d30;background-color:#b9c3bc}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2d3d30;border-color:#2d3d30}.list-group-item-warning{color:#957514;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#957514;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#957514;border-color:#957514}.list-group-item-danger{color:#916222;background-color:#fde4c1}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#916222;background-color:#fcd9a8}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#916222;border-color:#916222}.list-group-item-light{color:#919292;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#919292;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#919292;border-color:#919292}.list-group-item-dark{color:#2b2e32;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#2b2e32;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#2b2e32;border-color:#2b2e32}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#222;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#222;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(34,34,34,.1);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(34,34,34,.2);border-radius:1.5rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#222}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #495057;border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;align-items:center;justify-content:flex-end;padding:1rem;border-top:1px solid #495057;border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Droid Sans","Segoe UI",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#222}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#222}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#222}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#222}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#222;border-radius:1.5rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Droid Sans","Segoe UI",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(34,34,34,.2);border-radius:1.5rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 1.5rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(34,34,34,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:1.5rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(34,34,34,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(34,34,34,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:1.5rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(34,34,34,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:#495057;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(1.5rem - 1px);border-top-right-radius:calc(1.5rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#495057}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23ffffff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23ffffff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#fcd49d!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#fabe6c!important}.bg-secondary{background-color:#bad2be!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#9bbea1!important}.bg-success{background-color:#38553d!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#243627!important}.bg-info{background-color:#38553d!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#243627!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#f89e21!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#e08407!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #495057!important}.border-top{border-top:1px solid #495057!important}.border-right{border-right:1px solid #495057!important}.border-bottom{border-bottom:1px solid #495057!important}.border-left{border-left:1px solid #495057!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#fcd49d!important}.border-secondary{border-color:#bad2be!important}.border-success{border-color:#38553d!important}.border-info{border-color:#38553d!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#f89e21!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:1rem!important}.rounded{border-radius:1.5rem!important}.rounded-top{border-top-left-radius:1.5rem!important;border-top-right-radius:1.5rem!important}.rounded-right{border-top-right-radius:1.5rem!important;border-bottom-right-radius:1.5rem!important}.rounded-bottom{border-bottom-right-radius:1.5rem!important;border-bottom-left-radius:1.5rem!important}.rounded-left{border-top-left-radius:1.5rem!important;border-bottom-left-radius:1.5rem!important}.rounded-lg{border-radius:1.5rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(34,34,34,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(34,34,34,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(34,34,34,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#fcd49d!important}a.text-primary:focus,a.text-primary:hover{color:#fab353!important}.text-secondary{color:#bad2be!important}a.text-secondary:focus,a.text-secondary:hover{color:#8cb492!important}.text-success{color:#38553d!important}a.text-success:focus,a.text-success:hover{color:#19271c!important}.text-info{color:#38553d!important}a.text-info:focus,a.text-info:hover{color:#19271c!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#f89e21!important}a.text-danger:focus,a.text-danger:hover{color:#c77606!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#495057!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(34,34,34,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #222}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#495057}.table .thead-dark th{color:inherit;border-color:#495057}}
\ No newline at end of file
index b3c1a9a164fe093191dc8aa17ee4f401c19b5be5..0fb7824ec9c7e8b14df49366c6055d5a785a2c58 100644 (file)
@@ -18,6 +18,7 @@ import {
   setupTribute,
   wsJsonToRes,
   emojiPicker,
+  pictrsDeleteToast,
 } from '../utils';
 import { WebSocketService, UserService } from '../services';
 import autosize from 'autosize';
@@ -60,7 +61,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
     buttonTitle: !this.props.node
       ? capitalizeFirstLetter(i18n.t('post'))
       : this.props.edit
-      ? capitalizeFirstLetter(i18n.t('edit'))
+      ? capitalizeFirstLetter(i18n.t('save'))
       : capitalizeFirstLetter(i18n.t('reply')),
     previewMode: false,
     loading: false,
@@ -137,7 +138,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
               />
               {this.state.previewMode && (
                 <div
-                  className="md-div"
+                  className="card card-body md-div"
                   dangerouslySetInnerHTML={mdToHtml(
                     this.state.commentForm.content
                   )}
@@ -150,7 +151,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
               <button
                 type="submit"
                 class="btn btn-sm btn-secondary mr-2"
-                disabled={this.props.disabled}
+                disabled={this.props.disabled || this.state.loading}
               >
                 {this.state.loading ? (
                   <svg class="icon icon-spinner spin">
@@ -244,18 +245,32 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
     });
   }
 
-  handleFinished() {
-    this.state.previewMode = false;
-    this.state.loading = false;
-    this.state.commentForm.content = '';
-    this.setState(this.state);
-    let form: any = document.getElementById(this.formId);
-    form.reset();
-    if (this.props.node) {
-      this.props.onReplyCancel();
+  handleFinished(data: CommentResponse) {
+    let isReply =
+      this.props.node !== undefined && data.comment.parent_id !== null;
+    let xor =
+      +!(data.comment.parent_id !== null) ^ +(this.props.node !== undefined);
+
+    if (
+      (data.comment.creator_id == UserService.Instance.user.id &&
+        // If its a reply, make sure parent child match
+        isReply &&
+        data.comment.parent_id == this.props.node.comment.id) ||
+      // Otherwise, check the XOR of the two
+      (!isReply && xor)
+    ) {
+      this.state.previewMode = false;
+      this.state.loading = false;
+      this.state.commentForm.content = '';
+      this.setState(this.state);
+      let form: any = document.getElementById(this.formId);
+      form.reset();
+      if (this.props.node) {
+        this.props.onReplyCancel();
+      }
+      autosize.update(form);
+      this.setState(this.state);
     }
-    autosize.update(document.querySelector('textarea'));
-    this.setState(this.state);
   }
 
   handleCommentSubmit(i: CommentForm, event: any) {
@@ -305,9 +320,9 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
       file = event;
     }
 
-    const imageUploadUrl = `/pictshare/api/upload.php`;
+    const imageUploadUrl = `/pictrs/image`;
     const formData = new FormData();
-    formData.append('file', file);
+    formData.append('images[]', file);
 
     i.state.imageLoading = true;
     i.setState(i.state);
@@ -318,16 +333,31 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
     })
       .then(res => res.json())
       .then(res => {
-        let url = `${window.location.origin}/pictshare/${res.url}`;
-        let imageMarkdown =
-          res.filetype == 'mp4' ? `[vid](${url}/raw)` : `![](${url})`;
-        let content = i.state.commentForm.content;
-        content = content ? `${content}\n${imageMarkdown}` : imageMarkdown;
-        i.state.commentForm.content = content;
-        i.state.imageLoading = false;
-        i.setState(i.state);
-        let textarea: any = document.getElementById(i.id);
-        autosize.update(textarea);
+        console.log('pictrs upload:');
+        console.log(res);
+        if (res.msg == 'ok') {
+          let hash = res.files[0].file;
+          let url = `${window.location.origin}/pictrs/image/${hash}`;
+          let deleteToken = res.files[0].delete_token;
+          let deleteUrl = `${window.location.origin}/pictrs/image/delete/${deleteToken}/${hash}`;
+          let imageMarkdown = `![](${url})`;
+          let content = i.state.commentForm.content;
+          content = content ? `${content}\n${imageMarkdown}` : imageMarkdown;
+          i.state.commentForm.content = content;
+          i.state.imageLoading = false;
+          i.setState(i.state);
+          let textarea: any = document.getElementById(i.id);
+          autosize.update(textarea);
+          pictrsDeleteToast(
+            i18n.t('click_to_delete_picture'),
+            i18n.t('picture_deleted'),
+            deleteUrl
+          );
+        } else {
+          i.state.imageLoading = false;
+          i.setState(i.state);
+          toast(JSON.stringify(res), 'danger');
+        }
       })
       .catch(error => {
         i.state.imageLoading = false;
@@ -343,14 +373,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
     if (UserService.Instance.user) {
       if (res.op == UserOperation.CreateComment) {
         let data = res.data as CommentResponse;
-        if (data.comment.creator_id == UserService.Instance.user.id) {
-          this.handleFinished();
-        }
+        this.handleFinished(data);
       } else if (res.op == UserOperation.EditComment) {
         let data = res.data as CommentResponse;
-        if (data.comment.creator_id == UserService.Instance.user.id) {
-          this.handleFinished();
-        }
+        this.handleFinished(data);
       }
     }
   }
index ca828a45838afc1324596c31a6008cb44d757ae4..155efe8e0f66ac88df350a65328991195c35d372 100644 (file)
@@ -132,7 +132,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
       >
         <div
           id={`comment-${node.comment.id}`}
-          className={`details comment-node border-top border-light ${
+          className={`details comment-node border-top border-light py-2 ${
             this.isCommentNew ? 'mark' : ''
           }`}
           style={
@@ -148,7 +148,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
               'ml-2'
             }`}
           >
-            <div class="d-flex flex-wrap align-items-center mb-1 mt-1 text-muted small">
+            <div class="d-flex flex-wrap align-items-center text-muted small">
               <span class="mr-2">
                 <UserListing
                   user={{
@@ -297,25 +297,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                           )}
                         </button>
                       )}
-                      <button
-                        class="btn btn-link btn-animate text-muted"
-                        onClick={linkEvent(this, this.handleSaveCommentClick)}
-                        data-tippy-content={
-                          node.comment.saved ? i18n.t('unsave') : i18n.t('save')
-                        }
-                      >
-                        {this.state.saveLoading ? (
-                          this.loadingIcon
-                        ) : (
-                          <svg
-                            class={`icon icon-inline ${
-                              node.comment.saved && 'text-warning'
-                            }`}
-                          >
-                            <use xlinkHref="#icon-star"></use>
-                          </svg>
-                        )}
-                      </button>
                       <button
                         class="btn btn-link btn-animate text-muted"
                         onClick={linkEvent(this, this.handleReplyClick)}
@@ -351,6 +332,30 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                             </button>
                           )}
                           {!this.props.showContext && this.linkBtn}
+                          <button
+                            class="btn btn-link btn-animate text-muted"
+                            onClick={linkEvent(
+                              this,
+                              this.handleSaveCommentClick
+                            )}
+                            data-tippy-content={
+                              node.comment.saved
+                                ? i18n.t('unsave')
+                                : i18n.t('save')
+                            }
+                          >
+                            {this.state.saveLoading ? (
+                              this.loadingIcon
+                            ) : (
+                              <svg
+                                class={`icon icon-inline ${
+                                  node.comment.saved && 'text-warning'
+                                }`}
+                              >
+                                <use xlinkHref="#icon-star"></use>
+                              </svg>
+                            )}
+                          </button>
                           <button
                             className="btn btn-link btn-animate text-muted"
                             onClick={linkEvent(this, this.handleViewSource)}
index eedc2003808533a8af6727a8795a2fa3ff6b0226..90e127383aee6c59deaaef1985db1413d7a5fa3c 100644 (file)
@@ -207,7 +207,11 @@ export class CommunityForm extends Component<
           )}
           <div class="form-group row">
             <div class="col-12">
-              <button type="submit" class="btn btn-secondary mr-2">
+              <button
+                type="submit"
+                class="btn btn-secondary mr-2"
+                disabled={this.state.loading}
+              >
                 {this.state.loading ? (
                   <svg class="icon icon-spinner spin">
                     <use xlinkHref="#icon-spinner"></use>
index 4fa1498ac4eede6f685cbad554fbf295120c1cd6..edbacd518c5ffff473d86a30ae470f48f0eda9dd 100644 (file)
@@ -123,7 +123,10 @@ export class Inbox extends Component<any, InboxState> {
               this.state.unreadOrAll == UnreadOrAll.Unread && (
                 <ul class="list-inline mb-1 text-muted small font-weight-bold">
                   <li className="list-inline-item">
-                    <span class="pointer" onClick={this.markAllAsRead}>
+                    <span
+                      class="pointer"
+                      onClick={linkEvent(this, this.markAllAsRead)}
+                    >
                       {i18n.t('mark_all_as_read')}
                     </span>
                   </li>
@@ -392,8 +395,14 @@ export class Inbox extends Component<any, InboxState> {
     this.refetch();
   }
 
-  markAllAsRead() {
+  markAllAsRead(i: Inbox) {
     WebSocketService.Instance.markAllAsRead();
+    i.state.replies = [];
+    i.state.mentions = [];
+    i.state.messages = [];
+    i.sendUnreadCount();
+    window.scrollTo(0, 0);
+    i.setState(i.state);
   }
 
   parseMessage(msg: WebSocketJsonResponse) {
@@ -447,12 +456,7 @@ export class Inbox extends Component<any, InboxState> {
       this.setState(this.state);
       setupTippy();
     } else if (res.op == UserOperation.MarkAllAsRead) {
-      this.state.replies = [];
-      this.state.mentions = [];
-      this.state.messages = [];
-      this.sendUnreadCount();
-      window.scrollTo(0, 0);
-      this.setState(this.state);
+      // Moved to be instant
     } else if (res.op == UserOperation.EditComment) {
       let data = res.data as CommentResponse;
       editCommentRes(data, this.state.replies);
index 84014f68c577689f06ae2d725fe0ff8ee5a5d2ae..ce04d0d4f98ab4a664dd08264ed93ea80a91d9fb 100644 (file)
@@ -111,6 +111,7 @@ export class Login extends Component<any, State> {
                 required
               />
               <button
+                type="button"
                 disabled={!validEmail(this.state.loginForm.username_or_email)}
                 onClick={linkEvent(this, this.handlePasswordReset)}
                 className="btn p-0 btn-link d-inline-block float-right text-muted small font-weight-bold"
index f1936be1812fcd01af3898889821d8192540b14d..4cb74391b7361bdc6e4edba8a04265a1db67b4de 100644 (file)
@@ -22,7 +22,7 @@ import {
 } from '../interfaces';
 import {
   wsJsonToRes,
-  pictshareAvatarThumbnail,
+  pictrsAvatarThumbnail,
   showAvatars,
   fetchLimit,
   isCommentType,
@@ -218,7 +218,7 @@ export class Navbar extends Component<any, NavbarState> {
                     <span>
                       {UserService.Instance.user.avatar && showAvatars() && (
                         <img
-                          src={pictshareAvatarThumbnail(
+                          src={pictrsAvatarThumbnail(
                             UserService.Instance.user.avatar
                           )}
                           height="32"
index 22224c344af941f312ed08fab90864b57e0dbe93..9f5aa363e63726d0566c00acd6407033b70be185 100644 (file)
@@ -36,6 +36,7 @@ import {
   setupTippy,
   emojiPicker,
   hostname,
+  pictrsDeleteToast,
 } from '../utils';
 import autosize from 'autosize';
 import Tribute from 'tributejs/src/Tribute.js';
@@ -284,7 +285,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               />
               {this.state.previewMode && (
                 <div
-                  className="md-div"
+                  className="card card-body md-div"
                   dangerouslySetInnerHTML={mdToHtml(this.state.postForm.body)}
                 />
               )}
@@ -364,7 +365,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
           <div class="form-group row">
             <div class="col-sm-10">
               <button
-                disabled={!this.state.postForm.community_id}
+                disabled={
+                  !this.state.postForm.community_id || this.state.loading
+                }
                 type="submit"
                 class="btn btn-secondary mr-2"
               >
@@ -410,6 +413,12 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
 
   handlePostSubmit(i: PostForm, event: any) {
     event.preventDefault();
+
+    // Coerce empty url string to undefined
+    if (i.state.postForm.url && i.state.postForm.url === '') {
+      i.state.postForm.url = undefined;
+    }
+
     if (i.props.post) {
       WebSocketService.Instance.editPost(i.state.postForm);
     } else {
@@ -523,9 +532,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
       file = event;
     }
 
-    const imageUploadUrl = `/pictshare/api/upload.php`;
+    const imageUploadUrl = `/pictrs/image`;
     const formData = new FormData();
-    formData.append('file', file);
+    formData.append('images[]', file);
 
     i.state.imageLoading = true;
     i.setState(i.state);
@@ -536,13 +545,26 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     })
       .then(res => res.json())
       .then(res => {
-        let url = `${window.location.origin}/pictshare/${encodeURI(res.url)}`;
-        if (res.filetype == 'mp4') {
-          url += '/raw';
+        console.log('pictrs upload:');
+        console.log(res);
+        if (res.msg == 'ok') {
+          let hash = res.files[0].file;
+          let url = `${window.location.origin}/pictrs/image/${hash}`;
+          let deleteToken = res.files[0].delete_token;
+          let deleteUrl = `${window.location.origin}/pictrs/image/delete/${deleteToken}/${hash}`;
+          i.state.postForm.url = url;
+          i.state.imageLoading = false;
+          i.setState(i.state);
+          pictrsDeleteToast(
+            i18n.t('click_to_delete_picture'),
+            i18n.t('picture_deleted'),
+            deleteUrl
+          );
+        } else {
+          i.state.imageLoading = false;
+          i.setState(i.state);
+          toast(JSON.stringify(res), 'danger');
         }
-        i.state.postForm.url = url;
-        i.state.imageLoading = false;
-        i.setState(i.state);
       })
       .catch(error => {
         i.state.imageLoading = false;
index def42e3c3688d2e0a22ef0431bf0a32db439d463..b4cc4f928298e82549fc8f395c66fdea751aa6d3 100644 (file)
@@ -29,7 +29,7 @@ import {
   isImage,
   isVideo,
   getUnixTime,
-  pictshareImage,
+  pictrsImage,
   setupTippy,
   hostname,
   previewLines,
@@ -163,15 +163,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   getImage(thumbnail: boolean = false) {
     let post = this.props.post;
     if (isImage(post.url)) {
-      if (post.url.includes('pictshare')) {
-        return pictshareImage(post.url, thumbnail);
+      if (post.url.includes('pictrs')) {
+        return pictrsImage(post.url, thumbnail);
       } else if (post.thumbnail_url) {
-        return pictshareImage(post.thumbnail_url, thumbnail);
+        return pictrsImage(post.thumbnail_url, thumbnail);
       } else {
         return post.url;
       }
     } else if (post.thumbnail_url) {
-      return pictshareImage(post.thumbnail_url, thumbnail);
+      return pictrsImage(post.thumbnail_url, thumbnail);
     }
   }
 
index 64e22d61aed7d44038e9827a66a5bf156afb30c0..8cb7590e615c4ebf377964a9f1736e1cd78df03d 100644 (file)
@@ -157,7 +157,7 @@ export class PrivateMessageForm extends Component<
               />
               {this.state.previewMode && (
                 <div
-                  className="md-div"
+                  className="card card-body md-div"
                   dangerouslySetInnerHTML={mdToHtml(
                     this.state.privateMessageForm.content
                   )}
@@ -186,7 +186,11 @@ export class PrivateMessageForm extends Component<
           )}
           <div class="form-group row">
             <div class="offset-sm-2 col-sm-10">
-              <button type="submit" class="btn btn-secondary mr-2">
+              <button
+                type="submit"
+                class="btn btn-secondary mr-2"
+                disabled={this.state.loading}
+              >
                 {this.state.loading ? (
                   <svg class="icon icon-spinner spin">
                     <use xlinkHref="#icon-spinner"></use>
index 3acd6e19f06c1c40d2171866ee1f63d4830e38d4..71924f0cbabb882c84a24b2718fe97afa62aec02 100644 (file)
@@ -5,12 +5,7 @@ import {
   EditPrivateMessageForm,
 } from '../interfaces';
 import { WebSocketService, UserService } from '../services';
-import {
-  mdToHtml,
-  pictshareAvatarThumbnail,
-  showAvatars,
-  toast,
-} from '../utils';
+import { mdToHtml, pictrsAvatarThumbnail, showAvatars, toast } from '../utils';
 import { MomentTime } from './moment-time';
 import { PrivateMessageForm } from './private-message-form';
 import { i18n } from '../i18next';
@@ -78,7 +73,7 @@ export class PrivateMessage extends Component<
                     <img
                       height="32"
                       width="32"
-                      src={pictshareAvatarThumbnail(
+                      src={pictrsAvatarThumbnail(
                         this.mine
                           ? message.recipient_avatar
                           : message.creator_avatar
index f0c80585e5dea23c8c791b1108fff636043ba12a..a51286c81cd54972fda3a0bd12b156ad0060a020 100644 (file)
@@ -78,7 +78,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
         <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
           <h5>{`${
             this.props.site
-              ? capitalizeFirstLetter(i18n.t('edit'))
+              ? capitalizeFirstLetter(i18n.t('save'))
               : capitalizeFirstLetter(i18n.t('name'))
           } ${i18n.t('your_site')}`}</h5>
           <div class="form-group row">
@@ -175,7 +175,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
           </div>
           <div class="form-group row">
             <div class="col-12">
-              <button type="submit" class="btn btn-secondary mr-2">
+              <button
+                type="submit"
+                class="btn btn-secondary mr-2"
+                disabled={this.state.loading}
+              >
                 {this.state.loading ? (
                   <svg class="icon icon-spinner spin">
                     <use xlinkHref="#icon-spinner"></use>
index 903aa1a7550638da52250f2399eedc963afbb4cf..0e150b9420d3468d61cadd01ea229ab2dca01c54 100644 (file)
@@ -1,7 +1,7 @@
 import { Component } from 'inferno';
 import { Link } from 'inferno-router';
 import { UserView } from '../interfaces';
-import { pictshareAvatarThumbnail, showAvatars, hostname } from '../utils';
+import { pictrsAvatarThumbnail, showAvatars, hostname } from '../utils';
 
 interface UserOther {
   name: string;
@@ -40,7 +40,7 @@ export class UserListing extends Component<UserListingProps, any> {
           <img
             height="32"
             width="32"
-            src={pictshareAvatarThumbnail(user.avatar)}
+            src={pictrsAvatarThumbnail(user.avatar)}
             class="rounded-circle mr-2"
           />
         )}
index 78807153f94ab71328febd98307ee8ff38eadbf8..f635a1cd0b1d8eb48582b62f9c06fdb7234a0bb7 100644 (file)
@@ -927,7 +927,7 @@ export class User extends Component<any, UserState> {
 
   handleUserSettingsThemeChange(i: User, event: any) {
     i.state.userSettingsForm.theme = event.target.value;
-    setTheme(event.target.value);
+    setTheme(event.target.value, true);
     i.setState(i.state);
   }
 
@@ -993,9 +993,9 @@ export class User extends Component<any, UserState> {
   handleImageUpload(i: User, event: any) {
     event.preventDefault();
     let file = event.target.files[0];
-    const imageUploadUrl = `/pictshare/api/upload.php`;
+    const imageUploadUrl = `/pictrs/image`;
     const formData = new FormData();
-    formData.append('file', file);
+    formData.append('images[]', file);
 
     i.state.avatarLoading = true;
     i.setState(i.state);
@@ -1006,14 +1006,19 @@ export class User extends Component<any, UserState> {
     })
       .then(res => res.json())
       .then(res => {
-        let url = `${window.location.origin}/pictshare/${res.url}`;
-        if (res.filetype == 'mp4') {
-          url += '/raw';
+        console.log('pictrs upload:');
+        console.log(res);
+        if (res.msg == 'ok') {
+          let hash = res.files[0].file;
+          let url = `${window.location.origin}/pictrs/image/${hash}`;
+          i.state.userSettingsForm.avatar = url;
+          i.state.avatarLoading = false;
+          i.setState(i.state);
+        } else {
+          i.state.avatarLoading = false;
+          i.setState(i.state);
+          toast(JSON.stringify(res), 'danger');
         }
-        i.state.userSettingsForm.avatar = url;
-        console.log(url);
-        i.state.avatarLoading = false;
-        i.setState(i.state);
       })
       .catch(error => {
         i.state.avatarLoading = false;
index f39773d02ef27db83762a040bdd49cad53b01364..07d188e2e74e5b051a352d0145b3b1f0dda2eaa7 100644 (file)
@@ -15,7 +15,8 @@
     <link rel="stylesheet" type="text/css" href="/static/assets/css/toastify.css" />
     <link rel="stylesheet" type="text/css" href="/static/assets/css/selectr.min.css" />
     <link rel="stylesheet" type="text/css" href="/static/assets/css/tippy.css" />
-    <link rel="stylesheet" type="text/css" href="/static/assets/css/themes/darkly.min.css" id="darkly" />
+    <link rel="stylesheet" type="text/css" href="/static/assets/css/themes/litely.min.css" id="default-light" media="(prefers-color-scheme: light)" />
+    <link rel="stylesheet" type="text/css" href="/static/assets/css/themes/darkly.min.css" id="default-dark" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: dark)" />
     <link rel="stylesheet" type="text/css" href="/static/assets/css/main.css" />
 
     <!-- Scripts -->
index 47e28c73e8db37617a7e7f8fb585f3a5fd440195..786d5d07ebdb03e8419e56b652f03fb941503c72 100644 (file)
@@ -41,9 +41,7 @@ export class UserService {
 
   private setUser(jwt: string) {
     this.user = jwt_decode(jwt);
-    if (this.user.theme != 'darkly') {
-      setTheme(this.user.theme);
-    }
+    setTheme(this.user.theme, true);
     this.sub.next({ user: this.user });
     console.log(this.user);
   }
index 5ce84b39d915f6ef26a977df86be4b05ab2a472b..071b86acea6045bfe2928f738b056f8c411d4bfa 100644 (file)
@@ -103,6 +103,7 @@ export const themes = [
   'vaporwave',
   'vaporwave-dark',
   'i386',
+  'litely',
 ];
 
 export const emojiPicker = new EmojiButton({
@@ -113,11 +114,26 @@ export const emojiPicker = new EmojiButton({
   // TODO i18n
 });
 
-export function randomStr() {
-  return Math.random()
-    .toString(36)
-    .replace(/[^a-z]+/g, '')
-    .substr(2, 10);
+const DEFAULT_ALPHABET =
+  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+
+function getRandomCharFromAlphabet(alphabet: string): string {
+  return alphabet.charAt(Math.floor(Math.random() * alphabet.length));
+}
+
+export function randomStr(
+  idDesiredLength: number = 20,
+  alphabet = DEFAULT_ALPHABET
+): string {
+  /**
+   * Create n-long array and map it to random chars from given alphabet.
+   * Then join individual chars as string
+   */
+  return Array.from({ length: idDesiredLength })
+    .map(() => {
+      return getRandomCharFromAlphabet(alphabet);
+    })
+    .join('');
 }
 
 export function wsJsonToRes(msg: WebSocketJsonResponse): WebSocketResponse {
@@ -404,7 +420,7 @@ export function getMomentLanguage(): string {
   return lang;
 }
 
-export function setTheme(theme: string = 'darkly') {
+export function setTheme(theme: string = 'darkly', loggedIn: boolean = false) {
   // unload all the other themes
   for (var i = 0; i < themes.length; i++) {
     let styleSheet = document.getElementById(themes[i]);
@@ -413,10 +429,23 @@ export function setTheme(theme: string = 'darkly') {
     }
   }
 
-  // Load the theme dynamically
-  let cssLoc = `/static/assets/css/themes/${theme}.min.css`;
-  loadCss(theme, cssLoc);
-  document.getElementById(theme).removeAttribute('disabled');
+  // if the user is not logged in, we load the default themes and let the browser decide
+  if (!loggedIn) {
+    document.getElementById('default-light').removeAttribute('disabled');
+    document.getElementById('default-dark').removeAttribute('disabled');
+  } else {
+    document
+      .getElementById('default-light')
+      .setAttribute('disabled', 'disabled');
+    document
+      .getElementById('default-dark')
+      .setAttribute('disabled', 'disabled');
+
+    // Load the theme dynamically
+    let cssLoc = `/static/assets/css/themes/${theme}.min.css`;
+    loadCss(theme, cssLoc);
+    document.getElementById(theme).removeAttribute('disabled');
+  }
 }
 
 export function loadCss(id: string, loc: string) {
@@ -440,10 +469,12 @@ export function objectFlip(obj: any) {
   return ret;
 }
 
-export function pictshareAvatarThumbnail(src: string): string {
-  // sample url: http://localhost:8535/pictshare/gs7xuu.jpg
-  let split = src.split('pictshare');
-  let out = `${split[0]}pictshare/${canUseWebP() ? 'webp/' : ''}96${split[1]}`;
+export function pictrsAvatarThumbnail(src: string): string {
+  // sample url: http://localhost:8535/pictrs/image/thumbnail256/gs7xuu.jpg
+  let split = src.split('/pictrs/image');
+  let out = `${split[0]}/pictrs/image/${
+    canUseWebP() ? 'webp/' : ''
+  }thumbnail96${split[1]}`;
   return out;
 }
 
@@ -455,21 +486,18 @@ export function showAvatars(): boolean {
 }
 
 // Converts to image thumbnail
-export function pictshareImage(
-  hash: string,
-  thumbnail: boolean = false
-): string {
-  let root = `/pictshare`;
+export function pictrsImage(hash: string, thumbnail: boolean = false): string {
+  let root = `/pictrs/image`;
 
   // Necessary for other servers / domains
-  if (hash.includes('pictshare')) {
-    let split = hash.split('/pictshare/');
-    root = `${split[0]}/pictshare`;
+  if (hash.includes('pictrs')) {
+    let split = hash.split('/pictrs/image/');
+    root = `${split[0]}/pictrs/image`;
     hash = split[1];
   }
 
   let out = `${root}/${canUseWebP() ? 'webp/' : ''}${
-    thumbnail ? '192/' : ''
+    thumbnail ? 'thumbnail256/' : ''
   }${hash}`;
   return out;
 }
@@ -488,6 +516,29 @@ export function toast(text: string, background: string = 'success') {
   }).showToast();
 }
 
+export function pictrsDeleteToast(
+  clickToDeleteText: string,
+  deletePictureText: string,
+  deleteUrl: string
+) {
+  let backgroundColor = `var(--light)`;
+  let toast = Toastify({
+    text: clickToDeleteText,
+    backgroundColor: backgroundColor,
+    gravity: 'top',
+    position: 'right',
+    duration: 0,
+    onClick: () => {
+      if (toast) {
+        window.location.replace(deleteUrl);
+        alert(deletePictureText);
+        toast.hideToast();
+      }
+    },
+    close: true,
+  }).showToast();
+}
+
 export function messageToastify(
   creator: string,
   avatar: string,
@@ -501,7 +552,7 @@ export function messageToastify(
     text: `${body}<br />${creator}`,
     avatar: avatar,
     backgroundColor: backgroundColor,
-    className: 'text-body',
+    className: 'text-dark',
     close: true,
     gravity: 'top',
     position: 'right',
@@ -910,7 +961,6 @@ function canUseWebP() {
   return false;
 
   // var elem = document.createElement('canvas');
-
   // if (!!(elem.getContext && elem.getContext('2d'))) {
   //   var testString = !(window.mozInnerScreenX == null) ? 'png' : 'webp';
   //   // was able or not to get WebP representation
index 9abc8bceb5c33522bf7a487ff3a5bae246ca0990..575b5379cfa1a68ae7801219b1a170d3ba5eac59 100644 (file)
@@ -1 +1 @@
-export const version: string = 'v0.6.71';
+export const version: string = 'v0.7.0';
index 874172237f9fd19d1978fa01c5002a7ff5e6ee4c..6d2d1c5dce66acaa84dbe90be2dcad2157d80393 100644 (file)
@@ -27,6 +27,7 @@
     "number_of_communities": "{{count}} Community",
     "number_of_communities_plural": "{{count}} Communities",
     "community_reqs": "lowercase, underscores, and no spaces.",
+    "invalid_community_name": "Invalid name.",
     "create_private_message": "Create Private Message",
     "send_secure_message": "Send Secure Message",
     "send_message": "Send Message",
@@ -75,6 +76,8 @@
     "delete_account": "Delete Account",
     "delete_account_confirm":
       "Warning: this will permanently delete all your data. Enter your password to confirm.",
+    "click_to_delete_picture": "Click to delete picture.",
+    "picture_deleted": "Picture deleted.",
     "restore": "restore",
     "ban": "ban",
     "ban_from_site": "ban from site",
index 796aebde3dd7f5a677bfcc6d9c902740c8ea5cd7..0b25e08c0cfe662327270c3a4c5db567f9a547f0 100644 (file)
@@ -5,7 +5,7 @@
     "create_a_post": "Crear una publicación",
     "create_post": "Crear Publicación",
     "number_of_posts": "{{count}} Publicación",
-    "number_of_posts_plural": "{{count}} Publicaciónes",
+    "number_of_posts_plural": "{{count}} Publicaciones",
     "posts": "Publicaciones",
     "related_posts": "Estas publicaciones podrían estar relacionadas",
     "cross_posts": "Este link también ha sido publicado en:",
     "remove_as_admin": "eliminar como administrador",
     "appoint_as_admin": "designar como administrador",
     "remove": "eliminar",
-    "removed": "eliminado",
+    "removed": "eliminado por moderador",
     "locked": "bloqueado",
     "stickied": "fijado",
     "reason": "Razón",
     "mark_as_read": "marcar como leído",
     "mark_as_unread": "marcar como no leído",
     "delete": "eliminar",
-    "deleted": "eliminado",
+    "deleted": "eliminado por creador",
     "delete_account": "Eliminar Cuenta",
-    "delete_account_confirm": "Aviso: esta acción eliminará permanentemente tu información. Introduce tu contraseña para continuar",
+    "delete_account_confirm": "Advertencia: esta acción eliminará permanentemente toda tu información. Introduce tu contraseña para confirmar.",
     "restore": "restaurar",
     "ban": "expulsar",
     "ban_from_site": "expulsar del sitio",
     "theme": "Tema",
     "sponsors": "Patrocinadores",
     "sponsors_of_lemmy": "Patrocinadores de Lemmy",
-    "sponsor_message": "Lemmy es software libre y de <1>código abierto</1>, lo que significa que no tendrá publicidades, monetización, ni capitales emprendedores, nunca. Tus donaciones apoyan directamente el desarrollo a tiempo completo del proyecto. Muchas gracias a las siguientes personas:",
+    "sponsor_message": "Lemmy es software libre y de <1>código abierto</1>, lo que significa que nunca tendrá publicidad, monetización, ni capitales emprendedores. Tus donaciones apoyan directamente el desarrollo a tiempo completo del proyecto. Muchas gracias a las siguientes personas:",
     "support_on_patreon": "Apoyo en Patreon",
     "support_on_liberapay": "Apoyo en Liberapay",
     "donate_to_lemmy": "Donar a Lemmy",
     "banned_users": "Usuarios Baneados",
     "support_on_open_collective": "Dona en OpenCollective",
     "site_saved": "Sitio Guardado.",
-    "emoji_picker": "Emoji Picker",
-    "admin_settings": "Panel de Administración"
+    "emoji_picker": "Lista de emojis",
+    "admin_settings": "Panel de Administración",
+    "select_a_community": "Selecciona una comunidad",
+    "invalid_username": "Nombre de usuario inválido."
 }
index 82714249806f35e7b909ea62510394061a1f5081..a2dfcfdb305c50717517bdf102cecbca38756de6 100644 (file)
@@ -28,7 +28,7 @@
     "community_reqs": "en minuscule, sans espace et avec tiret du bas.",
     "create_private_message": "Créer un message privé",
     "send_secure_message": "Envoyer le message sécurisé",
-    "send_message": "Enovyer le message",
+    "send_message": "Envoyer le message",
     "message": "Message",
     "edit": "éditer",
     "reply": "répondre",
@@ -36,7 +36,7 @@
     "preview": "prévisualiser",
     "upload_image": "envoyer une image",
     "avatar": "Avatar",
-    "upload_avatar": "Télécharger une avatar",
+    "upload_avatar": "Télécharger un avatar",
     "show_avatars": "Afficher les avatars",
     "formatting_help": "aide au formattage",
     "view_source": "voir la source",
     "remove_as_admin": "Supprimer comme admin",
     "appoint_as_admin": "Nommer comme admin",
     "remove": "retirer",
-    "removed": "retiré",
+    "removed": "retiré par le modérateur",
     "locked": "bloqué",
     "stickied": "épinglé",
     "reason": "Raison",
     "mark_as_read": "marquer comme lu",
     "mark_as_unread": "marquer comme non-lu",
     "delete": "supprimer",
-    "deleted": "supprimé",
+    "deleted": "supprimé par le créateur",
     "delete_account": "Supprimer le compte",
     "delete_account_confirm": "Avertissement : cette action supprimera toutes vos données de façons permanente ! Saisissez votre mot de passe pour confirmer.",
     "restore": "restaurer",
     "theme": "Thème",
     "sponsors": "Sponsors",
     "sponsors_of_lemmy": "Sponsors de Lemmy",
-    "sponsor_message": "Lemmy est un logiciel libre et <1>open-source</1>, c’est à dire, il fonctionne sans publicité et sans monétisation aucune. Vos dons soutiennent directement le développement du projet à temps plein. Merci à toutes ces personnes :",
+    "sponsor_message": "Lemmy est un logiciel libre et <1>open-source</1>, sans jamais aucune publicité, ni monétisation ou capital-risque. Vos dons soutiennent directement le développement du projet à temps plein. Merci à toutes ces personnes :",
     "support_on_patreon": "Soutenir sur Patreon",
     "support_on_liberapay": "Soutenir sur Liberapay",
     "donate_to_lemmy": "Faire un don à Lemmy",
     "number_of_downvotes_plural": "{{count}} votes contre",
     "downvote": "Voter contre",
     "emoji_picker": "Sélecteur d’émojis",
-    "silver_sponsors": "Les sponsors argent sont ceux et celles qui ont fait une donation de 40$ à Lemmy."
+    "silver_sponsors": "Les sponsors argent sont ceux et celles qui ont fait une donation de 40$ à Lemmy.",
+    "select_a_community": "Sélectionner une communauté",
+    "invalid_username": "Nom d'utilisateur invalide."
 }
index 0967ef424bce6791893e9a57bb952f80fd536e93..6ad7e0de07b779f7042a7b0b531b70d4d0bc5e18 100644 (file)
@@ -1 +1,107 @@
-{}
+{
+    "post": "Elküld",
+    "remove_post": "Bejegyzés eltávolítása",
+    "no_posts": "Nincs bejegyzés.",
+    "create_post": "Bejegyzés létrehozása",
+    "create_a_post": "Bejegyzés létrehozása",
+    "number_of_posts": "{{count}} bejegyzés",
+    "number_of_posts_plural": "{{count}} bejegyzés",
+    "posts": "Bejegyzések",
+    "related_posts": "Ezek a bejegyzések kapcsolódhatnak",
+    "cross_posts": "Ez a hivatkozás itt is be lett küldve:",
+    "cross_post": "keresztbejegyzés",
+    "comments": "Hozzászólások",
+    "remove_comment": "Hozzászólások eltávolítása",
+    "cross_posted_to": "beküldve ide is: ",
+    "number_of_comments": "{{count}} hozzászólás",
+    "number_of_comments_plural": "{{count}} hozzászólás",
+    "communities": "Közösségek",
+    "users": "Felhasználók",
+    "create_a_community": "Közösség létrehozása",
+    "select_a_community": "Közösség kiválasztása",
+    "create_community": "Közösség létrehozása",
+    "remove_community": "Közösség eltávolítása",
+    "trending_communities": "Népszerű <1>közösségek</1>",
+    "list_of_communities": "Közösségek listája",
+    "community_reqs": "Kisbetű és alsóvonás megengedett, szóköz nem.",
+    "create_private_message": "Privát üzenet létrehozása",
+    "send_secure_message": "Biztonságos üzenet küldése",
+    "send_message": "Üzenet küldése",
+    "message": "Üzenet",
+    "edit": "szerkesztés",
+    "reply": "válasz",
+    "more": "több",
+    "cancel": "Mégse",
+    "preview": "Előnézet",
+    "upload_image": "kép feltöltése",
+    "avatar": "Avatár",
+    "upload_avatar": "Avatár feltöltése",
+    "show_avatars": "Avatárok mutatása",
+    "show_context": "Összefüggés mutatása",
+    "sorting_help": "rendezési segítség",
+    "view_source": "forrás megtekintése",
+    "unlock": "zárolás feloldása",
+    "lock": "zárolás",
+    "sticky": "rögzítés",
+    "unsticky": "rögzítés feloldása",
+    "link": "hivatkozás",
+    "mod": "moderátor",
+    "mods": "moderátorok",
+    "moderates": "Moderált közösségek",
+    "settings": "Beállítások",
+    "admin_settings": "Adminisztrációs beállítások",
+    "remove_as_mod": "moderátori jog eltávolítása",
+    "appoint_as_mod": "kinevezés moderátornak",
+    "modlog": "Moderációs napló",
+    "admin": "admin",
+    "admins": "adminok",
+    "remove_as_admin": "adminjog eltávolítása",
+    "appoint_as_admin": "kinevezés adminnak",
+    "remove": "eltávolítás",
+    "locked": "zárolva",
+    "stickied": "rögzítve",
+    "reason": "Indok",
+    "mark_as_read": "megjelölés olvasottnak",
+    "mark_as_unread": "megjelölés olvasatlannak",
+    "delete": "törlés",
+    "deleted": "eltávolítva a szerző által",
+    "delete_account": "FIók törlése",
+    "restore": "visszaállítás",
+    "ban": "kitiltás",
+    "ban_from_site": "kitiltás az oldalról",
+    "unban": "kitiltás visszavonása",
+    "unban_from_site": "az oldalról történő kitiltás visszavonása",
+    "banned": "kitiltva",
+    "banned_users": "Kitiltott felhasználók",
+    "save": "mentés",
+    "unsave": "mentés visszavonása",
+    "create": "létrehozás",
+    "creator": "szerző",
+    "username": "Felhasználónév",
+    "number_of_points": "{{count}} pont",
+    "number_of_points_plural": "{{count}} pont",
+    "number_of_subscribers": "{{count}} feliratkozó",
+    "number_of_subscribers_plural": "{{count}} feliratkozó",
+    "name": "Név",
+    "title": "Cím",
+    "category": "Kategória",
+    "both": "Mindkettő",
+    "saved": "Mentve",
+    "unsubscribe": "Leiratkozás",
+    "subscribe": "Feliratkozás",
+    "subscribed": "Feliratkozva",
+    "subscribed_to_communities": "Követett <1>közösségek</1>",
+    "number_of_communities": "{{count}} közösség",
+    "number_of_communities_plural": "{{count}} közösség",
+    "formatting_help": "formázási segítség",
+    "archive_link": "hivatkozás archiválása",
+    "site_config": "Oldalbeállítások",
+    "removed": "eltávolítva egy mod által",
+    "delete_account_confirm": "Figyelmeztetés: ez véglegesen törölni fogja az összes adatodat. A megerősítéshez írd be a jelszavad!",
+    "email_or_username": "Email vagy felhasználónév",
+    "number_of_users": "{{count}} felhasználó",
+    "number_of_users_plural": "{{count}} felhasználó",
+    "number_online": "{{count}} online felhasználó",
+    "number_online_plural": "{{count}} online felhasználó",
+    "subscribers": "Feliratkozók"
+}
index 872d0b51fbf0b1438fe3322243577ce010d899fd..def3b05cb8ae2025abbf08c0fe03822b5369bb55 100644 (file)
     "remove_as_admin": "移除管理权限",
     "appoint_as_admin": "添加管理权限",
     "remove": "移除",
-    "removed": "已移除",
+    "removed": "已被管理员移除",
     "locked": "已加锁",
     "reason": "原因",
     "mark_as_read": "标记未读",
     "mark_as_unread": "标记已读",
     "delete": "删除",
-    "deleted": "已删除",
+    "deleted": "作者已删除",
     "restore": "恢复",
     "ban": "禁止",
     "ban_from_site": "禁止此站点",
     "time": "时间",
     "action": "行动",
     "block_leaving": "确定要离开吗?",
-    "show_context": "显示上下文"
+    "show_context": "显示上下文",
+    "admin_settings": "管理员设置",
+    "site_config": "网站配置",
+    "banned_users": "被禁止用户",
+    "site_saved": "网站已保存",
+    "emoji_picker": "选择表情",
+    "invalid_username": "用户名无效"
 }