From 44681b97a6c06bfe0dbada1e9dac43a8a1c3783a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 8 Apr 2021 22:39:10 +0900 Subject: [PATCH 001/147] =?UTF-8?q?:sparkles:=20=EC=B6=94=EA=B0=80:=20deve?= =?UTF-8?q?lop=20=EB=B8=8C=EB=9E=9C=EC=B9=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5f6025a..1b408ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +# # Created by https://www.toptal.com/developers/gitignore/api/python,vscode # Edit at https://www.toptal.com/developers/gitignore?templates=python,vscode From 97f5b400c74a9bd3d528f4a054a6d74d99d31c87 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sat, 10 Apr 2021 15:03:40 +0900 Subject: [PATCH 002/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20gitignore=20id?= =?UTF-8?q?e=20setting=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1b408ae..d2fbbcd 100644 --- a/.gitignore +++ b/.gitignore @@ -159,4 +159,7 @@ Thumbs.db !.vscode/extensions.json *.code-workspace -# End of https://www.toptal.com/developers/gitignore/api/python,vscode \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/python,vscode +.idea/ + +.vscode/ From 7738e2ffe031f0664784311ce96a738a8256cfa7 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 20:44:09 +0900 Subject: [PATCH 003/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20user=20entity?= =?UTF-8?q?=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/user/provider.py | 6 ++++++ app/models/user/user.py | 11 +++++++++++ 2 files changed, 17 insertions(+) create mode 100644 app/models/user/provider.py create mode 100644 app/models/user/user.py diff --git a/app/models/user/provider.py b/app/models/user/provider.py new file mode 100644 index 0000000..6830a44 --- /dev/null +++ b/app/models/user/provider.py @@ -0,0 +1,6 @@ +import enum + + +class Provider(enum.Enum): + GOOGLE = 1 + FACEBOOK = 2 \ No newline at end of file diff --git a/app/models/user/user.py b/app/models/user/user.py new file mode 100644 index 0000000..3244211 --- /dev/null +++ b/app/models/user/user.py @@ -0,0 +1,11 @@ +from sqlalchemy import Column, Integer, Float, Enum, String + +from app.database.base_class import Base +from app.models.user.provider import Provider + + +class User(Base): + id = Column('user_id', Integer, primary_key=True, autoincrement=True) + provider = Column('user_provider', Enum(Provider), nullable=False) + social_id = Column('user_social_id', String, nullable=False, unique=True) + nickname = Column('user_nickname', String, nullable=False, unique=True) \ No newline at end of file From 40b6c3be01e05f153c3f131288fd4edbb053dc44 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 21:32:52 +0900 Subject: [PATCH 004/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20auth=20service?= =?UTF-8?q?=20test=20code=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/tests/service/__init__.py | 0 app/tests/service/user/__init__.py | 0 app/tests/service/user/test_auth.py | 43 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 app/tests/service/__init__.py create mode 100644 app/tests/service/user/__init__.py create mode 100644 app/tests/service/user/test_auth.py diff --git a/app/tests/service/__init__.py b/app/tests/service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/service/user/__init__.py b/app/tests/service/user/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/service/user/test_auth.py b/app/tests/service/user/test_auth.py new file mode 100644 index 0000000..3cd68a1 --- /dev/null +++ b/app/tests/service/user/test_auth.py @@ -0,0 +1,43 @@ +from datetime import timedelta +from typing import Dict + +from fastapi.testclient import TestClient +from jose import jwt, JWTError + +from app.core import settings + + +def test_create_token() -> None: + # 토큰의 생성이 이루어지는 지 테스트 + # payload 테스트 + data = {"body": "test"} + access_token_expires = timedelta(minutes=15) + token = create_access_token(data, access_token_expires) + payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) + + actual = payload.get("body") + + assert actual == "test" + + +def test_auth_google_token() -> None: + # 잘못된 토큰에 대하여 status 400 반환 + wrong_token = "test" + actual = auth_google_token(wrong_token).status_code + + assert actual == 400 + + +def test_check_access_token_valid() -> None: + test_token = "#$%^&feedfw1234" + actual = check_access_token_valid(test_token) + + assert actual is False + + +def test_check_refresh_token() -> None: + # redis의 ref 토큰을 확인. + user_id = 15 + actual = check_refresh_token(15) + + assert actual is not None From d218dbb23dce4d25373b1d3f03b2a46c4001abdb Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 21:55:44 +0900 Subject: [PATCH 005/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20auth=20service?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/__init__.py | 0 app/service/user/__init__.py | 0 app/service/user/auth.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 app/service/__init__.py create mode 100644 app/service/user/__init__.py create mode 100644 app/service/user/auth.py diff --git a/app/service/__init__.py b/app/service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/service/user/__init__.py b/app/service/user/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/service/user/auth.py b/app/service/user/auth.py new file mode 100644 index 0000000..92c9b28 --- /dev/null +++ b/app/service/user/auth.py @@ -0,0 +1,32 @@ +from datetime import datetime, timedelta +from typing import Optional + +import requests +from jose import jwt, JWTError + +from app.core import settings + + +def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): + to_encode = data.copy() + if expires_delta: + expire = datetime.utcnow() + expires_delta + else: + expire = datetime.utcnow() + timedelta(minutes=15) + to_encode.update({"exp": expire}) + encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM) + return encoded_jwt + + +def auth_google_token(token: str): + return requests.get("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + token) + + +def check_access_token_valid(token: str): + decode_token = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) + return decode_token["expires"] >= datetime.utcnow() + + +def check_refresh_token(param): + # todo : 레디스 연결 이후 + pass From 3a370854abf16751e3ed28bdf2c56ee008622fc6 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 21:56:13 +0900 Subject: [PATCH 006/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20config?= =?UTF-8?q?=EC=97=90=20token=20=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/core/config.py b/app/core/config.py index eca9651..47cacf9 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -8,6 +8,7 @@ class Settings(BaseSettings): PROJECT_NAME: str = "FastAPI" SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/fastapi_db" + ALGORITHM = "HS256" class Config: env_file = ".env" From 6322a1cc697b9fb896b6215a34a842800ad31c96 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 22:00:34 +0900 Subject: [PATCH 007/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20user=20fixture?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/tests/conftest.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 95de03a..db1dd6f 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -26,3 +26,12 @@ def random_product() -> Dict[str, str]: "name": "Test Product", "price": 80, } + + +def test_user() -> Dict[str, str]: + return { + "id": 1, + "provider": "Google", + "email": "test@test.com", + "nickname": "test" + } From cf6b60e16e3444d02a991c54d4a6e69837338640 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 22:01:41 +0900 Subject: [PATCH 008/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20.env=20gitgino?= =?UTF-8?q?re=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 --- .gitignore | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 7fc89a2..0000000 --- a/.env +++ /dev/null @@ -1,3 +0,0 @@ -API_V1_STR="/api/v1" -PROJECT_NAME="FastAPI" -SQLALCHEMY_DATABASE_URI="postgresql://localhost:5432/fastapi_db" diff --git a/.gitignore b/.gitignore index d2fbbcd..f5da125 100644 --- a/.gitignore +++ b/.gitignore @@ -163,3 +163,5 @@ Thumbs.db .idea/ .vscode/ + +.env From d7e8d1469cdfd64a2a28a4dc0dc48c7569443e46 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 22:04:30 +0900 Subject: [PATCH 009/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20User=20code=20?= =?UTF-8?q?formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/__init__.py | 1 + app/models/user/provider.py | 2 +- app/models/user/user.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/__init__.py b/app/models/__init__.py index e049467..6f9a137 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1 +1,2 @@ from app.models.product import Product +from app.models.user.user import User diff --git a/app/models/user/provider.py b/app/models/user/provider.py index 6830a44..5c59ec6 100644 --- a/app/models/user/provider.py +++ b/app/models/user/provider.py @@ -3,4 +3,4 @@ class Provider(enum.Enum): GOOGLE = 1 - FACEBOOK = 2 \ No newline at end of file + FACEBOOK = 2 diff --git a/app/models/user/user.py b/app/models/user/user.py index 3244211..fb494b2 100644 --- a/app/models/user/user.py +++ b/app/models/user/user.py @@ -8,4 +8,4 @@ class User(Base): id = Column('user_id', Integer, primary_key=True, autoincrement=True) provider = Column('user_provider', Enum(Provider), nullable=False) social_id = Column('user_social_id', String, nullable=False, unique=True) - nickname = Column('user_nickname', String, nullable=False, unique=True) \ No newline at end of file + nickname = Column('user_nickname', String, nullable=False, unique=True) From 8d47232b8d47e77fe0da5ff40b71e86b253b744c Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Thu, 6 May 2021 22:05:24 +0900 Subject: [PATCH 010/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20test=20code=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_check_access_token_valid -> test token 추가 test_check_refresh_token -> 주석처리 --- app/tests/service/user/test_auth.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/tests/service/user/test_auth.py b/app/tests/service/user/test_auth.py index 3cd68a1..2ba8920 100644 --- a/app/tests/service/user/test_auth.py +++ b/app/tests/service/user/test_auth.py @@ -5,6 +5,7 @@ from jose import jwt, JWTError from app.core import settings +from app.service.user.auth import create_access_token, auth_google_token, check_access_token_valid def test_create_token() -> None: @@ -29,15 +30,16 @@ def test_auth_google_token() -> None: def test_check_access_token_valid() -> None: - test_token = "#$%^&feedfw1234" + test_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImV4cCI6MTYyMDMwNjQzMH0' \ + '.1c4BevvQ3IvPJSPBYQGMfwArVNpxOwO_qUhGwycYAuc ' actual = check_access_token_valid(test_token) assert actual is False -def test_check_refresh_token() -> None: - # redis의 ref 토큰을 확인. - user_id = 15 - actual = check_refresh_token(15) - - assert actual is not None +# def test_check_refresh_token() -> None: +# # redis의 ref 토큰을 확인. +# user_id = 15 +# actual = check_refresh_token(15) +# +# assert actual is not None From 003ba85b4fb3e9872187090ce03b1abd06266638 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:28:41 +0900 Subject: [PATCH 011/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=EC=84=9C=EB=B2=84=EC=9A=B4=EC=98=81=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=84=A4=EC=A0=95=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 10 + config/redis/redis.conf | 1861 +++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 41 + 3 files changed, 1912 insertions(+) create mode 100644 Dockerfile create mode 100644 config/redis/redis.conf create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1c8c093 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.8 + +WORKDIR /code +ADD . /code +COPY ./requirements.txt /code/requirements.txt +RUN pip install -r requirements.txt +COPY . /code +ENV DOCKERIZE_VERSION v0.6.1\\ + +CMD ["python3", "-m", "app.main"] \ No newline at end of file diff --git a/config/redis/redis.conf b/config/redis/redis.conf new file mode 100644 index 0000000..0ed3b36 --- /dev/null +++ b/config/redis/redis.conf @@ -0,0 +1,1861 @@ +# Redis configuration file example. +# +# Note that in order to read the configuration file, Redis must be +# started with the file path as first argument: +# +# ./redis-server /path/to/redis.conf + +# Note on units: when memory size is needed, it is possible to specify +# it in the usual form of 1k 5GB 4M and so forth: +# +# 1k => 1000 bytes +# 1kb => 1024 bytes +# 1m => 1000000 bytes +# 1mb => 1024*1024 bytes +# 1g => 1000000000 bytes +# 1gb => 1024*1024*1024 bytes +# +# units are case insensitive so 1GB 1Gb 1gB are all the same. + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis servers but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# Notice option "include" won't be rewritten by command "CONFIG REWRITE" +# from admin or Redis Sentinel. Since Redis always uses the last processed +# line as value of a configuration directive, you'd better put includes +# at the beginning of this file to avoid overwriting config change at runtime. +# +# If instead you are interested in using includes to override configuration +# options, it is better to use include as the last line. +# +# include /path/to/local.conf +# include /path/to/other.conf + +################################## MODULES ##################################### + +# Load modules at startup. If the server is not able to load modules +# it will abort. It is possible to use multiple loadmodule directives. +# +# loadmodule /path/to/my_module.so +# loadmodule /path/to/other_module.so + +################################## NETWORK ##################################### + +# By default, if no "bind" configuration directive is specified, Redis listens +# for connections from all the network interfaces available on the server. +# It is possible to listen to just one or multiple selected interfaces using +# the "bind" configuration directive, followed by one or more IP addresses. +# +# Examples: +# +# bind 192.168.1.100 10.0.0.1 +# bind 127.0.0.1 ::1 +# +# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the +# internet, binding to all the interfaces is dangerous and will expose the +# instance to everybody on the internet. So by default we uncomment the +# following bind directive, that will force Redis to listen only into +# the IPv4 loopback interface address (this means Redis will be able to +# accept connections only from clients running into the same computer it +# is running). +# +# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES +# JUST COMMENT THE FOLLOWING LINE. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bind 0.0.0.0 + +# Protected mode is a layer of security protection, in order to avoid that +# Redis instances left open on the internet are accessed and exploited. +# +# When protected mode is on and if: +# +# 1) The server is not binding explicitly to a set of addresses using the +# "bind" directive. +# 2) No password is configured. +# +# The server only accepts connections from clients connecting from the +# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain +# sockets. +# +# By default protected mode is enabled. You should disable it only if +# you are sure you want clients from other hosts to connect to Redis +# even if no authentication is configured, nor a specific set of interfaces +# are explicitly listed using the "bind" directive. +protected-mode yes + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 6379 + +# TCP listen() backlog. +# +# In high requests-per-second environments you need an high backlog in order +# to avoid slow clients connections issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock +# unixsocketperm 700 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +################################# TLS/SSL ##################################### + +# By default, TLS/SSL is disabled. To enable it, the "tls-port" configuration +# directive can be used to define TLS-listening ports. To enable TLS on the +# default port, use: +# +# port 0 +# tls-port 6379 + +# Configure a X.509 certificate and private key to use for authenticating the +# server to connected clients, masters or cluster peers. These files should be +# PEM formatted. +# +# tls-cert-file redis.crt +# tls-key-file redis.key + +# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange: +# +# tls-dh-params-file redis.dh + +# Configure a CA certificate(s) bundle or directory to authenticate TLS/SSL +# clients and peers. Redis requires an explicit configuration of at least one +# of these, and will not implicitly use the system wide configuration. +# +# tls-ca-cert-file ca.crt +# tls-ca-cert-dir /etc/ssl/certs + +# By default, clients (including replica servers) on a TLS port are required +# to authenticate using valid client side certificates. +# +# If "no" is specified, client certificates are not required and not accepted. +# If "optional" is specified, client certificates are accepted and must be +# valid if provided, but are not required. +# +# tls-auth-clients no +# tls-auth-clients optional + +# By default, a Redis replica does not attempt to establish a TLS connection +# with its master. +# +# Use the following directive to enable TLS on replication links. +# +# tls-replication yes + +# By default, the Redis Cluster bus uses a plain TCP connection. To enable +# TLS for the bus protocol, use the following directive: +# +# tls-cluster yes + +# Explicitly specify TLS versions to support. Allowed values are case insensitive +# and include "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" (OpenSSL >= 1.1.1) or +# any combination. To enable only TLSv1.2 and TLSv1.3, use: +# +# tls-protocols "TLSv1.2 TLSv1.3" + +# Configure allowed ciphers. See the ciphers(1ssl) manpage for more information +# about the syntax of this string. +# +# Note: this configuration applies only to <= TLSv1.2. +# +# tls-ciphers DEFAULT:!MEDIUM + +# Configure allowed TLSv1.3 ciphersuites. See the ciphers(1ssl) manpage for more +# information about the syntax of this string, and specifically for TLSv1.3 +# ciphersuites. +# +# tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256 + +# When choosing a cipher, use the server's preference instead of the client +# preference. By default, the server follows the client's preference. +# +# tls-prefer-server-ciphers yes + +# By default, TLS session caching is enabled to allow faster and less expensive +# reconnections by clients that support it. Use the following directive to disable +# caching. +# +# tls-session-caching no + +# Change the default number of TLS sessions cached. A zero value sets the cache +# to unlimited size. The default size is 20480. +# +# tls-session-cache-size 5000 + +# Change the default timeout of cached TLS sessions. The default timeout is 300 +# seconds. +# +# tls-session-cache-timeout 60 + +################################# GENERAL ##################################### + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +daemonize no + +# If you run Redis from upstart or systemd, Redis can interact with your +# supervision tree. Options: +# supervised no - no supervision interaction +# supervised upstart - signal upstart by putting Redis into SIGSTOP mode +# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET +# supervised auto - detect upstart or systemd method based on +# UPSTART_JOB or NOTIFY_SOCKET environment variables +# Note: these supervision methods only signal "process is ready." +# They do not enable continuous liveness pings back to your supervisor. +supervised no + +# If a pid file is specified, Redis writes it where specified at startup +# and removes it at exit. +# +# When the server runs non daemonized, no pid file is created if none is +# specified in the configuration. When the server is daemonized, the pid file +# is used even if not specified, defaulting to "/var/run/redis.pid". +# +# Creating a pid file is best effort: if Redis is not able to create it +# nothing bad happens, the server will start and run normally. +pidfile /var/run/redis_6379.pid + +# Specify the server verbosity level. +# This can be one of: +# debug (a lot of information, useful for development/testing) +# verbose (many rarely useful info, but not a mess like the debug level) +# notice (moderately verbose, what you want in production probably) +# warning (only very important / critical messages are logged) +loglevel notice + +# Specify the log file name. Also the empty string can be used to force +# Redis to log on the standard output. Note that if you use standard +# output for logging but daemonize, logs will be sent to /dev/null +logfile "" + +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +# syslog-enabled no + +# Specify the syslog identity. +# syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# syslog-facility local0 + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT where +# dbid is a number between 0 and 'databases'-1 +databases 16 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY. Basically this means +# that normally a logo is displayed only in interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo yes + +################################ SNAPSHOTTING ################################ +# +# Save the DB on disk: +# +# save +# +# Will save the DB if both the given number of seconds and the given +# number of write operations against the DB occurred. +# +# In the example below the behaviour will be to save: +# after 900 sec (15 min) if at least 1 key changed +# after 300 sec (5 min) if at least 10 keys changed +# after 60 sec if at least 10000 keys changed +# +# Note: you can disable saving completely by commenting out all "save" lines. +# +# It is also possible to remove all the previously configured save +# points by adding a save directive with a single empty string argument +# like in the following example: +# +# save "" + +save 900 1 +save 300 10 +save 60 10000 + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# For default that's set to 'yes' as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename dump.rdb + +# Remove RDB files used by replication in instances without persistence +# enabled. By default this option is disabled, however there are environments +# where for regulations or other security concerns, RDB files persisted on +# disk by masters in order to feed replicas, or stored on disk by replicas +# in order to load them for the initial synchronization, should be deleted +# ASAP. Note that this option ONLY WORKS in instances that have both AOF +# and RDB persistence disabled, otherwise is completely ignored. +# +# An alternative (and sometimes better) way to obtain the same effect is +# to use diskless replication on both master and replicas instances. However +# in the case of replicas, diskless is not always an option. +rdb-del-sync-files no + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir ./ + +################################# REPLICATION ################################# + +# Master-Replica replication. Use replicaof to make a Redis instance a copy of +# another Redis server. A few things to understand ASAP about Redis replication. +# +# +------------------+ +---------------+ +# | Master | ---> | Replica | +# | (receive writes) | | (exact copy) | +# +------------------+ +---------------+ +# +# 1) Redis replication is asynchronous, but you can configure a master to +# stop accepting writes if it appears to be not connected with at least +# a given number of replicas. +# 2) Redis replicas are able to perform a partial resynchronization with the +# master if the replication link is lost for a relatively small amount of +# time. You may want to configure the replication backlog size (see the next +# sections of this file) with a sensible value depending on your needs. +# 3) Replication is automatic and does not need user intervention. After a +# network partition replicas automatically try to reconnect to masters +# and resynchronize with them. +# +# replicaof + +# If the master is password protected (using the "requirepass" configuration +# directive below) it is possible to tell the replica to authenticate before +# starting the replication synchronization process, otherwise the master will +# refuse the replica request. +# +# masterauth +# +# However this is not enough if you are using Redis ACLs (for Redis version +# 6 or greater), and the default user is not capable of running the PSYNC +# command and/or other commands needed for replication. In this case it's +# better to configure a special user to use with replication, and specify the +# masteruser configuration as such: +# +# masteruser +# +# When masteruser is specified, the replica will authenticate against its +# master using the new AUTH form: AUTH . + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if replica-serve-stale-data is set to 'no' the replica will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, +# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, +# COMMAND, POST, HOST: and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# New replicas and reconnecting replicas that are not able to continue the +# replication process just receiving differences, need to do what is called a +# "full synchronization". An RDB file is transmitted from the master to the +# replicas. +# +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child +# producing the RDB file finishes its work. With diskless replication instead +# once the transfer starts, new replicas arriving will be queued and a new +# transfer will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple +# replicas will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync no + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the +# server waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# ----------------------------------------------------------------------------- +# WARNING: RDB diskless load is experimental. Since in this setup the replica +# does not immediately store an RDB on disk, it may cause data loss during +# failovers. RDB diskless load + Redis modules not handling I/O reads may also +# cause Redis to abort in case of I/O errors during the initial synchronization +# stage with the master. Use only if your do what you are doing. +# ----------------------------------------------------------------------------- +# +# Replica can load the RDB it reads from the replication link directly from the +# socket, or store the RDB to a file and read that file after it was completely +# recived from the master. +# +# In many cases the disk is slower than the network, and storing and loading +# the RDB file may increase replication time (and even increase the master's +# Copy on Write memory and salve buffers). +# However, parsing the RDB file directly from the socket may mean that we have +# to flush the contents of the current database before the full rdb was +# received. For this reason we have the following options: +# +# "disabled" - Don't use diskless load (store the rdb file to the disk first) +# "on-empty-self" - Use diskless load only when it is completely safe. +# "swapdb" - Keep a copy of the current self contents in RAM while parsing +# the data directly from the socket. note that this requires +# sufficient memory, if you don't have it, you risk an OOM kill. +repl-diskless-load disabled + +# Replicas send PINGs to server in a predefined interval. It's possible to +# change this interval with the repl_ping_replica_period option. The default +# value is 10 seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# Set the replication backlog size. The backlog is a buffer that accumulates +# replica data when replicas are disconnected for some time, so that when a +# replica wants to reconnect again, often a full resync is not needed, but a +# partial resync is enough, just passing the portion of data the replica +# missed while disconnected. +# +# The bigger the replication backlog, the longer the time the replica can be +# disconnected and later be able to perform a partial resynchronization. +# +# The backlog is only allocated once there is at least a replica connected. +# +# repl-backlog-size 1mb + +# After a master has no longer connected replicas for some time, the backlog +# will be freed. The following option configures the amount of seconds that +# need to elapse, starting from the time the last replica disconnected, for +# the backlog buffer to be freed. +# +# Note that replicas never free the backlog for timeout, since they may be +# promoted to masters later, and should be able to correctly "partially +# resynchronize" with the replicas: hence they should always accumulate backlog. +# +# A value of 0 means to never release the backlog. +# +# repl-backlog-ttl 3600 + +# The replica priority is an integer number published by Redis in the INFO +# output. It is used by Redis Sentinel in order to select a replica to promote +# into a master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel +# will pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# It is possible for a master to stop accepting writes if there are less than +# N replicas connected, having a lag less or equal than M seconds. +# +# The N replicas need to be in "online" state. +# +# The lag in seconds, that must be <= the specified value, is calculated from +# the last ping received from the replica, that is usually sent every second. +# +# This option does not GUARANTEE that N replicas will accept the write, but +# will limit the window of exposure for lost writes in case not enough replicas +# are available, to the specified number of seconds. +# +# For example to require at least 3 replicas with a lag <= 10 seconds use: +# +# min-replicas-to-write 3 +# min-replicas-max-lag 10 +# +# Setting one or the other to 0 disables the feature. +# +# By default min-replicas-to-write is set to 0 (feature disabled) and +# min-replicas-max-lag is set to 10. + +# A Redis master is able to list the address and port of the attached +# replicas in different ways. For example the "INFO replication" section +# offers this information, which is used, among other tools, by +# Redis Sentinel in order to discover replica instances. +# Another place where this info is available is in the output of the +# "ROLE" command of a master. +# +# The listed IP and address normally reported by a replica is obtained +# in the following way: +# +# IP: The address is auto detected by checking the peer address +# of the socket used by the replica to connect with the master. +# +# Port: The port is communicated by the replica during the replication +# handshake, and is normally the port that the replica is using to +# listen for connections. +# +# However when port forwarding or Network Address Translation (NAT) is +# used, the replica may be actually reachable via different IP and port +# pairs. The following two options can be used by a replica in order to +# report to its master a specific set of IP and port, so that both INFO +# and ROLE will report those values. +# +# There is no need to use both the options if you need to override just +# the port or the IP address. +# +# replica-announce-ip 5.5.5.5 +# replica-announce-port 1234 + +############################### KEYS TRACKING ################################# + +# Redis implements server assisted support for client side caching of values. +# This is implemented using an invalidation table that remembers, using +# 16 millions of slots, what clients may have certain subsets of keys. In turn +# this is used in order to send invalidation messages to clients. Please +# to understand more about the feature check this page: +# +# https://redis.io/topics/client-side-caching +# +# When tracking is enabled for a client, all the read only queries are assumed +# to be cached: this will force Redis to store information in the invalidation +# table. When keys are modified, such information is flushed away, and +# invalidation messages are sent to the clients. However if the workload is +# heavily dominated by reads, Redis could use more and more memory in order +# to track the keys fetched by many clients. +# +# For this reason it is possible to configure a maximum fill value for the +# invalidation table. By default it is set to 1M of keys, and once this limit +# is reached, Redis will start to evict keys in the invalidation table +# even if they were not modified, just to reclaim memory: this will in turn +# force the clients to invalidate the cached values. Basically the table +# maximum size is a trade off between the memory you want to spend server +# side to track information about who cached what, and the ability of clients +# to retain cached objects in memory. +# +# If you set the value to 0, it means there are no limits, and Redis will +# retain as many keys as needed in the invalidation table. +# In the "stats" INFO section, you can find information about the number of +# keys in the invalidation table at every given moment. +# +# Note: when key tracking is used in broadcasting mode, no memory is used +# in the server side so this setting is useless. +# +# tracking-table-max-keys 1000000 + +################################## SECURITY ################################### + +# Warning: since Redis is pretty fast an outside user can try up to +# 1 million passwords per second against a modern box. This means that you +# should use very strong passwords, otherwise they will be very easy to break. +# Note that because the password is really a shared secret between the client +# and the server, and should not be memorized by any human, the password +# can be easily a long string from /dev/urandom or whatever, so by using a +# long and unguessable password no brute force attack will be possible. + +# Redis ACL users are defined in the following format: +# +# user ... acl rules ... +# +# For example: +# +# user worker +@list +@connection ~jobs:* on >ffa9203c493aa99 +# +# The special username "default" is used for new connections. If this user +# has the "nopass" rule, then new connections will be immediately authenticated +# as the "default" user without the need of any password provided via the +# AUTH command. Otherwise if the "default" user is not flagged with "nopass" +# the connections will start in not authenticated state, and will require +# AUTH (or the HELLO command AUTH option) in order to be authenticated and +# start to work. +# +# The ACL rules that describe what an user can do are the following: +# +# on Enable the user: it is possible to authenticate as this user. +# off Disable the user: it's no longer possible to authenticate +# with this user, however the already authenticated connections +# will still work. +# + Allow the execution of that command +# - Disallow the execution of that command +# +@ Allow the execution of all the commands in such category +# with valid categories are like @admin, @set, @sortedset, ... +# and so forth, see the full list in the server.c file where +# the Redis command table is described and defined. +# The special category @all means all the commands, but currently +# present in the server, and that will be loaded in the future +# via modules. +# +|subcommand Allow a specific subcommand of an otherwise +# disabled command. Note that this form is not +# allowed as negative like -DEBUG|SEGFAULT, but +# only additive starting with "+". +# allcommands Alias for +@all. Note that it implies the ability to execute +# all the future commands loaded via the modules system. +# nocommands Alias for -@all. +# ~ Add a pattern of keys that can be mentioned as part of +# commands. For instance ~* allows all the keys. The pattern +# is a glob-style pattern like the one of KEYS. +# It is possible to specify multiple patterns. +# allkeys Alias for ~* +# resetkeys Flush the list of allowed keys patterns. +# > Add this passowrd to the list of valid password for the user. +# For example >mypass will add "mypass" to the list. +# This directive clears the "nopass" flag (see later). +# < Remove this password from the list of valid passwords. +# nopass All the set passwords of the user are removed, and the user +# is flagged as requiring no password: it means that every +# password will work against this user. If this directive is +# used for the default user, every new connection will be +# immediately authenticated with the default user without +# any explicit AUTH command required. Note that the "resetpass" +# directive will clear this condition. +# resetpass Flush the list of allowed passwords. Moreover removes the +# "nopass" status. After "resetpass" the user has no associated +# passwords and there is no way to authenticate without adding +# some password (or setting it as "nopass" later). +# reset Performs the following actions: resetpass, resetkeys, off, +# -@all. The user returns to the same state it has immediately +# after its creation. +# +# ACL rules can be specified in any order: for instance you can start with +# passwords, then flags, or key patterns. However note that the additive +# and subtractive rules will CHANGE MEANING depending on the ordering. +# For instance see the following example: +# +# user alice on +@all -DEBUG ~* >somepassword +# +# This will allow "alice" to use all the commands with the exception of the +# DEBUG command, since +@all added all the commands to the set of the commands +# alice can use, and later DEBUG was removed. However if we invert the order +# of two ACL rules the result will be different: +# +# user alice on -DEBUG +@all ~* >somepassword +# +# Now DEBUG was removed when alice had yet no commands in the set of allowed +# commands, later all the commands are added, so the user will be able to +# execute everything. +# +# Basically ACL rules are processed left-to-right. +# +# For more information about ACL configuration please refer to +# the Redis web site at https://redis.io/topics/acl + +# ACL LOG +# +# The ACL Log tracks failed commands and authentication events associated +# with ACLs. The ACL Log is useful to troubleshoot failed commands blocked +# by ACLs. The ACL Log is stored in memory. You can reclaim memory with +# ACL LOG RESET. Define the maximum entry length of the ACL Log below. +acllog-max-len 128 + +# Using an external ACL file +# +# Instead of configuring users here in this file, it is possible to use +# a stand-alone file just listing users. The two methods cannot be mixed: +# if you configure users here and at the same time you activate the exteranl +# ACL file, the server will refuse to start. +# +# The format of the external ACL user file is exactly the same as the +# format that is used inside redis.conf to describe users. +# +# aclfile /etc/redis/users.acl + +# IMPORTANT NOTE: starting with Redis 6 "requirepass" is just a compatiblity +# layer on top of the new ACL system. The option effect will be just setting +# the password for the default user. Clients will still authenticate using +# AUTH as usually, or more explicitly with AUTH default +# if they follow the new protocol: both will work. +# +# requirepass foobared + +# Command renaming (DEPRECATED). +# +# ------------------------------------------------------------------------ +# WARNING: avoid using this option if possible. Instead use ACLs to remove +# commands from the default user, and put them only in some admin user you +# create for administrative purposes. +# ------------------------------------------------------------------------ +# +# It is possible to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possible to completely kill a command by renaming it into +# an empty string: +# +# rename-command CONFIG "" +# +# Please note that changing the name of commands that are logged into the +# AOF file or transmitted to replicas may cause problems. + +################################### CLIENTS #################################### + +# Set the max number of connected clients at the same time. By default +# this limit is set to 10000 clients, however if the Redis server is not +# able to configure the process file limit to allow for the specified limit +# the max number of allowed clients is set to the current file limit +# minus 32 (as Redis reserves a few file descriptors for internal uses). +# +# Once the limit is reached Redis will close all the new connections sending +# an error 'max number of clients reached'. +# +# IMPORTANT: When Redis Cluster is used, the max number of connections is also +# shared with the cluster bus: every node in the cluster will use two +# connections, one incoming and another outgoing. It is important to size the +# limit accordingly in case of very large clusters. +# +# maxclients 10000 + +############################## MEMORY MANAGEMENT ################################ + +# Set a memory usage limit to the specified amount of bytes. +# When the memory limit is reached Redis will try to remove keys +# according to the eviction policy selected (see maxmemory-policy). +# +# If Redis can't remove keys according to the policy, or if the policy is +# set to 'noeviction', Redis will start to reply with errors to commands +# that would use more memory, like SET, LPUSH, and so on, and will continue +# to reply to read-only commands like GET. +# +# This option is usually useful when using Redis as an LRU or LFU cache, or to +# set a hard memory limit for an instance (using the 'noeviction' policy). +# +# WARNING: If you have replicas attached to an instance with maxmemory on, +# the size of the output buffers needed to feed the replicas are subtracted +# from the used memory count, so that network problems / resyncs will +# not trigger a loop where keys are evicted, and in turn the output +# buffer of replicas is full with DELs of keys evicted triggering the deletion +# of more keys, and so forth until the database is completely emptied. +# +# In short... if you have replicas attached it is suggested that you set a lower +# limit for maxmemory so that there is some free RAM on the system for replica +# output buffers (but this is not needed if the policy is 'noeviction'). +# +# maxmemory + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached. You can select one from the following behaviors: +# +# volatile-lru -> Evict using approximated LRU, only keys with an expire set. +# allkeys-lru -> Evict any key using approximated LRU. +# volatile-lfu -> Evict using approximated LFU, only keys with an expire set. +# allkeys-lfu -> Evict any key using approximated LFU. +# volatile-random -> Remove a random key having an expire set. +# allkeys-random -> Remove a random key, any key. +# volatile-ttl -> Remove the key with the nearest expire time (minor TTL) +# noeviction -> Don't evict anything, just return an error on write operations. +# +# LRU means Least Recently Used +# LFU means Least Frequently Used +# +# Both LRU, LFU and volatile-ttl are implemented using approximated +# randomized algorithms. +# +# Note: with any of the above policies, Redis will return an error on write +# operations, when there are no suitable keys for eviction. +# +# At the date of writing these commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy noeviction + +# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can tune it for speed or +# accuracy. For default Redis will check five keys and pick the one that was +# used less recently, you can change the sample size using the following +# configuration directive. +# +# The default of 5 produces good enough results. 10 Approximates very closely +# true LRU but costs more CPU. 3 is faster but not very accurate. +# +# maxmemory-samples 5 + +# Starting from Redis 5, by default a replica will ignore its maxmemory setting +# (unless it is promoted to master after a failover or manually). It means +# that the eviction of keys will be just handled by the master, sending the +# DEL commands to the replica as keys evict in the master side. +# +# This behavior ensures that masters and replicas stay consistent, and is usually +# what you want, however if your replica is writable, or you want the replica +# to have a different memory setting, and you are sure all the writes performed +# to the replica are idempotent, then you may change this default (but be sure +# to understand what you are doing). +# +# Note that since the replica by default does not evict, it may end using more +# memory than the one set via maxmemory (there are certain buffers that may +# be larger on the replica, or data structures may sometimes take more memory +# and so forth). So make sure you monitor your replicas and make sure they +# have enough memory to never hit a real out-of-memory condition before the +# master hits the configured maxmemory setting. +# +# replica-ignore-maxmemory yes + +# Redis reclaims expired keys in two ways: upon access when those keys are +# found to be expired, and also in background, in what is called the +# "active expire key". The key space is slowly and interactively scanned +# looking for expired keys to reclaim, so that it is possible to free memory +# of keys that are expired and will never be accessed again in a short time. +# +# The default effort of the expire cycle will try to avoid having more than +# ten percent of expired keys still in memory, and will try to avoid consuming +# more than 25% of total memory and to add latency to the system. However +# it is possible to increase the expire "effort" that is normally set to +# "1", to a greater value, up to the value "10". At its maximum value the +# system will use more CPU, longer cycles (and technically may introduce +# more latency), and will tollerate less already expired keys still present +# in the system. It's a tradeoff betweeen memory, CPU and latecy. +# +# active-expire-effort 1 + +############################# LAZY FREEING #################################### + +# Redis has two primitives to delete keys. One is called DEL and is a blocking +# deletion of the object. It means that the server stops processing new commands +# in order to reclaim all the memory associated with an object in a synchronous +# way. If the key deleted is associated with a small object, the time needed +# in order to execute the DEL command is very small and comparable to most other +# O(1) or O(log_N) commands in Redis. However if the key is associated with an +# aggregated value containing millions of elements, the server can block for +# a long time (even seconds) in order to complete the operation. +# +# For the above reasons Redis also offers non blocking deletion primitives +# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and +# FLUSHDB commands, in order to reclaim memory in background. Those commands +# are executed in constant time. Another thread will incrementally free the +# object in the background as fast as possible. +# +# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. +# It's up to the design of the application to understand when it is a good +# idea to use one or the other. However the Redis server sometimes has to +# delete keys or flush the whole database as a side effect of other operations. +# Specifically Redis deletes objects independently of a user call in the +# following scenarios: +# +# 1) On eviction, because of the maxmemory and maxmemory policy configurations, +# in order to make room for new data, without going over the specified +# memory limit. +# 2) Because of expire: when a key with an associated time to live (see the +# EXPIRE command) must be deleted from memory. +# 3) Because of a side effect of a command that stores data on a key that may +# already exist. For example the RENAME command may delete the old key +# content when it is replaced with another one. Similarly SUNIONSTORE +# or SORT with STORE option may delete existing keys. The SET command +# itself removes any old content of the specified key in order to replace +# it with the specified string. +# 4) During replication, when a replica performs a full resynchronization with +# its master, the content of the whole database is removed in order to +# load the RDB file just transferred. +# +# In all the above cases the default is to delete objects in a blocking way, +# like if DEL was called. However you can configure each case specifically +# in order to instead release memory in a non-blocking way like if UNLINK +# was called, using the following configuration directives. + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +# It is also possible, for the case when to replace the user code DEL calls +# with UNLINK calls is not easy, to modify the default behavior of the DEL +# command to act exactly like UNLINK, using the following configuration +# directive: + +lazyfree-lazy-user-del no + +################################ THREADED I/O ################################# + +# Redis is mostly single threaded, however there are certain threaded +# operations such as UNLINK, slow I/O accesses and other things that are +# performed on side threads. +# +# Now it is also possible to handle Redis clients socket reads and writes +# in different I/O threads. Since especially writing is so slow, normally +# Redis users use pipelining in order to speedup the Redis performances per +# core, and spawn multiple instances in order to scale more. Using I/O +# threads it is possible to easily speedup two times Redis without resorting +# to pipelining nor sharding of the instance. +# +# By default threading is disabled, we suggest enabling it only in machines +# that have at least 4 or more cores, leaving at least one spare core. +# Using more than 8 threads is unlikely to help much. We also recommend using +# threaded I/O only if you actually have performance problems, with Redis +# instances being able to use a quite big percentage of CPU time, otherwise +# there is no point in using this feature. +# +# So for instance if you have a four cores boxes, try to use 2 or 3 I/O +# threads, if you have a 8 cores, try to use 6 threads. In order to +# enable I/O threads use the following configuration directive: +# +# io-threads 4 +# +# Setting io-threads to 1 will just use the main thread as usually. +# When I/O threads are enabled, we only use threads for writes, that is +# to thread the write(2) syscall and transfer the client buffers to the +# socket. However it is also possible to enable threading of reads and +# protocol parsing using the following configuration directive, by setting +# it to yes: +# +# io-threads-do-reads no +# +# Usually threading reads doesn't help much. +# +# NOTE 1: This configuration directive cannot be changed at runtime via +# CONFIG SET. Aso this feature currently does not work when SSL is +# enabled. +# +# NOTE 2: If you want to test the Redis speedup using redis-benchmark, make +# sure you also run the benchmark itself in threaded mode, using the +# --threads option to match the number of Redis theads, otherwise you'll not +# be able to notice the improvements. + +############################ KERNEL OOM CONTROL ############################## + +# On Linux, it is possible to hint the kernel OOM killer on what processes +# should be killed first when out of memory. +# +# Enabling this feature makes Redis actively control the oom_score_adj value +# for all its processes, depending on their role. The default scores will +# attempt to have background child processes killed before all others, and +# replicas killed before masters. + +oom-score-adj no + +# When oom-score-adj is used, this directive controls the specific values used +# for master, replica and background child processes. Values range -1000 to +# 1000 (higher means more likely to be killed). +# +# Unprivileged processes (not root, and without CAP_SYS_RESOURCE capabilities) +# can freely increase their value, but not decrease it below its initial +# settings. +# +# Values are used relative to the initial value of oom_score_adj when the server +# starts. Because typically the initial value is 0, they will often match the +# absolute values. + +oom-score-adj-values 0 200 800 + +############################## APPEND ONLY MODE ############################### + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check http://redis.io/topics/persistence for more information. + +appendonly no + +# The name of the append only file (default: "appendonly.aof") + +appendfilename "appendonly.aof" + +# The fsync() call tells the Operating System to actually write data on disk +# instead of waiting for more data in the output buffer. Some OS will really flush +# data on disk, some other OS will just try to do it ASAP. +# +# Redis supports three different modes: +# +# no: don't fsync, just let the OS flush the data when it wants. Faster. +# always: fsync after every write to the append only log. Slow, Safest. +# everysec: fsync only one time every second. Compromise. +# +# The default is "everysec", as that's usually the right compromise between +# speed and data safety. It's up to you to understand if you can relax this to +# "no" that will let the operating system flush the output buffer when +# it wants, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting), +# or on the contrary, use "always" that's very slow but a bit safer than +# everysec. +# +# More details please check the following article: +# http://antirez.com/post/redis-persistence-demystified.html +# +# If unsure, use "everysec". + +# appendfsync always +appendfsync everysec +# appendfsync no + +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. + +no-appendfsync-on-rewrite no + +# Automatic rewrite of the append only file. +# Redis is able to automatically rewrite the log file implicitly calling +# BGREWRITEAOF when the AOF log size grows by the specified percentage. +# +# This is how it works: Redis remembers the size of the AOF file after the +# latest rewrite (if no rewrite has happened since the restart, the size of +# the AOF at startup is used). +# +# This base size is compared to the current size. If the current size is +# bigger than the specified percentage, the rewrite is triggered. Also +# you need to specify a minimal size for the AOF file to be rewritten, this +# is useful to avoid rewriting the AOF file even if the percentage increase +# is reached but it is still pretty small. +# +# Specify a percentage of zero in order to disable the automatic AOF +# rewrite feature. + +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + +# When rewriting the AOF file, Redis is able to use an RDB preamble in the +# AOF file for faster rewrites and recoveries. When this option is turned +# on the rewritten AOF file is composed of two different stanzas: +# +# [RDB file][AOF tail] +# +# When loading Redis recognizes that the AOF file starts with the "REDIS" +# string and loads the prefixed RDB file, and continues loading the AOF +# tail. +aof-use-rdb-preamble yes + +################################ LUA SCRIPTING ############################### + +# Max execution time of a Lua script in milliseconds. +# +# If the maximum execution time is reached Redis will log that a script is +# still in execution after the maximum allowed time and will start to +# reply to queries with an error. +# +# When a long running script exceeds the maximum execution time only the +# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be +# used to stop a script that did not yet called write commands. The second +# is the only way to shut down the server in the case a write command was +# already issued by the script but the user doesn't want to wait for the natural +# termination of the script. +# +# Set it to 0 or a negative value for unlimited execution without warnings. +lua-time-limit 5000 + +################################ REDIS CLUSTER ############################### + +# Normal Redis instances can't be part of a Redis Cluster; only nodes that are +# started as cluster nodes can. In order to start a Redis instance as a +# cluster node enable the cluster support uncommenting the following: +# +# cluster-enabled yes + +# Every cluster node has a cluster configuration file. This file is not +# intended to be edited by hand. It is created and updated by Redis nodes. +# Every Redis Cluster node requires a different cluster configuration file. +# Make sure that instances running in the same system do not have +# overlapping cluster configuration file names. +# +# cluster-config-file nodes-6379.conf + +# Cluster node timeout is the amount of milliseconds a node must be unreachable +# for it to be considered in failure state. +# Most other internal time limits are multiple of the node timeout. +# +# cluster-node-timeout 15000 + +# A replica of a failing master will avoid to start a failover if its data +# looks too old. +# +# There is no simple way for a replica to actually have an exact measure of +# its "data age", so the following two checks are performed: +# +# 1) If there are multiple replicas able to failover, they exchange messages +# in order to try to give an advantage to the replica with the best +# replication offset (more data from the master processed). +# Replicas will try to get their rank by offset, and apply to the start +# of the failover a delay proportional to their rank. +# +# 2) Every single replica computes the time of the last interaction with +# its master. This can be the last ping or command received (if the master +# is still in the "connected" state), or the time that elapsed since the +# disconnection with the master (if the replication link is currently down). +# If the last interaction is too old, the replica will not try to failover +# at all. +# +# The point "2" can be tuned by user. Specifically a replica will not perform +# the failover if, since the last interaction with the master, the time +# elapsed is greater than: +# +# (node-timeout * replica-validity-factor) + repl-ping-replica-period +# +# So for example if node-timeout is 30 seconds, and the replica-validity-factor +# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the +# replica will not try to failover if it was not able to talk with the master +# for longer than 310 seconds. +# +# A large replica-validity-factor may allow replicas with too old data to failover +# a master, while a too small value may prevent the cluster from being able to +# elect a replica at all. +# +# For maximum availability, it is possible to set the replica-validity-factor +# to a value of 0, which means, that replicas will always try to failover the +# master regardless of the last time they interacted with the master. +# (However they'll always try to apply a delay proportional to their +# offset rank). +# +# Zero is the only value able to guarantee that when all the partitions heal +# the cluster will always be able to continue. +# +# cluster-replica-validity-factor 10 + +# Cluster replicas are able to migrate to orphaned masters, that are masters +# that are left without working replicas. This improves the cluster ability +# to resist to failures as otherwise an orphaned master can't be failed over +# in case of failure if it has no working replicas. +# +# Replicas migrate to orphaned masters only if there are still at least a +# given number of other working replicas for their old master. This number +# is the "migration barrier". A migration barrier of 1 means that a replica +# will migrate only if there is at least 1 other working replica for its master +# and so forth. It usually reflects the number of replicas you want for every +# master in your cluster. +# +# Default is 1 (replicas migrate only if their masters remain with at least +# one replica). To disable migration just set it to a very large value. +# A value of 0 can be set but is useful only for debugging and dangerous +# in production. +# +# cluster-migration-barrier 1 + +# By default Redis Cluster nodes stop accepting queries if they detect there +# is at least an hash slot uncovered (no available node is serving it). +# This way if the cluster is partially down (for example a range of hash slots +# are no longer covered) all the cluster becomes, eventually, unavailable. +# It automatically returns available as soon as all the slots are covered again. +# +# However sometimes you want the subset of the cluster which is working, +# to continue to accept queries for the part of the key space that is still +# covered. In order to do so, just set the cluster-require-full-coverage +# option to no. +# +# cluster-require-full-coverage yes + +# This option, when set to yes, prevents replicas from trying to failover its +# master during master failures. However the master can still perform a +# manual failover, if forced to do so. +# +# This is useful in different scenarios, especially in the case of multiple +# data center operations, where we want one side to never be promoted if not +# in the case of a total DC failure. +# +# cluster-replica-no-failover no + +# This option, when set to yes, allows nodes to serve read traffic while the +# the cluster is in a down state, as long as it believes it owns the slots. +# +# This is useful for two cases. The first case is for when an application +# doesn't require consistency of data during node failures or network partitions. +# One example of this is a cache, where as long as the node has the data it +# should be able to serve it. +# +# The second use case is for configurations that don't meet the recommended +# three shards but want to enable cluster mode and scale later. A +# master outage in a 1 or 2 shard configuration causes a read/write outage to the +# entire cluster without this option set, with it set there is only a write outage. +# Without a quorum of masters, slot ownership will not change automatically. +# +# cluster-allow-reads-when-down no + +# In order to setup your cluster make sure to read the documentation +# available at http://redis.io web site. + +########################## CLUSTER DOCKER/NAT support ######################## + +# In certain deployments, Redis Cluster nodes address discovery fails, because +# addresses are NAT-ted or because ports are forwarded (the typical case is +# Docker and other containers). +# +# In order to make Redis Cluster working in such environments, a static +# configuration where each node knows its public address is needed. The +# following two options are used for this scope, and are: +# +# * cluster-announce-ip +# * cluster-announce-port +# * cluster-announce-bus-port +# +# Each instruct the node about its address, client port, and cluster message +# bus port. The information is then published in the header of the bus packets +# so that other nodes will be able to correctly map the address of the node +# publishing the information. +# +# If the above options are not used, the normal Redis Cluster auto-detection +# will be used instead. +# +# Note that when remapped, the bus port may not be at the fixed offset of +# clients port + 10000, so you can specify any port and bus-port depending +# on how they get remapped. If the bus-port is not set, a fixed offset of +# 10000 will be used as usually. +# +# Example: +# +# cluster-announce-ip 10.1.1.5 +# cluster-announce-port 6379 +# cluster-announce-bus-port 6380 + +################################## SLOW LOG ################################### + +# The Redis Slow Log is a system to log queries that exceeded a specified +# execution time. The execution time does not include the I/O operations +# like talking with the client, sending the reply and so forth, +# but just the time needed to actually execute the command (this is the only +# stage of command execution where the thread is blocked and can not serve +# other requests in the meantime). +# +# You can configure the slow log with two parameters: one tells Redis +# what is the execution time, in microseconds, to exceed in order for the +# command to get logged, and the other parameter is the length of the +# slow log. When a new command is logged the oldest one is removed from the +# queue of logged commands. + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +################################ LATENCY MONITOR ############################## + +# The Redis latency monitoring subsystem samples different operations +# at runtime in order to collect data related to possible sources of +# latency of a Redis instance. +# +# Via the LATENCY command this information is available to the user that can +# print graphs and obtain reports. +# +# The system only logs operations that were performed in a time equal or +# greater than the amount of milliseconds specified via the +# latency-monitor-threshold configuration directive. When its value is set +# to zero, the latency monitor is turned off. +# +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold " if needed. +latency-monitor-threshold 0 + +############################# EVENT NOTIFICATION ############################## + +# Redis can notify Pub/Sub clients about events happening in the key space. +# This feature is documented at http://redis.io/topics/notifications +# +# For instance if keyspace events notification is enabled, and a client +# performs a DEL operation on key "foo" stored in the Database 0, two +# messages will be published via Pub/Sub: +# +# PUBLISH __keyspace@0__:foo del +# PUBLISH __keyevent@0__:del foo +# +# It is possible to select the events that Redis will notify among a set +# of classes. Every class is identified by a single character: +# +# K Keyspace events, published with __keyspace@__ prefix. +# E Keyevent events, published with __keyevent@__ prefix. +# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... +# $ String commands +# l List commands +# s Set commands +# h Hash commands +# z Sorted set commands +# x Expired events (events generated every time a key expires) +# e Evicted events (events generated when a key is evicted for maxmemory) +# t Stream commands +# m Key-miss events (Note: It is not included in the 'A' class) +# A Alias for g$lshzxet, so that the "AKE" string means all the events +# (Except key-miss events which are excluded from 'A' due to their +# unique nature). +# +# The "notify-keyspace-events" takes as argument a string that is composed +# of zero or multiple characters. The empty string means that notifications +# are disabled. +# +# Example: to enable list and generic events, from the point of view of the +# event name, use: +# +# notify-keyspace-events Elg +# +# Example 2: to get the stream of the expired keys subscribing to channel +# name __keyevent@0__:expired use: +# +# notify-keyspace-events Ex +# +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +############################### GOPHER SERVER ################################# + +# Redis contains an implementation of the Gopher protocol, as specified in +# the RFC 1436 (https://www.ietf.org/rfc/rfc1436.txt). +# +# The Gopher protocol was very popular in the late '90s. It is an alternative +# to the web, and the implementation both server and client side is so simple +# that the Redis server has just 100 lines of code in order to implement this +# support. +# +# What do you do with Gopher nowadays? Well Gopher never *really* died, and +# lately there is a movement in order for the Gopher more hierarchical content +# composed of just plain text documents to be resurrected. Some want a simpler +# internet, others believe that the mainstream internet became too much +# controlled, and it's cool to create an alternative space for people that +# want a bit of fresh air. +# +# Anyway for the 10nth birthday of the Redis, we gave it the Gopher protocol +# as a gift. +# +# --- HOW IT WORKS? --- +# +# The Redis Gopher support uses the inline protocol of Redis, and specifically +# two kind of inline requests that were anyway illegal: an empty request +# or any request that starts with "/" (there are no Redis commands starting +# with such a slash). Normal RESP2/RESP3 requests are completely out of the +# path of the Gopher protocol implementation and are served as usually as well. +# +# If you open a connection to Redis when Gopher is enabled and send it +# a string like "/foo", if there is a key named "/foo" it is served via the +# Gopher protocol. +# +# In order to create a real Gopher "hole" (the name of a Gopher site in Gopher +# talking), you likely need a script like the following: +# +# https://github.com/antirez/gopher2redis +# +# --- SECURITY WARNING --- +# +# If you plan to put Redis on the internet in a publicly accessible address +# to server Gopher pages MAKE SURE TO SET A PASSWORD to the instance. +# Once a password is set: +# +# 1. The Gopher server (when enabled, not by default) will still serve +# content via Gopher. +# 2. However other commands cannot be called before the client will +# authenticate. +# +# So use the 'requirepass' option to protect your instance. +# +# To enable Gopher support uncomment the following line and set +# the option from no (the default) to yes. +# +# gopher-enabled no + +############################### ADVANCED CONFIG ############################### + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +list-max-ziplist-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When an HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entires limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# The limit can be set differently for the three different classes of clients: +# +# normal -> normal clients including MONITOR clients +# replica -> replica clients +# pubsub -> clients subscribed to at least one pubsub channel or pattern +# +# The syntax of every client-output-buffer-limit directive is the following: +# +# client-output-buffer-limit +# +# A client is immediately disconnected once the hard limit is reached, or if +# the soft limit is reached and remains reached for the specified number of +# seconds (continuously). +# So for instance if the hard limit is 32 megabytes and the soft limit is +# 16 megabytes / 10 seconds, the client will get disconnected immediately +# if the size of the output buffers reach 32 megabytes, but will also get +# disconnected if the client reaches 16 megabytes and continuously overcomes +# the limit for 10 seconds. +# +# By default normal clients are not limited because they don't receive data +# without asking (in a push way), but just after a request, so only +# asynchronous clients may create a scenario where data is requested faster +# than it can read. +# +# Instead there is a default limit for pubsub and replica clients, since +# subscribers and replicas receive data in a push fashion. +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here, but must be 1mb or greater +# +# proto-max-bulk-len 512mb + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# Normally it is useful to have an HZ value which is proportional to the +# number of clients connected. This is useful in order, for instance, to +# avoid too many clients are processed for each background task invocation +# in order to avoid latency spikes. +# +# Since the default HZ value by default is conservatively set to 10, Redis +# offers, and enables by default, the ability to use an adaptive HZ value +# which will temporary raise when there are many connected clients. +# +# When dynamic HZ is enabled, the actual configured HZ will be used +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good +# idea to start with the default settings and only change them after investigating +# how to improve the performances and how the keys LFU change over time, which +# is possible to inspect via the OBJECT FREQ command. +# +# There are two tunable parameters in the Redis LFU implementation: the +# counter logarithm factor and the counter decay time. It is important to +# understand what the two parameters mean before changing them. +# +# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis +# uses a probabilistic increment with logarithmic behavior. Given the value +# of the old counter, when a key is accessed, the counter is incremented in +# this way: +# +# 1. A random number R between 0 and 1 is extracted. +# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). +# 3. The counter is incremented only if R < P. +# +# The default lfu-log-factor is 10. This is a table of how the frequency +# counter changes with a different number of accesses with different +# logarithmic factors: +# +# +--------+------------+------------+------------+------------+------------+ +# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | +# +--------+------------+------------+------------+------------+------------+ +# | 0 | 104 | 255 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 1 | 18 | 49 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 10 | 10 | 18 | 142 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 100 | 8 | 11 | 49 | 143 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# +# NOTE: The above table was obtained by running the following commands: +# +# redis-benchmark -n 1000000 incr foo +# redis-cli object freq foo +# +# NOTE 2: The counter initial value is 5 in order to give new objects a chance +# to accumulate hits. +# +# The counter decay time is the time, in minutes, that must elapse in order +# for the key counter to be divided by two (or decremented if it has a value +# less <= 10). +# +# The default value for the lfu-decay-time is 1. A Special value of 0 means to +# decay the counter every time it happens to be scanned. +# +# lfu-log-factor 10 +# lfu-decay-time 1 + +########################### ACTIVE DEFRAGMENTATION ####################### +# +# What is active defragmentation? +# ------------------------------- +# +# Active (online) defragmentation allows a Redis server to compact the +# spaces left between small allocations and deallocations of data in memory, +# thus allowing to reclaim back memory. +# +# Fragmentation is a natural process that happens with every allocator (but +# less so with Jemalloc, fortunately) and certain workloads. Normally a server +# restart is needed in order to lower the fragmentation, or at least to flush +# away all the data and create it again. However thanks to this feature +# implemented by Oran Agra for Redis 4.0 this process can happen at runtime +# in an "hot" way, while the server is running. +# +# Basically when the fragmentation is over a certain level (see the +# configuration options below) Redis will start to create new copies of the +# values in contiguous memory regions by exploiting certain specific Jemalloc +# features (in order to understand if an allocation is causing fragmentation +# and to allocate it in a better place), and at the same time, will release the +# old copies of the data. This process, repeated incrementally for all the keys +# will cause the fragmentation to drop back to normal values. +# +# Important things to understand: +# +# 1. This feature is disabled by default, and only works if you compiled Redis +# to use the copy of Jemalloc we ship with the source code of Redis. +# This is the default with Linux builds. +# +# 2. You never need to enable this feature if you don't have fragmentation +# issues. +# +# 3. Once you experience fragmentation, you can enable this feature when +# needed with the command "CONFIG SET activedefrag yes". +# +# The configuration parameters are able to fine tune the behavior of the +# defragmentation process. If you are not sure about what they mean it is +# a good idea to leave the defaults untouched. + +# Enabled active defragmentation +# activedefrag no + +# Minimum amount of fragmentation waste to start active defrag +# active-defrag-ignore-bytes 100mb + +# Minimum percentage of fragmentation to start active defrag +# active-defrag-threshold-lower 10 + +# Maximum percentage of fragmentation at which we use maximum effort +# active-defrag-threshold-upper 100 + +# Minimal effort for defrag in CPU percentage, to be used when the lower +# threshold is reached +# active-defrag-cycle-min 1 + +# Maximal effort for defrag in CPU percentage, to be used when the upper +# threshold is reached +# active-defrag-cycle-max 25 + +# Maximum number of set/hash/zset/list fields that will be processed from +# the main dictionary scan +# active-defrag-max-scan-fields 1000 + +# Jemalloc background thread for purging will be enabled by default +jemalloc-bg-thread yes + +# It is possible to pin different threads and processes of Redis to specific +# CPUs in your system, in order to maximize the performances of the server. +# This is useful both in order to pin different Redis threads in different +# CPUs, but also in order to make sure that multiple Redis instances running +# in the same host will be pinned to different CPUs. +# +# Normally you can do this using the "taskset" command, however it is also +# possible to this via Redis configuration directly, both in Linux and FreeBSD. +# +# You can pin the server/IO threads, bio threads, aof rewrite child process, and +# the bgsave child process. The syntax to specify the cpu list is the same as +# the taskset command: +# +# Set redis server/io threads to cpu affinity 0,2,4,6: +# server_cpulist 0-7:2 +# +# Set bio threads to cpu affinity 1,3: +# bio_cpulist 1,3 +# +# Set aof rewrite child process to cpu affinity 8,9,10,11: +# aof_rewrite_cpulist 8-11 +# +# Set bgsave child process to cpu affinity 1,10,11 +# bgsave_cpulist 1,10-11 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..95fae6e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,41 @@ +version: "3" +services: + db: + image: postgres:latest + container_name: postgres_db + ports: + - "5433:5432" + volumes: + - ~/WorkSpace/postgres/yapp/data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=1234 + privileged: true + +# pgadmin db연결 시, 포워딩한 포트가 아닌 원래포트 사용해야 함 + pgadmin: + image: dpage/pgadmin4 + container_name: pgadmin + ports: + - "5434:80" + volumes: + - ~/WorkSpace/pgadmin/yapp/data:/var/lib/pgadmin + environment: + - PGADMIN_DEFAULT_EMAIL=yappml@pgadmin.com + - PGADMIN_DEFAULT_PASSWORD=1234 + privileged: true + + redis: + image: redis:latest + container_name: redis_db + ports: + - "6000:6379" + volumes: + - ./config/redis:/usr/local/etc/redis + - ~/WorkSpace/redis/yapp/data:/data + environment: + - TZ=Asia/Seoul + command: redis-server /usr/local/etc/redis/redis.conf + restart: always + privileged: true + From 4c444fe1b900574ec1c27e5ca76f14f8ee1cf594 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:29:26 +0900 Subject: [PATCH 012/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20user=20crud=20?= =?UTF-8?q?=EB=B0=8F=20=ED=95=84=EC=9A=94=20=EB=A1=9C=EC=A7=81=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 필요로직 -> findByEmail --- app/crud/__init__.py | 1 + app/crud/user.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 app/crud/user.py diff --git a/app/crud/__init__.py b/app/crud/__init__.py index e47c4c5..e290738 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1 +1,2 @@ from app.crud.product import product +from app.crud.user import user \ No newline at end of file diff --git a/app/crud/user.py b/app/crud/user.py new file mode 100644 index 0000000..c7c57ca --- /dev/null +++ b/app/crud/user.py @@ -0,0 +1,16 @@ +from typing import Optional, List + +from sqlalchemy.orm import Session + +from app.crud.base import CRUDBase +from app.models import User +from app.schemas import UserCreate, UserUpdate + + +class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]): + # Declare model specific CRUD operation methods. + def get_one_by_email(self, db: Session, email: str): + return db.query(User).filter(User.social_id == email).first() + + +user = CRUDUser(User) From a20308c46eed11c507bc7b29d2daa475a6ef5c27 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:30:04 +0900 Subject: [PATCH 013/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20Provider=20enu?= =?UTF-8?q?m=20type=20String=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/user/provider.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/user/provider.py b/app/models/user/provider.py index 5c59ec6..432dc52 100644 --- a/app/models/user/provider.py +++ b/app/models/user/provider.py @@ -1,6 +1,6 @@ import enum -class Provider(enum.Enum): - GOOGLE = 1 - FACEBOOK = 2 +class Provider(str, enum.Enum): + GOOGLE = 'google' + FACEBOOK = 'facebook' From ad9ba4988150204c1feba7311ed8dd308d5ff268 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:31:08 +0900 Subject: [PATCH 014/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20user=20route?= =?UTF-8?q?=20service=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit proto 버전 -> 개발 방향성 논의 이후 변경 --- app/api/__init__.py | 7 +++++++ app/api/users.py | 51 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 app/api/users.py diff --git a/app/api/__init__.py b/app/api/__init__.py index e69de29..f702921 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -0,0 +1,7 @@ +from fastapi import APIRouter + +from app.api import users + +user_router = APIRouter() + +user_router.include_router(users.router, tags=["users"]) diff --git a/app/api/users.py b/app/api/users.py new file mode 100644 index 0000000..8a9eb94 --- /dev/null +++ b/app/api/users.py @@ -0,0 +1,51 @@ +from datetime import timedelta +from typing import Optional + +from fastapi import APIRouter, Depends, Header, HTTPException, Response +from jose import JWTError +from sqlalchemy import null +from sqlalchemy.orm import Session + +from app import schemas, crud +from app.api.deps import get_db +from app.schemas import UserResponse +from app.service.user import auth +from app.core import settings + +router = APIRouter() + + +@router.post("/signup", response_model=UserResponse) +def sign_up(*, db: Session = Depends(get_db), user_in: schemas.UserCreate, authorization: Optional[str] = Header(None)): + if auth.check_access_token_valid(__get_token_in_header(authorization)): + user = crud.user.create(db, obj_in=user_in) + return user + else: + raise HTTPException(status_code=401, detail='Invalid token') + + +@router.get("/signin", response_model=UserResponse) +def sign_in(*, db: Session = Depends(get_db), + response: Response, + authorization: Optional[str] = Header(None) + ): + try: + email = auth.auth_google_token(__get_token_in_header(authorization)) + except JWTError: + raise HTTPException(status_code=401, detail="Invalid Token") + + user = crud.user.get_one_by_email(db, email) + + if user is None: + raise HTTPException(status_code=404, detail="user(email: " + email + ") not exist.") + + token = auth.create_access_token({"sub": user.social_id}, timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)) + + response.headers["Authorization"] = 'bearer ' + token + + return user + + +def __get_token_in_header(header: str) -> str: + # bearer gkwlfnbnklvjbopw.wegwedvkls.234352ewfdsv + return header.split(" ")[1] From 3f9cb464c9346fdb21a92d43cf16b3491925f9fc Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:32:20 +0900 Subject: [PATCH 015/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20User=20Schema?= =?UTF-8?q?=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/__init__.py | 1 + app/schemas/user.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 app/schemas/user.py diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index fb3c44b..659d1b0 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,2 +1,3 @@ from app.schemas.message import Message from app.schemas.product import ProductBase, ProductCreate, ProductUpdate, ProductResponse +from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse \ No newline at end of file diff --git a/app/schemas/user.py b/app/schemas/user.py new file mode 100644 index 0000000..e4ed682 --- /dev/null +++ b/app/schemas/user.py @@ -0,0 +1,27 @@ +import enum +from typing import Optional + +from pydantic import BaseModel + + +class UserBase(BaseModel): + id: Optional[int] + provider: Optional[str] + social_id: Optional[str] + nickname: Optional[str] + + +class UserCreate(UserBase): + provider: str + social_id: str + nickname: str + + +class UserUpdate(UserBase): + id: int + pass + + +class UserResponse(UserBase): + class Config: + orm_mode = True From 075ab98b650dba2080066bcd36c46c5c35b1748a Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:32:55 +0900 Subject: [PATCH 016/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20auth=5Fgoogle?= =?UTF-8?q?=5Ftoken=20status=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/user/auth.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/service/user/auth.py b/app/service/user/auth.py index 92c9b28..02f4d3e 100644 --- a/app/service/user/auth.py +++ b/app/service/user/auth.py @@ -2,6 +2,7 @@ from typing import Optional import requests +from fastapi import HTTPException from jose import jwt, JWTError from app.core import settings @@ -19,7 +20,13 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): def auth_google_token(token: str): - return requests.get("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + token) + result = requests.get("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + token) + + if result.status_code == 200: + return result.json()["email"] + + else: + raise JWTError def check_access_token_valid(token: str): From 21871060c83fe1ec5def93dc76af488b2413d380 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:33:49 +0900 Subject: [PATCH 017/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20user=20api=20/?= =?UTF-8?q?=20token=20expire=20time=20config=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/core/config.py b/app/core/config.py index 47cacf9..bf0030e 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -5,10 +5,12 @@ class Settings(BaseSettings): API_V1_STR: str = "/api/v1" + API_USER: str = "/api/user" PROJECT_NAME: str = "FastAPI" SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/fastapi_db" ALGORITHM = "HS256" + ACCESS_TOKEN_EXPIRE_MINUTES = 30 class Config: env_file = ".env" From 1822e604f3e54574224e3d1448abceb1161b60d6 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 14:34:02 +0900 Subject: [PATCH 018/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=EC=82=AC=ED=95=AD=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/database/base.py | 1 + app/main.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/database/base.py b/app/database/base.py index 3f25dd6..609e64d 100644 --- a/app/database/base.py +++ b/app/database/base.py @@ -1,2 +1,3 @@ from app.database.base_class import Base from app.models.product import Product +from app.models.user.user import User \ No newline at end of file diff --git a/app/main.py b/app/main.py index df384be..b6d96d8 100644 --- a/app/main.py +++ b/app/main.py @@ -3,11 +3,13 @@ from fastapi import FastAPI from app.api.v1 import api_router +from app.api import user_router from app.core import settings app = FastAPI(title=settings.PROJECT_NAME) app.include_router(api_router, prefix=settings.API_V1_STR) +app.include_router(user_router, prefix=settings.API_USER) if __name__ == "__main__": - uvicorn.run(app, host="0.0.0.0", port=8000) + uvicorn.run(app, host="0.0.0.0", port=8001) From 188096057da07f9a339bbceb1dd7b66601938919 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 18:28:29 +0900 Subject: [PATCH 019/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20user=20model?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/user/user.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/models/user/user.py b/app/models/user/user.py index fb494b2..5fdba44 100644 --- a/app/models/user/user.py +++ b/app/models/user/user.py @@ -1,7 +1,12 @@ -from sqlalchemy import Column, Integer, Float, Enum, String +import enum +from sqlalchemy import Column, Integer, Enum, String from app.database.base_class import Base -from app.models.user.provider import Provider + + +class Provider(str, enum.Enum): + GOOGLE = 'google' + FACEBOOK = 'facebook' class User(Base): From 53fec7f4b24c6fc15a46aabb307f5761ec616310 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 9 May 2021 18:28:43 +0900 Subject: [PATCH 020/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20router=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 25 +++++++++++++------------ app/service/{user => }/auth.py | 23 ++++++++++++++++++++--- 2 files changed, 33 insertions(+), 15 deletions(-) rename app/service/{user => }/auth.py (61%) diff --git a/app/api/users.py b/app/api/users.py index 8a9eb94..1383248 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -1,23 +1,26 @@ +import logging from datetime import timedelta from typing import Optional from fastapi import APIRouter, Depends, Header, HTTPException, Response +from fastapi.logger import logger from jose import JWTError -from sqlalchemy import null from sqlalchemy.orm import Session from app import schemas, crud from app.api.deps import get_db from app.schemas import UserResponse -from app.service.user import auth +from app.service import auth from app.core import settings +from app.service.auth import get_token_in_header router = APIRouter() @router.post("/signup", response_model=UserResponse) def sign_up(*, db: Session = Depends(get_db), user_in: schemas.UserCreate, authorization: Optional[str] = Header(None)): - if auth.check_access_token_valid(__get_token_in_header(authorization)): + jwt = get_token_in_header(authorization) + if auth.check_access_token_valid(jwt): user = crud.user.create(db, obj_in=user_in) return user else: @@ -30,22 +33,20 @@ def sign_in(*, db: Session = Depends(get_db), authorization: Optional[str] = Header(None) ): try: - email = auth.auth_google_token(__get_token_in_header(authorization)) + email = auth.auth_google_token(get_token_in_header(authorization)) except JWTError: raise HTTPException(status_code=401, detail="Invalid Token") user = crud.user.get_one_by_email(db, email) - if user is None: - raise HTTPException(status_code=404, detail="user(email: " + email + ") not exist.") + token = auth.create_access_token({"sub": email}, timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)) - token = auth.create_access_token({"sub": user.social_id}, timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)) + if user is None: + raise HTTPException(status_code=404, + detail="user(email: " + email + ") not exist.", + headers={"Authorization": 'bearer ' + token} + ) response.headers["Authorization"] = 'bearer ' + token return user - - -def __get_token_in_header(header: str) -> str: - # bearer gkwlfnbnklvjbopw.wegwedvkls.234352ewfdsv - return header.split(" ")[1] diff --git a/app/service/user/auth.py b/app/service/auth.py similarity index 61% rename from app/service/user/auth.py rename to app/service/auth.py index 02f4d3e..e9efd79 100644 --- a/app/service/user/auth.py +++ b/app/service/auth.py @@ -3,7 +3,8 @@ import requests from fastapi import HTTPException -from jose import jwt, JWTError +from jose import jwt, JWTError, ExpiredSignatureError +from jose.exceptions import JWTClaimsError from app.core import settings @@ -30,8 +31,24 @@ def auth_google_token(token: str): def check_access_token_valid(token: str): - decode_token = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) - return decode_token["expires"] >= datetime.utcnow() + try: + decode_token = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) + return True + + except ExpiredSignatureError: + print("time") + return False + except JWTClaimsError: + print("claim") + return False + except JWTError: + print("jwt") + return False + + +def get_token_in_header(header: str) -> str: + # bearer gkwlfnbnklvjbopw.wegwedvkls.234352ewfdsv + return header.split(" ")[1] def check_refresh_token(param): From d573071a798b03f49b728af56ef4a1d39ba6ef87 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 17:05:57 +0900 Subject: [PATCH 021/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=EC=A0=81=EC=9D=B8=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 + .gitignore | 2 +- app/api/__init__.py | 17 ++++- app/api/study_rooms.py | 52 +++++++++++++ app/api/v1/__init__.py | 6 -- app/api/v1/products.py | 57 -------------- app/core/__init__.py | 5 +- app/core/config.py | 15 +++- app/crud/__init__.py | 12 ++- app/crud/product.py | 15 ---- app/crud/study_rooms.py | 74 +++++++++++++++++++ app/database/base.py | 3 +- app/database/session.py | 7 +- app/{tests/api/v1 => erros}/__init__.py | 0 app/erros/study_rooms/__init__.py | 1 + app/erros/study_rooms/handling.py | 28 +++++++ app/main.py | 17 ++++- app/models/__init__.py | 4 +- app/models/product.py | 9 --- app/models/study_rooms.py | 26 +++++++ app/models/users.py | 20 +++++ app/schemas/__init__.py | 11 ++- app/schemas/message.py | 5 -- app/schemas/product.py | 24 ------ app/schemas/study_rooms.py | 42 +++++++++++ app/tests/api/study_rooms.py | 54 ++++++++++++++ app/tests/api/v1/test_products.py | 35 --------- app/tests/conftest.py | 31 +++++--- .../versions/eaae517c1e2f_initialise.py | 35 --------- requirements.txt | 21 ++++++ 30 files changed, 413 insertions(+), 218 deletions(-) create mode 100644 .env create mode 100644 app/api/study_rooms.py delete mode 100644 app/api/v1/__init__.py delete mode 100644 app/api/v1/products.py delete mode 100644 app/crud/product.py create mode 100644 app/crud/study_rooms.py rename app/{tests/api/v1 => erros}/__init__.py (100%) create mode 100644 app/erros/study_rooms/__init__.py create mode 100644 app/erros/study_rooms/handling.py delete mode 100644 app/models/product.py create mode 100644 app/models/study_rooms.py create mode 100644 app/models/users.py delete mode 100644 app/schemas/message.py delete mode 100644 app/schemas/product.py create mode 100644 app/schemas/study_rooms.py create mode 100644 app/tests/api/study_rooms.py delete mode 100644 app/tests/api/v1/test_products.py delete mode 100644 migrations/versions/eaae517c1e2f_initialise.py diff --git a/.env b/.env new file mode 100644 index 0000000..80d754d --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +API_V1_STR="/api/v1" +PROJECT_NAME="Studeep" +SQLALCHEMY_DATABASE_URI="postgresql://localhost:5432/studeep" diff --git a/.gitignore b/.gitignore index f5da125..0da46cd 100644 --- a/.gitignore +++ b/.gitignore @@ -152,7 +152,7 @@ Thumbs.db ### vscode ### -.vscode/* +.vscode !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json diff --git a/app/api/__init__.py b/app/api/__init__.py index f702921..31c8131 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -1,7 +1,16 @@ -from fastapi import APIRouter +from fastapi import APIRouter -from app.api import users +from app.api import users, study_rooms +from app.core import study_rooms_settings -user_router = APIRouter() -user_router.include_router(users.router, tags=["users"]) +api_router = APIRouter() +api_router.include_router( + users.router, + tags=['users'] +) +api_router.include_router( + study_rooms.router, + prefix=study_rooms_settings.API_STUDY_ROOM, + tags=['study_rooms'] +) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py new file mode 100644 index 0000000..08379c1 --- /dev/null +++ b/app/api/study_rooms.py @@ -0,0 +1,52 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm.session import Session + +from app.api.deps import get_db +from app.erros.study_rooms import CustomException +from app.crud import ( + get_study_room, + get_study_rooms, + create_study_room, + update_study_room, + delete_study_room + ) +from app.schemas import ( + StudyRoomResponse, + StudyRoomsCreate, + StudyRoomsUpdate + ) + + + +router = APIRouter() + + +@router.get('/{room_id}', response_model=StudyRoomResponse) +def get(room_id: str, db: Session = Depends(get_db)): + study_room = get_study_room(db, room_id) + if study_room: + return study_room + else: + raise CustomException(message = 'NOT_FOUND') + + +@router.patch('/{room_id}') +def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): + response = update_study_room(db, room_id, room_info) + return response + + +@router.delete('/{room_id}') +def delete(room_id: str, db: Session = Depends(get_db)): + _ = delete_study_room(db, room_id) + + +@router.get('') +def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): + response = get_study_rooms(db, skip, limit, option) + return response + + +@router.post('') +def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): + create_study_room(db, rooms) \ No newline at end of file diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py deleted file mode 100644 index c1f8349..0000000 --- a/app/api/v1/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from fastapi import APIRouter - -from app.api.v1 import products - -api_router = APIRouter() -api_router.include_router(products.router, prefix="/products", tags=["products"]) diff --git a/app/api/v1/products.py b/app/api/v1/products.py deleted file mode 100644 index 540524c..0000000 --- a/app/api/v1/products.py +++ /dev/null @@ -1,57 +0,0 @@ -from typing import Any, List - -from fastapi import APIRouter, Depends, HTTPException, status -from sqlalchemy.orm import Session - -from app import schemas, crud -from app.api.deps import get_db - -router = APIRouter() - - -@router.get("", response_model=List[schemas.ProductResponse]) -def read_products(db: Session = Depends(get_db), skip: int = 0, limit: int = 100) -> Any: - """ - Retrieve all products. - """ - products = crud.product.get_multi(db, skip=skip, limit=limit) - return products - - -@router.post("", response_model=schemas.ProductResponse) -def create_product(*, db: Session = Depends(get_db), product_in: schemas.ProductCreate) -> Any: - """ - Create new products. - """ - product = crud.product.create(db, obj_in=product_in) - return product - - -@router.put("", response_model=schemas.ProductResponse) -def update_product(*, db: Session = Depends(get_db), product_in: schemas.ProductUpdate) -> Any: - """ - Update existing products. - """ - product = crud.product.get(db, model_id=product_in.id) - if not product: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="The product with this ID does not exist in the system.", - ) - product = crud.product.update(db, db_obj=product, obj_in=product_in) - return product - - -@router.delete("", response_model=schemas.Message) -def delete_product(*, db: Session = Depends(get_db), id: int) -> Any: - """ - Delete existing product. - """ - product = crud.product.get(db, model_id=id) - if not product: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="The product with this ID does not exist in the system.", - ) - crud.product.remove(db, model_id=product.id) - return {"message": f"Product with ID = {id} deleted."} diff --git a/app/core/__init__.py b/app/core/__init__.py index 15f329a..785badc 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -1 +1,4 @@ -from app.core.config import settings +from app.core.config import ( + common_settings, + study_rooms_settings + ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index bf0030e..e6393b8 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -3,6 +3,7 @@ from pydantic import BaseSettings +<<<<<<< HEAD class Settings(BaseSettings): API_V1_STR: str = "/api/v1" API_USER: str = "/api/user" @@ -11,9 +12,21 @@ class Settings(BaseSettings): SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/fastapi_db" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 +======= +class CommonSettings(BaseSettings): + COMMON_API: str = '/api' + PROJECT_NAME: str = "studeep" + SECRET_KEY: str = secrets.token_urlsafe(32) + SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 class Config: env_file = ".env" -settings = Settings() +class StudyRoomSettings(BaseSettings): + API_STUDY_ROOM: str = '/study-rooms' + + +common_settings = CommonSettings() +study_rooms_settings = StudyRoomSettings() diff --git a/app/crud/__init__.py b/app/crud/__init__.py index e290738..2cf33f7 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,2 +1,12 @@ +<<<<<<< HEAD from app.crud.product import product -from app.crud.user import user \ No newline at end of file +from app.crud.user import user +======= +from app.crud.study_rooms import ( + get_study_room, + get_study_rooms, + create_study_room, + update_study_room, + delete_study_room + ) +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 diff --git a/app/crud/product.py b/app/crud/product.py deleted file mode 100644 index 1d77012..0000000 --- a/app/crud/product.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Optional, List - -from sqlalchemy.orm import Session - -from app.crud.base import CRUDBase -from app.models.product import Product -from app.schemas import ProductCreate, ProductUpdate - - -class CRUDProduct(CRUDBase[Product, ProductCreate, ProductUpdate]): - # Declare model specific CRUD operation methods. - pass - - -product = CRUDProduct(Product) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py new file mode 100644 index 0000000..e449d3d --- /dev/null +++ b/app/crud/study_rooms.py @@ -0,0 +1,74 @@ +from uuid import UUID +from typing import TypeVar + +from fastapi import HTTPException, status +from fastapi.encoders import jsonable_encoder +from pydantic import BaseModel +from sqlalchemy.orm import Session + +from app.models import StudyRooms +from app.schemas import StudyRoomsCreate, StudyRoomsUpdate +from app.erros.study_rooms.handling import CustomException, NotFoundHandler + + +ModelSchema = TypeVar('ModelSchema', bound=BaseModel) + + +def password_exception_handler(room_info: ModelSchema): + detail = [ + { + "loc": [ + "body", + "password" + ], + "msg": "field required", + "type": "value_error.missing" + } + ] + if (not room_info.is_public) and (not room_info.password): + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) + else: + pass + + +def get_study_room(db: Session, room_id: str): + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() + if study_room: + return study_room + + + +def get_study_rooms(db: Session, skip: int, limit: int, option: str): + study_rooms = db.query(StudyRooms).filter(StudyRooms.current_join_counts < 5).order_by(f'{option}').offset(skip).limit(limit).all() + return study_rooms + + +def create_study_room(db: Session, room_info: StudyRoomsCreate): + print(room_info.is_public) + password_exception_handler(StudyRoomsCreate) + room_info.current_join_counts += 1 + response = StudyRooms(**jsonable_encoder(room_info)) + db.add(response) + db.commit() + return response + + +def update_study_room(db: Session, room_id: str, room_info: StudyRoomsUpdate): + password_exception_handler(StudyRoomsUpdate) + update_data = room_info.dict(exclude_none=True) + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) + db.commit() + return study_room + + +def delete_study_room(db: Session, room_id: str): + try: + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() + if study_room: + db.delete(study_room) + db.commit() + else: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') + except ValueError: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') + \ No newline at end of file diff --git a/app/database/base.py b/app/database/base.py index 609e64d..25a1c23 100644 --- a/app/database/base.py +++ b/app/database/base.py @@ -1,3 +1,2 @@ from app.database.base_class import Base -from app.models.product import Product -from app.models.user.user import User \ No newline at end of file +from app.models.user.user import User diff --git a/app/database/session.py b/app/database/session.py index 9684b37..22368bb 100644 --- a/app/database/session.py +++ b/app/database/session.py @@ -1,7 +1,8 @@ -from sqlalchemy import create_engine +from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from app.core import settings +from app.core import common_settings -engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True) + +engine = create_engine(common_settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) diff --git a/app/tests/api/v1/__init__.py b/app/erros/__init__.py similarity index 100% rename from app/tests/api/v1/__init__.py rename to app/erros/__init__.py diff --git a/app/erros/study_rooms/__init__.py b/app/erros/study_rooms/__init__.py new file mode 100644 index 0000000..65f1c7c --- /dev/null +++ b/app/erros/study_rooms/__init__.py @@ -0,0 +1 @@ +from app.erros.study_rooms.handling import CustomException \ No newline at end of file diff --git a/app/erros/study_rooms/handling.py b/app/erros/study_rooms/handling.py new file mode 100644 index 0000000..400e8d7 --- /dev/null +++ b/app/erros/study_rooms/handling.py @@ -0,0 +1,28 @@ +from fastapi import FastAPI, Request, status, Request +from fastapi.encoders import jsonable_encoder +from fastapi.exceptions import RequestValidationError +from fastapi.responses import JSONResponse + + +app = FastAPI() + +class CustomException(Exception): + def __init__(self, message: str): + self.message = message + + +@app.exception_handler(RequestValidationError) +def validation_exception_handler(request: Request, exc: RequestValidationError): + loc = exc.errors()[0]['loc'][0].upper() + item = exc.errors()[0]['loc'][1].upper() + return JSONResponse( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + content=jsonable_encoder({'data': '', 'message': f'ERROR_{item}_IN_{loc}'}) + ) + + +@app.exception_handler(CustomException) +def NotFoundHandler(request: Request, exc: CustomException): + return JSONResponse(status_code = 404, content = {'data': '', 'message': exc.message}) + + diff --git a/app/main.py b/app/main.py index b6d96d8..f46a742 100644 --- a/app/main.py +++ b/app/main.py @@ -1,15 +1,28 @@ import uvicorn -from fastapi import FastAPI +from fastapi import FastAPI +<<<<<<< HEAD from app.api.v1 import api_router from app.api import user_router from app.core import settings +======= +from app.api import api_router +from app.core import common_settings +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -app = FastAPI(title=settings.PROJECT_NAME) +<<<<<<< HEAD app.include_router(api_router, prefix=settings.API_V1_STR) app.include_router(user_router, prefix=settings.API_USER) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8001) +======= +server = FastAPI(title=common_settings.PROJECT_NAME) +server.include_router(api_router, prefix=common_settings.COMMON_API) + + +if __name__ == "__main__": + uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 diff --git a/app/models/__init__.py b/app/models/__init__.py index 6f9a137..886b0c8 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,2 +1,2 @@ -from app.models.product import Product -from app.models.user.user import User +from app.models.users import User +from app.models.study_rooms import StudyRooms diff --git a/app/models/product.py b/app/models/product.py deleted file mode 100644 index ab5634e..0000000 --- a/app/models/product.py +++ /dev/null @@ -1,9 +0,0 @@ -from sqlalchemy import Column, Integer, String, Float - -from app.database.base_class import Base - - -class Product(Base): - id = Column(Integer, primary_key=True, index=True) - name = Column(String, nullable=False) - price = Column(Float, nullable=False) diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py new file mode 100644 index 0000000..fd325e7 --- /dev/null +++ b/app/models/study_rooms.py @@ -0,0 +1,26 @@ +from uuid import uuid4 +from datetime import datetime, timedelta + +from sqlalchemy import Column, ForeignKey, String, Boolean, Integer, SmallInteger, DateTime +from sqlalchemy.orm import relation +from sqlalchemy.dialects.postgresql import UUID + +from app.database.base_class import Base + + +UTC_NOW = datetime.utcnow() +KST = timedelta(hours=9) +KOR_NOW = UTC_NOW + KST + + +class StudyRooms(Base): + __tablename__ = 'study_rooms' + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4) + title = Column(String(64), nullable=False) + description = Column(String(256), nullable=False) + is_public = Column(Boolean(), default=False, nullable=False) + password = Column(String(32), nullable=True) + current_join_counts = Column(SmallInteger(), nullable=False, default=0) + created_at = Column(DateTime(), default=KOR_NOW) + owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) + owner = relation('User', back_populates = "study_rooms") \ No newline at end of file diff --git a/app/models/users.py b/app/models/users.py new file mode 100644 index 0000000..1d7584c --- /dev/null +++ b/app/models/users.py @@ -0,0 +1,20 @@ +import enum + +from sqlalchemy import Column, Integer, Enum, String +from sqlalchemy.orm import relation + +from app.database.base_class import Base + + +class Provider(str, enum.Enum): + GOOGLE = 'google' + FACEBOOK = 'facebook' + + +class User(Base): + __tablename__ = 'users' + id = Column('user_id', Integer, primary_key=True, autoincrement=True) + provider = Column('user_provider', Enum(Provider), nullable=False) + social_id = Column('user_social_id', String, nullable=False, unique=True) + nickname = Column('user_nickname', String, nullable=False, unique=True) + study_rooms = relation('StudyRooms', back_populates = "owner") \ No newline at end of file diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 659d1b0..44d1169 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,3 +1,8 @@ -from app.schemas.message import Message -from app.schemas.product import ProductBase, ProductCreate, ProductUpdate, ProductResponse -from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse \ No newline at end of file +from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse +from app.schemas.study_rooms import ( + StudyRoomsBase, + StudyRoomsCreate, + StudyRoomsUpdate, + StudyRoomResponse + ) + diff --git a/app/schemas/message.py b/app/schemas/message.py deleted file mode 100644 index 8b65c80..0000000 --- a/app/schemas/message.py +++ /dev/null @@ -1,5 +0,0 @@ -from pydantic import BaseModel - - -class Message(BaseModel): - message: str diff --git a/app/schemas/product.py b/app/schemas/product.py deleted file mode 100644 index bcb4181..0000000 --- a/app/schemas/product.py +++ /dev/null @@ -1,24 +0,0 @@ -from typing import Optional - -from pydantic import BaseModel - - -class ProductBase(BaseModel): - id: Optional[int] - name: Optional[str] - price: Optional[float] - - -class ProductCreate(ProductBase): - name: str - price: float - - -class ProductUpdate(ProductBase): - id: int - pass - - -class ProductResponse(ProductBase): - class Config: - orm_mode = True diff --git a/app/schemas/study_rooms.py b/app/schemas/study_rooms.py new file mode 100644 index 0000000..59ef5cc --- /dev/null +++ b/app/schemas/study_rooms.py @@ -0,0 +1,42 @@ +from uuid import UUID +from typing import Optional, Union + +from pydantic import BaseModel + + +class StudyRoomsBase(BaseModel): + title: str + description: str + is_public: bool + current_join_counts: int + owner_id: int + + +class StudyRoomsCreate(StudyRoomsBase): + password: Optional[str] + current_join_counts: int = 0 + + +class StudyRoomsUpdate(BaseModel): + title: Optional[str] + description: Optional[str] + is_public: Optional[bool] + password: Optional[str] + + +class StudyRoomResponse(BaseModel): + data: Union[str, StudyRoomsBase] + message: str + class Config: + orm_mode = True + schema_extra = { + 'example': { + 'id': 'd7e3a12f-5669-4eb4-96db-b27efc6d96a2', + 'title': '주 4시간 이상 고시 공부방 🔥', + 'description': '같이 열심히 공부하실 분들만!', + 'is_public': False, + 'password': 'TestPassword!234', + 'current_join_counts': 1, + 'owner_id': 1 + } + } \ No newline at end of file diff --git a/app/tests/api/study_rooms.py b/app/tests/api/study_rooms.py new file mode 100644 index 0000000..a735048 --- /dev/null +++ b/app/tests/api/study_rooms.py @@ -0,0 +1,54 @@ +from app.core import settings +from app.tests.conftest import client + + +api_address = settings.API_V1_STR + + +def test_get_study_room_success(): + room_id = 'be6172b4-c388-4b5d-832a-b30110e11bd5' + response = client.get( + f'{api_address}/study-rooms/{room_id}' + ) + assert response.status_code == 200 + + +def test_get_study_room_uuid(): + room_id = '7aa4556e-bdc2-4fe9-813a-1a4' + response = client.get( + f'{api_address}/study-rooms/{room_id}' + ) + assert response.status_code == 500 + + +def test_get_study_room_not_found(): + room_id = '7aa4556e-bdc2-4fe9' + response = client.get( + f'{api_address}/study_rooms/{room_id}' + ) + print(response.json()) + assert response.status_code == 404 + + +def test_get_study_rooms(): + response = client.get( + f'{api_address}/study-rooms' + ) + print(response.json()) + assert response.status_code == 200 + + +def test_create_study_room(): + data = { + "title": "스터디 룸 생성 테스트", + "description": "스터디룸 생성 설명", + "is_public": True, + "owner_id": 1 + } + response = client.post( + f'{api_address}/study-rooms', + json = { **data } + ) + print(response.json()) + assert response.status_code == 200 + assert response.json() == None \ No newline at end of file diff --git a/app/tests/api/v1/test_products.py b/app/tests/api/v1/test_products.py deleted file mode 100644 index c69411c..0000000 --- a/app/tests/api/v1/test_products.py +++ /dev/null @@ -1,35 +0,0 @@ -from typing import Dict - -from fastapi.testclient import TestClient - -from app.core import settings - - -def test_create_product(client: TestClient, random_product: Dict[str, str]) -> None: - response = client.post(f"{settings.API_V1_STR}/products", json=random_product) - product = response.json() - assert response.status_code == 200 - assert product.get("name") == random_product.get("name") - assert product.get("price") == random_product.get("price") - - -def test_read_products(client: TestClient) -> None: - response = client.get(f"{settings.API_V1_STR}/products") - products = response.json() - assert response.status_code == 200 - assert len(products) > 0 - - -def test_update_product(client: TestClient, random_product: Dict[str, str]) -> None: - random_product["price"] = 100 - response = client.put(f"{settings.API_V1_STR}/products", json=random_product) - product = response.json() - assert response.status_code == 200 - assert product.get("price") == random_product.get("price") - - -def test_delete_product(client: TestClient, random_product: Dict[str, str]) -> None: - response = client.delete(f"{settings.API_V1_STR}/products?id={random_product.get('id')}") - message = response.json() - assert response.status_code == 200 - assert "message" in message diff --git a/app/tests/conftest.py b/app/tests/conftest.py index db1dd6f..0942528 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -1,24 +1,28 @@ -from typing import Dict, Generator - -import pytest - from fastapi.testclient import TestClient from app.database.session import SessionLocal -from app.main import app +from app.database.base import Base +from app.api.deps import get_db +from app.main import app +Base.metadata -@pytest.fixture(scope="session") -def db() -> Generator: - yield SessionLocal() +def overried_get_db(): + try: + db = SessionLocal() + yield db + finally: + db.close() -@pytest.fixture(scope="module") -def client() -> Generator: - with TestClient(app) as c: - yield c +def client(): + with TestClient(app) as client: + yield client + +app.dependency_overrides[get_db] = overried_get_db +<<<<<<< HEAD @pytest.fixture(scope="module") def random_product() -> Dict[str, str]: return { @@ -35,3 +39,6 @@ def test_user() -> Dict[str, str]: "email": "test@test.com", "nickname": "test" } +======= +client = TestClient(app) +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 diff --git a/migrations/versions/eaae517c1e2f_initialise.py b/migrations/versions/eaae517c1e2f_initialise.py deleted file mode 100644 index d18764f..0000000 --- a/migrations/versions/eaae517c1e2f_initialise.py +++ /dev/null @@ -1,35 +0,0 @@ -"""initialise - -Revision ID: eaae517c1e2f -Revises: -Create Date: 2020-10-01 12:32:07.701738 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'eaae517c1e2f' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('product', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(), nullable=False), - sa.Column('price', sa.Float(), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_product_id'), 'product', ['id'], unique=False) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_product_id'), table_name='product') - op.drop_table('product') - # ### end Alembic commands ### diff --git a/requirements.txt b/requirements.txt index 0847dcf..6b3d963 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,31 @@ +alembic==1.6.2 +attrs==20.3.0 certifi==2020.12.5 +chardet==4.0.0 click==7.1.2 fastapi==0.63.0 greenlet==1.0.0 h11==0.12.0 +idna==2.10 +iniconfig==1.1.1 +jose==1.0.0 +Mako==1.1.4 +MarkupSafe==1.1.1 +packaging==20.9 +pluggy==0.13.1 +psycopg2==2.8.6 +py==1.10.0 pydantic==1.8.1 +pyparsing==2.4.7 +pytest==6.2.4 +python-dateutil==2.8.1 +python-dotenv==0.17.1 +python-editor==1.0.4 +requests==2.25.1 +six==1.16.0 SQLAlchemy==1.4.6 starlette==0.13.6 +toml==0.10.2 typing-extensions==3.7.4.3 +urllib3==1.26.4 uvicorn==0.13.4 From ddc3ff139025ce093b75a1ab0603be4fc377c09d Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 18:54:24 +0900 Subject: [PATCH 022/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/__init__.py | 6 ++++ app/api/v1/study_rooms.py | 52 +++++++++++++++++++++++++++ app/core/config.py | 6 ++++ app/crud/__init__.py | 6 ++++ app/main.py | 17 +++++++++ app/models/__init__.py | 6 ++++ app/models/study_rooms.py | 7 +++- app/models/user/provider.py | 6 ++++ app/models/user/user.py | 18 ++++++++++ app/schemas/__init__.py | 6 ++++ app/schemas/product.py | 24 +++++++++++++ app/schemas/users.py | 28 +++++++++++++++ app/tests/api/v1/test_products.py | 36 +++++++++++++++++++ app/tests/api/v1/test_study_rooms.py | 54 ++++++++++++++++++++++++++++ app/tests/conftest.py | 24 +++++++++++++ requirements.txt | 3 ++ 16 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 app/api/v1/__init__.py create mode 100644 app/api/v1/study_rooms.py create mode 100644 app/schemas/product.py create mode 100644 app/schemas/users.py create mode 100644 app/tests/api/v1/test_products.py create mode 100644 app/tests/api/v1/test_study_rooms.py diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py new file mode 100644 index 0000000..292daf1 --- /dev/null +++ b/app/api/v1/__init__.py @@ -0,0 +1,6 @@ +from fastapi import APIRouter + +from app.api.v1 import study_rooms + +api_router = APIRouter() +api_router.include_router(study_rooms.router, prefix="/study-rooms", tags=["study_rooms"]) diff --git a/app/api/v1/study_rooms.py b/app/api/v1/study_rooms.py new file mode 100644 index 0000000..08379c1 --- /dev/null +++ b/app/api/v1/study_rooms.py @@ -0,0 +1,52 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm.session import Session + +from app.api.deps import get_db +from app.erros.study_rooms import CustomException +from app.crud import ( + get_study_room, + get_study_rooms, + create_study_room, + update_study_room, + delete_study_room + ) +from app.schemas import ( + StudyRoomResponse, + StudyRoomsCreate, + StudyRoomsUpdate + ) + + + +router = APIRouter() + + +@router.get('/{room_id}', response_model=StudyRoomResponse) +def get(room_id: str, db: Session = Depends(get_db)): + study_room = get_study_room(db, room_id) + if study_room: + return study_room + else: + raise CustomException(message = 'NOT_FOUND') + + +@router.patch('/{room_id}') +def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): + response = update_study_room(db, room_id, room_info) + return response + + +@router.delete('/{room_id}') +def delete(room_id: str, db: Session = Depends(get_db)): + _ = delete_study_room(db, room_id) + + +@router.get('') +def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): + response = get_study_rooms(db, skip, limit, option) + return response + + +@router.post('') +def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): + create_study_room(db, rooms) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index e6393b8..d804a17 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -6,6 +6,7 @@ <<<<<<< HEAD class Settings(BaseSettings): API_V1_STR: str = "/api/v1" +<<<<<<< HEAD API_USER: str = "/api/user" PROJECT_NAME: str = "FastAPI" SECRET_KEY: str = secrets.token_urlsafe(32) @@ -19,6 +20,11 @@ class CommonSettings(BaseSettings): SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" >>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 +======= + PROJECT_NAME: str = "studeep" + SECRET_KEY: str = secrets.token_urlsafe(32) + SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" +>>>>>>> 1e939ba... 추가: Study Room class Config: env_file = ".env" diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 2cf33f7..3b0a137 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,7 +1,10 @@ <<<<<<< HEAD +<<<<<<< HEAD from app.crud.product import product from app.crud.user import user ======= +======= +>>>>>>> 1e939ba... 추가: Study Room from app.crud.study_rooms import ( get_study_room, get_study_rooms, @@ -9,4 +12,7 @@ update_study_room, delete_study_room ) +<<<<<<< HEAD >>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 +======= +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/main.py b/app/main.py index f46a742..88b3f54 100644 --- a/app/main.py +++ b/app/main.py @@ -1,5 +1,6 @@ import uvicorn +<<<<<<< HEAD from fastapi import FastAPI <<<<<<< HEAD @@ -26,3 +27,19 @@ if __name__ == "__main__": uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) >>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 +======= +from fastapi import FastAPI + +from app.core import settings +from app.api.v1 import api_router + +server = FastAPI(title=settings.PROJECT_NAME) + + + +server.include_router(api_router, prefix=settings.API_V1_STR) + + +if __name__ == "__main__": + uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/__init__.py b/app/models/__init__.py index 886b0c8..5e5f323 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,2 +1,8 @@ +<<<<<<< HEAD from app.models.users import User from app.models.study_rooms import StudyRooms +======= +from app.models.product import Product +from app.models.user.user import User +from app.models.study_rooms import StudyRooms +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index fd325e7..f974744 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -23,4 +23,9 @@ class StudyRooms(Base): current_join_counts = Column(SmallInteger(), nullable=False, default=0) created_at = Column(DateTime(), default=KOR_NOW) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) - owner = relation('User', back_populates = "study_rooms") \ No newline at end of file +<<<<<<< HEAD + owner = relation('User', back_populates = "study_rooms") +======= + + owner = relation('User', back_populates = "study_rooms") +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/user/provider.py b/app/models/user/provider.py index 432dc52..4608b6f 100644 --- a/app/models/user/provider.py +++ b/app/models/user/provider.py @@ -1,6 +1,12 @@ import enum +<<<<<<< HEAD class Provider(str, enum.Enum): GOOGLE = 'google' FACEBOOK = 'facebook' +======= +class Provider(enum.Enum): + GOOGLE = 1 + FACEBOOK = 2 +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/user/user.py b/app/models/user/user.py index 5fdba44..aa1230a 100644 --- a/app/models/user/user.py +++ b/app/models/user/user.py @@ -1,3 +1,4 @@ +<<<<<<< HEAD import enum from sqlalchemy import Column, Integer, Enum, String @@ -10,7 +11,24 @@ class Provider(str, enum.Enum): class User(Base): +======= +from sqlalchemy import Column, Integer, Float, Enum, String +from sqlalchemy.orm import relation + +from app.database.base_class import Base +from app.models.user.provider import Provider + + +class User(Base): + __tablename__ = 'users' + +>>>>>>> 1e939ba... 추가: Study Room id = Column('user_id', Integer, primary_key=True, autoincrement=True) provider = Column('user_provider', Enum(Provider), nullable=False) social_id = Column('user_social_id', String, nullable=False, unique=True) nickname = Column('user_nickname', String, nullable=False, unique=True) +<<<<<<< HEAD +======= + + study_rooms = relation('StudyRooms', back_populates = "owner") +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 44d1169..a2e2cf2 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,3 +1,4 @@ +<<<<<<< HEAD from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse from app.schemas.study_rooms import ( StudyRoomsBase, @@ -6,3 +7,8 @@ StudyRoomResponse ) +======= +from app.schemas.message import Message +from app.schemas.product import ProductBase, ProductCreate, ProductUpdate, ProductResponse +from app.schemas.study_rooms import StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, StudyRoomResponse +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/schemas/product.py b/app/schemas/product.py new file mode 100644 index 0000000..628ff4c --- /dev/null +++ b/app/schemas/product.py @@ -0,0 +1,24 @@ +from typing import Optional + +from pydantic import BaseModel + + +class ProductBase(BaseModel): + id: Optional[int] + name: Optional[str] + price: Optional[float] + + +class ProductCreate(ProductBase): + name: str + price: float + + +class ProductUpdate(ProductBase): + id: int + pass + + +class ProductResponse(ProductBase): + class Config: + orm_mode = True \ No newline at end of file diff --git a/app/schemas/users.py b/app/schemas/users.py new file mode 100644 index 0000000..4a14127 --- /dev/null +++ b/app/schemas/users.py @@ -0,0 +1,28 @@ +from uuid import UUID + +from typing import Optional + +from pydantic import BaseModel + +class StudyRoomsBase(BaseModel): + title: str + description: str + is_public: bool + password: Optional[str] + owner_id: int + + +class StudyRoomsCreate(StudyRoomsBase): + title: str + description: str + is_public: bool + owner_id: int + + +class StudyRoomsUpdate(StudyRoomsBase): + pass + + +class StudyRoomResponse(StudyRoomsBase): + class Config: + orm_mode = True \ No newline at end of file diff --git a/app/tests/api/v1/test_products.py b/app/tests/api/v1/test_products.py new file mode 100644 index 0000000..1b063e5 --- /dev/null +++ b/app/tests/api/v1/test_products.py @@ -0,0 +1,36 @@ +from typing import Dict + +from fastapi.testclient import TestClient + +from app.core import settings +from app.tests.conftest import client + + +# def test_create_product(random_product: Dict[str, str]) -> None: +# response = client.post(f"{settings.API_V1_STR}/products", json=random_product) +# product = response.json() +# assert response.status_code == 200 +# assert product.get("name") == random_product.get("name") +# assert product.get("price") == random_product.get("price") + + +# def test_read_products() -> None: +# response = client.get(f"{settings.API_V1_STR}/products") +# products = response.json() +# assert response.status_code == 200 +# assert len(products) > 0 + + +# def test_update_product(random_product: Dict[str, str]) -> None: +# random_product["price"] = 100 +# response = client.put(f"{settings.API_V1_STR}/products", json=random_product) +# product = response.json() +# assert response.status_code == 200 +# assert product.get("price") == random_product.get("price") + + +# def test_delete_product(random_product: Dict[str, str]) -> None: +# response = client.delete(f"{settings.API_V1_STR}/products?id={random_product.get('id')}") +# message = response.json() +# assert response.status_code == 200 +# assert "message" in message diff --git a/app/tests/api/v1/test_study_rooms.py b/app/tests/api/v1/test_study_rooms.py new file mode 100644 index 0000000..a735048 --- /dev/null +++ b/app/tests/api/v1/test_study_rooms.py @@ -0,0 +1,54 @@ +from app.core import settings +from app.tests.conftest import client + + +api_address = settings.API_V1_STR + + +def test_get_study_room_success(): + room_id = 'be6172b4-c388-4b5d-832a-b30110e11bd5' + response = client.get( + f'{api_address}/study-rooms/{room_id}' + ) + assert response.status_code == 200 + + +def test_get_study_room_uuid(): + room_id = '7aa4556e-bdc2-4fe9-813a-1a4' + response = client.get( + f'{api_address}/study-rooms/{room_id}' + ) + assert response.status_code == 500 + + +def test_get_study_room_not_found(): + room_id = '7aa4556e-bdc2-4fe9' + response = client.get( + f'{api_address}/study_rooms/{room_id}' + ) + print(response.json()) + assert response.status_code == 404 + + +def test_get_study_rooms(): + response = client.get( + f'{api_address}/study-rooms' + ) + print(response.json()) + assert response.status_code == 200 + + +def test_create_study_room(): + data = { + "title": "스터디 룸 생성 테스트", + "description": "스터디룸 생성 설명", + "is_public": True, + "owner_id": 1 + } + response = client.post( + f'{api_address}/study-rooms', + json = { **data } + ) + print(response.json()) + assert response.status_code == 200 + assert response.json() == None \ No newline at end of file diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 0942528..b093302 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -4,6 +4,17 @@ from app.database.base import Base from app.api.deps import get_db from app.main import app +<<<<<<< HEAD + +Base.metadata + +def overried_get_db(): + try: + db = SessionLocal() + yield db + finally: + db.close() +======= Base.metadata @@ -14,14 +25,24 @@ def overried_get_db(): finally: db.close() +>>>>>>> 1e939ba... 추가: Study Room def client(): with TestClient(app) as client: yield client +<<<<<<< HEAD +def client(): + with TestClient(app) as client: + yield client +======= +>>>>>>> 1e939ba... 추가: Study Room app.dependency_overrides[get_db] = overried_get_db +<<<<<<< HEAD +app.dependency_overrides[get_db] = overried_get_db + <<<<<<< HEAD @pytest.fixture(scope="module") def random_product() -> Dict[str, str]: @@ -42,3 +63,6 @@ def test_user() -> Dict[str, str]: ======= client = TestClient(app) >>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 +======= +client = TestClient(app) +>>>>>>> 1e939ba... 추가: Study Room diff --git a/requirements.txt b/requirements.txt index 6b3d963..ea48446 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,10 @@ greenlet==1.0.0 h11==0.12.0 idna==2.10 iniconfig==1.1.1 +<<<<<<< HEAD jose==1.0.0 +======= +>>>>>>> 1e939ba... 추가: Study Room Mako==1.1.4 MarkupSafe==1.1.1 packaging==20.9 From 28af917ce69ecd9c3b0bf9c5a59d05a451d51500 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 18:56:46 +0900 Subject: [PATCH 023/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/__init__.py | 6 ------ app/schemas/__init__.py | 6 ------ 2 files changed, 12 deletions(-) diff --git a/app/models/__init__.py b/app/models/__init__.py index 5e5f323..886b0c8 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,8 +1,2 @@ -<<<<<<< HEAD from app.models.users import User from app.models.study_rooms import StudyRooms -======= -from app.models.product import Product -from app.models.user.user import User -from app.models.study_rooms import StudyRooms ->>>>>>> 1e939ba... 추가: Study Room diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index a2e2cf2..44d1169 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,4 +1,3 @@ -<<<<<<< HEAD from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse from app.schemas.study_rooms import ( StudyRoomsBase, @@ -7,8 +6,3 @@ StudyRoomResponse ) -======= -from app.schemas.message import Message -from app.schemas.product import ProductBase, ProductCreate, ProductUpdate, ProductResponse -from app.schemas.study_rooms import StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, StudyRoomResponse ->>>>>>> 1e939ba... 추가: Study Room From 39e321481a7970c91a3124789fdd06e0a01d3076 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 18:58:14 +0900 Subject: [PATCH 024/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/__init__.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 3b0a137..31f9651 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,10 +1,4 @@ -<<<<<<< HEAD -<<<<<<< HEAD -from app.crud.product import product -from app.crud.user import user -======= -======= ->>>>>>> 1e939ba... 추가: Study Room +from app.crud.user import user from app.crud.study_rooms import ( get_study_room, get_study_rooms, @@ -12,7 +6,3 @@ update_study_room, delete_study_room ) -<<<<<<< HEAD ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -======= ->>>>>>> 1e939ba... 추가: Study Room From 04ea70ae1e04cf469d7cce4a81ab0abc269e7a0a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:00:37 +0900 Subject: [PATCH 025/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/__init__.py | 6 ----- app/api/v1/study_rooms.py | 52 ------------------------------------- app/database/base.py | 2 +- app/models/user/provider.py | 12 --------- app/models/user/user.py | 34 ------------------------ 5 files changed, 1 insertion(+), 105 deletions(-) delete mode 100644 app/api/v1/__init__.py delete mode 100644 app/api/v1/study_rooms.py delete mode 100644 app/models/user/provider.py delete mode 100644 app/models/user/user.py diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py deleted file mode 100644 index 292daf1..0000000 --- a/app/api/v1/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from fastapi import APIRouter - -from app.api.v1 import study_rooms - -api_router = APIRouter() -api_router.include_router(study_rooms.router, prefix="/study-rooms", tags=["study_rooms"]) diff --git a/app/api/v1/study_rooms.py b/app/api/v1/study_rooms.py deleted file mode 100644 index 08379c1..0000000 --- a/app/api/v1/study_rooms.py +++ /dev/null @@ -1,52 +0,0 @@ -from fastapi import APIRouter, Depends -from sqlalchemy.orm.session import Session - -from app.api.deps import get_db -from app.erros.study_rooms import CustomException -from app.crud import ( - get_study_room, - get_study_rooms, - create_study_room, - update_study_room, - delete_study_room - ) -from app.schemas import ( - StudyRoomResponse, - StudyRoomsCreate, - StudyRoomsUpdate - ) - - - -router = APIRouter() - - -@router.get('/{room_id}', response_model=StudyRoomResponse) -def get(room_id: str, db: Session = Depends(get_db)): - study_room = get_study_room(db, room_id) - if study_room: - return study_room - else: - raise CustomException(message = 'NOT_FOUND') - - -@router.patch('/{room_id}') -def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): - response = update_study_room(db, room_id, room_info) - return response - - -@router.delete('/{room_id}') -def delete(room_id: str, db: Session = Depends(get_db)): - _ = delete_study_room(db, room_id) - - -@router.get('') -def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): - response = get_study_rooms(db, skip, limit, option) - return response - - -@router.post('') -def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): - create_study_room(db, rooms) \ No newline at end of file diff --git a/app/database/base.py b/app/database/base.py index 25a1c23..7ab4ad9 100644 --- a/app/database/base.py +++ b/app/database/base.py @@ -1,2 +1,2 @@ from app.database.base_class import Base -from app.models.user.user import User +from app.models.users import User diff --git a/app/models/user/provider.py b/app/models/user/provider.py deleted file mode 100644 index 4608b6f..0000000 --- a/app/models/user/provider.py +++ /dev/null @@ -1,12 +0,0 @@ -import enum - - -<<<<<<< HEAD -class Provider(str, enum.Enum): - GOOGLE = 'google' - FACEBOOK = 'facebook' -======= -class Provider(enum.Enum): - GOOGLE = 1 - FACEBOOK = 2 ->>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/user/user.py b/app/models/user/user.py deleted file mode 100644 index aa1230a..0000000 --- a/app/models/user/user.py +++ /dev/null @@ -1,34 +0,0 @@ -<<<<<<< HEAD -import enum -from sqlalchemy import Column, Integer, Enum, String - -from app.database.base_class import Base - - -class Provider(str, enum.Enum): - GOOGLE = 'google' - FACEBOOK = 'facebook' - - -class User(Base): -======= -from sqlalchemy import Column, Integer, Float, Enum, String -from sqlalchemy.orm import relation - -from app.database.base_class import Base -from app.models.user.provider import Provider - - -class User(Base): - __tablename__ = 'users' - ->>>>>>> 1e939ba... 추가: Study Room - id = Column('user_id', Integer, primary_key=True, autoincrement=True) - provider = Column('user_provider', Enum(Provider), nullable=False) - social_id = Column('user_social_id', String, nullable=False, unique=True) - nickname = Column('user_nickname', String, nullable=False, unique=True) -<<<<<<< HEAD -======= - - study_rooms = relation('StudyRooms', back_populates = "owner") ->>>>>>> 1e939ba... 추가: Study Room From 33b3739af89008fcc8ed716dcf44c1b146a88d71 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:04:42 +0900 Subject: [PATCH 026/147] WIP --- app/tests/api/v1/test_products.py | 36 ------------------- app/tests/api/v1/test_study_rooms.py | 54 ---------------------------- app/tests/conftest.py | 32 ++++------------- 3 files changed, 6 insertions(+), 116 deletions(-) delete mode 100644 app/tests/api/v1/test_products.py delete mode 100644 app/tests/api/v1/test_study_rooms.py diff --git a/app/tests/api/v1/test_products.py b/app/tests/api/v1/test_products.py deleted file mode 100644 index 1b063e5..0000000 --- a/app/tests/api/v1/test_products.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import Dict - -from fastapi.testclient import TestClient - -from app.core import settings -from app.tests.conftest import client - - -# def test_create_product(random_product: Dict[str, str]) -> None: -# response = client.post(f"{settings.API_V1_STR}/products", json=random_product) -# product = response.json() -# assert response.status_code == 200 -# assert product.get("name") == random_product.get("name") -# assert product.get("price") == random_product.get("price") - - -# def test_read_products() -> None: -# response = client.get(f"{settings.API_V1_STR}/products") -# products = response.json() -# assert response.status_code == 200 -# assert len(products) > 0 - - -# def test_update_product(random_product: Dict[str, str]) -> None: -# random_product["price"] = 100 -# response = client.put(f"{settings.API_V1_STR}/products", json=random_product) -# product = response.json() -# assert response.status_code == 200 -# assert product.get("price") == random_product.get("price") - - -# def test_delete_product(random_product: Dict[str, str]) -> None: -# response = client.delete(f"{settings.API_V1_STR}/products?id={random_product.get('id')}") -# message = response.json() -# assert response.status_code == 200 -# assert "message" in message diff --git a/app/tests/api/v1/test_study_rooms.py b/app/tests/api/v1/test_study_rooms.py deleted file mode 100644 index a735048..0000000 --- a/app/tests/api/v1/test_study_rooms.py +++ /dev/null @@ -1,54 +0,0 @@ -from app.core import settings -from app.tests.conftest import client - - -api_address = settings.API_V1_STR - - -def test_get_study_room_success(): - room_id = 'be6172b4-c388-4b5d-832a-b30110e11bd5' - response = client.get( - f'{api_address}/study-rooms/{room_id}' - ) - assert response.status_code == 200 - - -def test_get_study_room_uuid(): - room_id = '7aa4556e-bdc2-4fe9-813a-1a4' - response = client.get( - f'{api_address}/study-rooms/{room_id}' - ) - assert response.status_code == 500 - - -def test_get_study_room_not_found(): - room_id = '7aa4556e-bdc2-4fe9' - response = client.get( - f'{api_address}/study_rooms/{room_id}' - ) - print(response.json()) - assert response.status_code == 404 - - -def test_get_study_rooms(): - response = client.get( - f'{api_address}/study-rooms' - ) - print(response.json()) - assert response.status_code == 200 - - -def test_create_study_room(): - data = { - "title": "스터디 룸 생성 테스트", - "description": "스터디룸 생성 설명", - "is_public": True, - "owner_id": 1 - } - response = client.post( - f'{api_address}/study-rooms', - json = { **data } - ) - print(response.json()) - assert response.status_code == 200 - assert response.json() == None \ No newline at end of file diff --git a/app/tests/conftest.py b/app/tests/conftest.py index b093302..69085c9 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -1,20 +1,14 @@ -from fastapi.testclient import TestClient +import pytest + +from typing import Dict + +from fastapi.testclient import TestClient from app.database.session import SessionLocal from app.database.base import Base from app.api.deps import get_db from app.main import app -<<<<<<< HEAD - -Base.metadata -def overried_get_db(): - try: - db = SessionLocal() - yield db - finally: - db.close() -======= Base.metadata @@ -25,25 +19,15 @@ def overried_get_db(): finally: db.close() ->>>>>>> 1e939ba... 추가: Study Room def client(): with TestClient(app) as client: yield client -<<<<<<< HEAD -def client(): - with TestClient(app) as client: - yield client -======= ->>>>>>> 1e939ba... 추가: Study Room app.dependency_overrides[get_db] = overried_get_db -<<<<<<< HEAD -app.dependency_overrides[get_db] = overried_get_db -<<<<<<< HEAD @pytest.fixture(scope="module") def random_product() -> Dict[str, str]: return { @@ -60,9 +44,5 @@ def test_user() -> Dict[str, str]: "email": "test@test.com", "nickname": "test" } -======= client = TestClient(app) ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -======= -client = TestClient(app) ->>>>>>> 1e939ba... 추가: Study Room + From 6d1cd05c4bfd4ea94dcb84082a33c17d49bb91e8 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:10:41 +0900 Subject: [PATCH 027/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 17 ----------------- app/main.py | 31 ------------------------------- app/models/study_rooms.py | 7 +------ 3 files changed, 1 insertion(+), 54 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index d804a17..d5af78b 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -3,28 +3,11 @@ from pydantic import BaseSettings -<<<<<<< HEAD -class Settings(BaseSettings): - API_V1_STR: str = "/api/v1" -<<<<<<< HEAD - API_USER: str = "/api/user" - PROJECT_NAME: str = "FastAPI" - SECRET_KEY: str = secrets.token_urlsafe(32) - SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/fastapi_db" - ALGORITHM = "HS256" - ACCESS_TOKEN_EXPIRE_MINUTES = 30 -======= class CommonSettings(BaseSettings): COMMON_API: str = '/api' PROJECT_NAME: str = "studeep" SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -======= - PROJECT_NAME: str = "studeep" - SECRET_KEY: str = secrets.token_urlsafe(32) - SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" ->>>>>>> 1e939ba... 추가: Study Room class Config: env_file = ".env" diff --git a/app/main.py b/app/main.py index 88b3f54..bb30564 100644 --- a/app/main.py +++ b/app/main.py @@ -1,45 +1,14 @@ import uvicorn -<<<<<<< HEAD from fastapi import FastAPI -<<<<<<< HEAD -from app.api.v1 import api_router -from app.api import user_router -from app.core import settings -======= from app.api import api_router from app.core import common_settings ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -<<<<<<< HEAD -app.include_router(api_router, prefix=settings.API_V1_STR) -app.include_router(user_router, prefix=settings.API_USER) - -if __name__ == "__main__": - uvicorn.run(app, host="0.0.0.0", port=8001) -======= server = FastAPI(title=common_settings.PROJECT_NAME) server.include_router(api_router, prefix=common_settings.COMMON_API) if __name__ == "__main__": uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -======= -from fastapi import FastAPI - -from app.core import settings -from app.api.v1 import api_router - -server = FastAPI(title=settings.PROJECT_NAME) - - - -server.include_router(api_router, prefix=settings.API_V1_STR) - - -if __name__ == "__main__": - uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) ->>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index f974744..fd325e7 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -23,9 +23,4 @@ class StudyRooms(Base): current_join_counts = Column(SmallInteger(), nullable=False, default=0) created_at = Column(DateTime(), default=KOR_NOW) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) -<<<<<<< HEAD - owner = relation('User', back_populates = "study_rooms") -======= - - owner = relation('User', back_populates = "study_rooms") ->>>>>>> 1e939ba... 추가: Study Room + owner = relation('User', back_populates = "study_rooms") \ No newline at end of file From a318fe0689a5e9c7b42c5457ffc64b332023f095 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:12:37 +0900 Subject: [PATCH 028/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflcit=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index ea48446..6b3d963 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,10 +8,7 @@ greenlet==1.0.0 h11==0.12.0 idna==2.10 iniconfig==1.1.1 -<<<<<<< HEAD jose==1.0.0 -======= ->>>>>>> 1e939ba... 추가: Study Room Mako==1.1.4 MarkupSafe==1.1.1 packaging==20.9 From 38aa3bea8ccbd2504a1498babc0b97b52a390adf Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:14:36 +0900 Subject: [PATCH 029/147] =?UTF-8?q?=E3=85=85=EC=88=98=EC=A0=95:=20.env=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 80d754d..0000000 --- a/.env +++ /dev/null @@ -1,3 +0,0 @@ -API_V1_STR="/api/v1" -PROJECT_NAME="Studeep" -SQLALCHEMY_DATABASE_URI="postgresql://localhost:5432/studeep" From 72eb5870aecac308aa3bd53f98b81657e7112364 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:16:16 +0900 Subject: [PATCH 030/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Product=20Schema?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/product.py | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 app/schemas/product.py diff --git a/app/schemas/product.py b/app/schemas/product.py deleted file mode 100644 index 628ff4c..0000000 --- a/app/schemas/product.py +++ /dev/null @@ -1,24 +0,0 @@ -from typing import Optional - -from pydantic import BaseModel - - -class ProductBase(BaseModel): - id: Optional[int] - name: Optional[str] - price: Optional[float] - - -class ProductCreate(ProductBase): - name: str - price: float - - -class ProductUpdate(ProductBase): - id: int - pass - - -class ProductResponse(ProductBase): - class Config: - orm_mode = True \ No newline at end of file From a886cf64fa80a9bb82b2a8dd7d3d9b63b666471b Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 17:05:57 +0900 Subject: [PATCH 031/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=EC=A0=81=EC=9D=B8=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 +++ app/core/config.py | 3 --- app/crud/__init__.py | 1 + app/tests/conftest.py | 14 +------------- requirements.txt | 12 ++++++++++++ 5 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..80d754d --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +API_V1_STR="/api/v1" +PROJECT_NAME="Studeep" +SQLALCHEMY_DATABASE_URI="postgresql://localhost:5432/studeep" diff --git a/app/core/config.py b/app/core/config.py index 67816a0..c714b08 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -9,9 +9,6 @@ class CommonSettings(BaseSettings): SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" - class Config: - env_file = ".env" - class StudyRoomSettings(BaseSettings): API_STUDY_ROOM: str = '/study-rooms' diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 31f9651..a0a83b8 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,4 +1,5 @@ from app.crud.user import user + from app.crud.study_rooms import ( get_study_room, get_study_rooms, diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 69085c9..106ffb1 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -1,7 +1,4 @@ -import pytest - from typing import Dict - from fastapi.testclient import TestClient from app.database.session import SessionLocal @@ -19,7 +16,6 @@ def overried_get_db(): finally: db.close() - def client(): with TestClient(app) as client: yield client @@ -28,14 +24,6 @@ def client(): app.dependency_overrides[get_db] = overried_get_db -@pytest.fixture(scope="module") -def random_product() -> Dict[str, str]: - return { - "id": 1, - "name": "Test Product", - "price": 80, - } - def test_user() -> Dict[str, str]: return { @@ -44,5 +32,5 @@ def test_user() -> Dict[str, str]: "email": "test@test.com", "nickname": "test" } -client = TestClient(app) +client = TestClient(app) diff --git a/requirements.txt b/requirements.txt index 8987069..5270e9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,10 @@ alembic==1.6.2 attrs==20.3.0 certifi==2020.12.5 +<<<<<<< HEAD cffi==1.14.5 +======= +>>>>>>> 913a161... 수정: 전체적인 폴더 구조 리팩토링 chardet==4.0.0 click==7.1.2 cryptography==3.4.7 @@ -16,19 +19,28 @@ Mako==1.1.4 MarkupSafe==1.1.1 packaging==20.9 pluggy==0.13.1 +<<<<<<< HEAD psycopg2-binary==2.8.6 py==1.10.0 pyasn1==0.4.8 pycparser==2.20 +======= +psycopg2==2.8.6 +py==1.10.0 +>>>>>>> 913a161... 수정: 전체적인 폴더 구조 리팩토링 pydantic==1.8.1 pyparsing==2.4.7 pytest==6.2.4 python-dateutil==2.8.1 python-dotenv==0.17.1 python-editor==1.0.4 +<<<<<<< HEAD python-jose==3.2.0 requests==2.25.1 rsa==4.7.2 +======= +requests==2.25.1 +>>>>>>> 913a161... 수정: 전체적인 폴더 구조 리팩토링 six==1.16.0 SQLAlchemy==1.4.6 starlette==0.13.6 From 744aef27b9b1ddcb1fc5e25e86e90211a89f87f5 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 18:54:24 +0900 Subject: [PATCH 032/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/__init__.py | 6 ++++ app/api/v1/study_rooms.py | 52 +++++++++++++++++++++++++++ app/core/config.py | 7 ++++ app/crud/__init__.py | 17 +++++++++ app/main.py | 2 ++ app/models/study_rooms.py | 7 +++- app/models/user/provider.py | 12 +++++++ app/models/user/user.py | 34 ++++++++++++++++++ app/schemas/__init__.py | 6 ++++ app/schemas/product.py | 24 +++++++++++++ app/tests/api/v1/test_products.py | 36 +++++++++++++++++++ app/tests/api/v1/test_study_rooms.py | 54 ++++++++++++++++++++++++++++ app/tests/conftest.py | 43 ++++++++++++++++++++++ requirements.txt | 18 ---------- 14 files changed, 299 insertions(+), 19 deletions(-) create mode 100644 app/api/v1/__init__.py create mode 100644 app/api/v1/study_rooms.py create mode 100644 app/models/user/provider.py create mode 100644 app/models/user/user.py create mode 100644 app/schemas/product.py create mode 100644 app/tests/api/v1/test_products.py create mode 100644 app/tests/api/v1/test_study_rooms.py diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py new file mode 100644 index 0000000..292daf1 --- /dev/null +++ b/app/api/v1/__init__.py @@ -0,0 +1,6 @@ +from fastapi import APIRouter + +from app.api.v1 import study_rooms + +api_router = APIRouter() +api_router.include_router(study_rooms.router, prefix="/study-rooms", tags=["study_rooms"]) diff --git a/app/api/v1/study_rooms.py b/app/api/v1/study_rooms.py new file mode 100644 index 0000000..08379c1 --- /dev/null +++ b/app/api/v1/study_rooms.py @@ -0,0 +1,52 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm.session import Session + +from app.api.deps import get_db +from app.erros.study_rooms import CustomException +from app.crud import ( + get_study_room, + get_study_rooms, + create_study_room, + update_study_room, + delete_study_room + ) +from app.schemas import ( + StudyRoomResponse, + StudyRoomsCreate, + StudyRoomsUpdate + ) + + + +router = APIRouter() + + +@router.get('/{room_id}', response_model=StudyRoomResponse) +def get(room_id: str, db: Session = Depends(get_db)): + study_room = get_study_room(db, room_id) + if study_room: + return study_room + else: + raise CustomException(message = 'NOT_FOUND') + + +@router.patch('/{room_id}') +def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): + response = update_study_room(db, room_id, room_info) + return response + + +@router.delete('/{room_id}') +def delete(room_id: str, db: Session = Depends(get_db)): + _ = delete_study_room(db, room_id) + + +@router.get('') +def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): + response = get_study_rooms(db, skip, limit, option) + return response + + +@router.post('') +def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): + create_study_room(db, rooms) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index c714b08..db3ee33 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -3,11 +3,18 @@ from pydantic import BaseSettings + class CommonSettings(BaseSettings): COMMON_API: str = '/api' PROJECT_NAME: str = "studeep" SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" + PROJECT_NAME: str = "studeep" + SECRET_KEY: str = secrets.token_urlsafe(32) + SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" + + class Config: + env_file = ".env" class StudyRoomSettings(BaseSettings): diff --git a/app/crud/__init__.py b/app/crud/__init__.py index a0a83b8..6c5bfab 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,5 +1,15 @@ +<<<<<<< HEAD from app.crud.user import user +======= +<<<<<<< HEAD +<<<<<<< HEAD +from app.crud.product import product +from app.crud.user import user +======= +======= +>>>>>>> 1e939ba... 추가: Study Room +>>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 from app.crud.study_rooms import ( get_study_room, get_study_rooms, @@ -7,3 +17,10 @@ update_study_room, delete_study_room ) +<<<<<<< HEAD +======= +<<<<<<< HEAD +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 +======= +>>>>>>> 1e939ba... 추가: Study Room +>>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 diff --git a/app/main.py b/app/main.py index bb30564..5d54537 100644 --- a/app/main.py +++ b/app/main.py @@ -12,3 +12,5 @@ if __name__ == "__main__": uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) + + diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index fd325e7..f974744 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -23,4 +23,9 @@ class StudyRooms(Base): current_join_counts = Column(SmallInteger(), nullable=False, default=0) created_at = Column(DateTime(), default=KOR_NOW) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) - owner = relation('User', back_populates = "study_rooms") \ No newline at end of file +<<<<<<< HEAD + owner = relation('User', back_populates = "study_rooms") +======= + + owner = relation('User', back_populates = "study_rooms") +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/user/provider.py b/app/models/user/provider.py new file mode 100644 index 0000000..4608b6f --- /dev/null +++ b/app/models/user/provider.py @@ -0,0 +1,12 @@ +import enum + + +<<<<<<< HEAD +class Provider(str, enum.Enum): + GOOGLE = 'google' + FACEBOOK = 'facebook' +======= +class Provider(enum.Enum): + GOOGLE = 1 + FACEBOOK = 2 +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/user/user.py b/app/models/user/user.py new file mode 100644 index 0000000..aa1230a --- /dev/null +++ b/app/models/user/user.py @@ -0,0 +1,34 @@ +<<<<<<< HEAD +import enum +from sqlalchemy import Column, Integer, Enum, String + +from app.database.base_class import Base + + +class Provider(str, enum.Enum): + GOOGLE = 'google' + FACEBOOK = 'facebook' + + +class User(Base): +======= +from sqlalchemy import Column, Integer, Float, Enum, String +from sqlalchemy.orm import relation + +from app.database.base_class import Base +from app.models.user.provider import Provider + + +class User(Base): + __tablename__ = 'users' + +>>>>>>> 1e939ba... 추가: Study Room + id = Column('user_id', Integer, primary_key=True, autoincrement=True) + provider = Column('user_provider', Enum(Provider), nullable=False) + social_id = Column('user_social_id', String, nullable=False, unique=True) + nickname = Column('user_nickname', String, nullable=False, unique=True) +<<<<<<< HEAD +======= + + study_rooms = relation('StudyRooms', back_populates = "owner") +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 44d1169..a2e2cf2 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,3 +1,4 @@ +<<<<<<< HEAD from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse from app.schemas.study_rooms import ( StudyRoomsBase, @@ -6,3 +7,8 @@ StudyRoomResponse ) +======= +from app.schemas.message import Message +from app.schemas.product import ProductBase, ProductCreate, ProductUpdate, ProductResponse +from app.schemas.study_rooms import StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, StudyRoomResponse +>>>>>>> 1e939ba... 추가: Study Room diff --git a/app/schemas/product.py b/app/schemas/product.py new file mode 100644 index 0000000..628ff4c --- /dev/null +++ b/app/schemas/product.py @@ -0,0 +1,24 @@ +from typing import Optional + +from pydantic import BaseModel + + +class ProductBase(BaseModel): + id: Optional[int] + name: Optional[str] + price: Optional[float] + + +class ProductCreate(ProductBase): + name: str + price: float + + +class ProductUpdate(ProductBase): + id: int + pass + + +class ProductResponse(ProductBase): + class Config: + orm_mode = True \ No newline at end of file diff --git a/app/tests/api/v1/test_products.py b/app/tests/api/v1/test_products.py new file mode 100644 index 0000000..1b063e5 --- /dev/null +++ b/app/tests/api/v1/test_products.py @@ -0,0 +1,36 @@ +from typing import Dict + +from fastapi.testclient import TestClient + +from app.core import settings +from app.tests.conftest import client + + +# def test_create_product(random_product: Dict[str, str]) -> None: +# response = client.post(f"{settings.API_V1_STR}/products", json=random_product) +# product = response.json() +# assert response.status_code == 200 +# assert product.get("name") == random_product.get("name") +# assert product.get("price") == random_product.get("price") + + +# def test_read_products() -> None: +# response = client.get(f"{settings.API_V1_STR}/products") +# products = response.json() +# assert response.status_code == 200 +# assert len(products) > 0 + + +# def test_update_product(random_product: Dict[str, str]) -> None: +# random_product["price"] = 100 +# response = client.put(f"{settings.API_V1_STR}/products", json=random_product) +# product = response.json() +# assert response.status_code == 200 +# assert product.get("price") == random_product.get("price") + + +# def test_delete_product(random_product: Dict[str, str]) -> None: +# response = client.delete(f"{settings.API_V1_STR}/products?id={random_product.get('id')}") +# message = response.json() +# assert response.status_code == 200 +# assert "message" in message diff --git a/app/tests/api/v1/test_study_rooms.py b/app/tests/api/v1/test_study_rooms.py new file mode 100644 index 0000000..a735048 --- /dev/null +++ b/app/tests/api/v1/test_study_rooms.py @@ -0,0 +1,54 @@ +from app.core import settings +from app.tests.conftest import client + + +api_address = settings.API_V1_STR + + +def test_get_study_room_success(): + room_id = 'be6172b4-c388-4b5d-832a-b30110e11bd5' + response = client.get( + f'{api_address}/study-rooms/{room_id}' + ) + assert response.status_code == 200 + + +def test_get_study_room_uuid(): + room_id = '7aa4556e-bdc2-4fe9-813a-1a4' + response = client.get( + f'{api_address}/study-rooms/{room_id}' + ) + assert response.status_code == 500 + + +def test_get_study_room_not_found(): + room_id = '7aa4556e-bdc2-4fe9' + response = client.get( + f'{api_address}/study_rooms/{room_id}' + ) + print(response.json()) + assert response.status_code == 404 + + +def test_get_study_rooms(): + response = client.get( + f'{api_address}/study-rooms' + ) + print(response.json()) + assert response.status_code == 200 + + +def test_create_study_room(): + data = { + "title": "스터디 룸 생성 테스트", + "description": "스터디룸 생성 설명", + "is_public": True, + "owner_id": 1 + } + response = client.post( + f'{api_address}/study-rooms', + json = { **data } + ) + print(response.json()) + assert response.status_code == 200 + assert response.json() == None \ No newline at end of file diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 106ffb1..766be96 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -5,6 +5,17 @@ from app.database.base import Base from app.api.deps import get_db from app.main import app +<<<<<<< HEAD + +Base.metadata + +def overried_get_db(): + try: + db = SessionLocal() + yield db + finally: + db.close() +======= Base.metadata @@ -16,13 +27,38 @@ def overried_get_db(): finally: db.close() +<<<<<<< HEAD +======= +>>>>>>> 1e939ba... 추가: Study Room + +>>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 def client(): with TestClient(app) as client: yield client +<<<<<<< HEAD +def client(): + with TestClient(app) as client: + yield client +======= +>>>>>>> 1e939ba... 추가: Study Room app.dependency_overrides[get_db] = overried_get_db +<<<<<<< HEAD +======= +<<<<<<< HEAD +app.dependency_overrides[get_db] = overried_get_db + +<<<<<<< HEAD +@pytest.fixture(scope="module") +def random_product() -> Dict[str, str]: + return { + "id": 1, + "name": "Test Product", + "price": 80, + } +>>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 def test_user() -> Dict[str, str]: @@ -34,3 +70,10 @@ def test_user() -> Dict[str, str]: } client = TestClient(app) +<<<<<<< HEAD +======= +>>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 +======= +client = TestClient(app) +>>>>>>> 1e939ba... 추가: Study Room +>>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 diff --git a/requirements.txt b/requirements.txt index 5270e9a..f516006 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,6 @@ alembic==1.6.2 attrs==20.3.0 certifi==2020.12.5 -<<<<<<< HEAD -cffi==1.14.5 -======= ->>>>>>> 913a161... 수정: 전체적인 폴더 구조 리팩토링 chardet==4.0.0 click==7.1.2 cryptography==3.4.7 @@ -14,33 +10,19 @@ greenlet==1.0.0 h11==0.12.0 idna==2.10 iniconfig==1.1.1 -jose==1.0.0 Mako==1.1.4 MarkupSafe==1.1.1 packaging==20.9 pluggy==0.13.1 -<<<<<<< HEAD -psycopg2-binary==2.8.6 -py==1.10.0 -pyasn1==0.4.8 -pycparser==2.20 -======= psycopg2==2.8.6 py==1.10.0 ->>>>>>> 913a161... 수정: 전체적인 폴더 구조 리팩토링 pydantic==1.8.1 pyparsing==2.4.7 pytest==6.2.4 python-dateutil==2.8.1 python-dotenv==0.17.1 python-editor==1.0.4 -<<<<<<< HEAD -python-jose==3.2.0 -requests==2.25.1 -rsa==4.7.2 -======= requests==2.25.1 ->>>>>>> 913a161... 수정: 전체적인 폴더 구조 리팩토링 six==1.16.0 SQLAlchemy==1.4.6 starlette==0.13.6 From a385d75301f8b855145ba59784ecef3a1b1a331b Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 18:56:46 +0900 Subject: [PATCH 033/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/__init__.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index a2e2cf2..44d1169 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,4 +1,3 @@ -<<<<<<< HEAD from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse from app.schemas.study_rooms import ( StudyRoomsBase, @@ -7,8 +6,3 @@ StudyRoomResponse ) -======= -from app.schemas.message import Message -from app.schemas.product import ProductBase, ProductCreate, ProductUpdate, ProductResponse -from app.schemas.study_rooms import StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, StudyRoomResponse ->>>>>>> 1e939ba... 추가: Study Room From 2c9afbe8b866444df561e619e80f44e00e30d3ec Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 18:58:14 +0900 Subject: [PATCH 034/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/__init__.py | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 6c5bfab..70de615 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,15 +1,4 @@ -<<<<<<< HEAD from app.crud.user import user - -======= -<<<<<<< HEAD -<<<<<<< HEAD -from app.crud.product import product -from app.crud.user import user -======= -======= ->>>>>>> 1e939ba... 추가: Study Room ->>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 from app.crud.study_rooms import ( get_study_room, get_study_rooms, @@ -17,10 +6,4 @@ update_study_room, delete_study_room ) -<<<<<<< HEAD -======= -<<<<<<< HEAD ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -======= ->>>>>>> 1e939ba... 추가: Study Room ->>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 + From 2d33c89397c94c690cece1f332ef3dbe57716a39 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:00:37 +0900 Subject: [PATCH 035/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/__init__.py | 6 ----- app/api/v1/study_rooms.py | 52 ------------------------------------- app/models/user/provider.py | 12 --------- app/models/user/user.py | 34 ------------------------ 4 files changed, 104 deletions(-) delete mode 100644 app/api/v1/__init__.py delete mode 100644 app/api/v1/study_rooms.py delete mode 100644 app/models/user/provider.py delete mode 100644 app/models/user/user.py diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py deleted file mode 100644 index 292daf1..0000000 --- a/app/api/v1/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from fastapi import APIRouter - -from app.api.v1 import study_rooms - -api_router = APIRouter() -api_router.include_router(study_rooms.router, prefix="/study-rooms", tags=["study_rooms"]) diff --git a/app/api/v1/study_rooms.py b/app/api/v1/study_rooms.py deleted file mode 100644 index 08379c1..0000000 --- a/app/api/v1/study_rooms.py +++ /dev/null @@ -1,52 +0,0 @@ -from fastapi import APIRouter, Depends -from sqlalchemy.orm.session import Session - -from app.api.deps import get_db -from app.erros.study_rooms import CustomException -from app.crud import ( - get_study_room, - get_study_rooms, - create_study_room, - update_study_room, - delete_study_room - ) -from app.schemas import ( - StudyRoomResponse, - StudyRoomsCreate, - StudyRoomsUpdate - ) - - - -router = APIRouter() - - -@router.get('/{room_id}', response_model=StudyRoomResponse) -def get(room_id: str, db: Session = Depends(get_db)): - study_room = get_study_room(db, room_id) - if study_room: - return study_room - else: - raise CustomException(message = 'NOT_FOUND') - - -@router.patch('/{room_id}') -def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): - response = update_study_room(db, room_id, room_info) - return response - - -@router.delete('/{room_id}') -def delete(room_id: str, db: Session = Depends(get_db)): - _ = delete_study_room(db, room_id) - - -@router.get('') -def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): - response = get_study_rooms(db, skip, limit, option) - return response - - -@router.post('') -def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): - create_study_room(db, rooms) \ No newline at end of file diff --git a/app/models/user/provider.py b/app/models/user/provider.py deleted file mode 100644 index 4608b6f..0000000 --- a/app/models/user/provider.py +++ /dev/null @@ -1,12 +0,0 @@ -import enum - - -<<<<<<< HEAD -class Provider(str, enum.Enum): - GOOGLE = 'google' - FACEBOOK = 'facebook' -======= -class Provider(enum.Enum): - GOOGLE = 1 - FACEBOOK = 2 ->>>>>>> 1e939ba... 추가: Study Room diff --git a/app/models/user/user.py b/app/models/user/user.py deleted file mode 100644 index aa1230a..0000000 --- a/app/models/user/user.py +++ /dev/null @@ -1,34 +0,0 @@ -<<<<<<< HEAD -import enum -from sqlalchemy import Column, Integer, Enum, String - -from app.database.base_class import Base - - -class Provider(str, enum.Enum): - GOOGLE = 'google' - FACEBOOK = 'facebook' - - -class User(Base): -======= -from sqlalchemy import Column, Integer, Float, Enum, String -from sqlalchemy.orm import relation - -from app.database.base_class import Base -from app.models.user.provider import Provider - - -class User(Base): - __tablename__ = 'users' - ->>>>>>> 1e939ba... 추가: Study Room - id = Column('user_id', Integer, primary_key=True, autoincrement=True) - provider = Column('user_provider', Enum(Provider), nullable=False) - social_id = Column('user_social_id', String, nullable=False, unique=True) - nickname = Column('user_nickname', String, nullable=False, unique=True) -<<<<<<< HEAD -======= - - study_rooms = relation('StudyRooms', back_populates = "owner") ->>>>>>> 1e939ba... 추가: Study Room From f5562b16214666287310b215e089b0b1cf1040bb Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:04:42 +0900 Subject: [PATCH 036/147] WIP --- app/tests/api/v1/test_products.py | 36 ------------------- app/tests/api/v1/test_study_rooms.py | 54 ---------------------------- app/tests/conftest.py | 44 ++--------------------- 3 files changed, 2 insertions(+), 132 deletions(-) delete mode 100644 app/tests/api/v1/test_products.py delete mode 100644 app/tests/api/v1/test_study_rooms.py diff --git a/app/tests/api/v1/test_products.py b/app/tests/api/v1/test_products.py deleted file mode 100644 index 1b063e5..0000000 --- a/app/tests/api/v1/test_products.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import Dict - -from fastapi.testclient import TestClient - -from app.core import settings -from app.tests.conftest import client - - -# def test_create_product(random_product: Dict[str, str]) -> None: -# response = client.post(f"{settings.API_V1_STR}/products", json=random_product) -# product = response.json() -# assert response.status_code == 200 -# assert product.get("name") == random_product.get("name") -# assert product.get("price") == random_product.get("price") - - -# def test_read_products() -> None: -# response = client.get(f"{settings.API_V1_STR}/products") -# products = response.json() -# assert response.status_code == 200 -# assert len(products) > 0 - - -# def test_update_product(random_product: Dict[str, str]) -> None: -# random_product["price"] = 100 -# response = client.put(f"{settings.API_V1_STR}/products", json=random_product) -# product = response.json() -# assert response.status_code == 200 -# assert product.get("price") == random_product.get("price") - - -# def test_delete_product(random_product: Dict[str, str]) -> None: -# response = client.delete(f"{settings.API_V1_STR}/products?id={random_product.get('id')}") -# message = response.json() -# assert response.status_code == 200 -# assert "message" in message diff --git a/app/tests/api/v1/test_study_rooms.py b/app/tests/api/v1/test_study_rooms.py deleted file mode 100644 index a735048..0000000 --- a/app/tests/api/v1/test_study_rooms.py +++ /dev/null @@ -1,54 +0,0 @@ -from app.core import settings -from app.tests.conftest import client - - -api_address = settings.API_V1_STR - - -def test_get_study_room_success(): - room_id = 'be6172b4-c388-4b5d-832a-b30110e11bd5' - response = client.get( - f'{api_address}/study-rooms/{room_id}' - ) - assert response.status_code == 200 - - -def test_get_study_room_uuid(): - room_id = '7aa4556e-bdc2-4fe9-813a-1a4' - response = client.get( - f'{api_address}/study-rooms/{room_id}' - ) - assert response.status_code == 500 - - -def test_get_study_room_not_found(): - room_id = '7aa4556e-bdc2-4fe9' - response = client.get( - f'{api_address}/study_rooms/{room_id}' - ) - print(response.json()) - assert response.status_code == 404 - - -def test_get_study_rooms(): - response = client.get( - f'{api_address}/study-rooms' - ) - print(response.json()) - assert response.status_code == 200 - - -def test_create_study_room(): - data = { - "title": "스터디 룸 생성 테스트", - "description": "스터디룸 생성 설명", - "is_public": True, - "owner_id": 1 - } - response = client.post( - f'{api_address}/study-rooms', - json = { **data } - ) - print(response.json()) - assert response.status_code == 200 - assert response.json() == None \ No newline at end of file diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 766be96..2938e00 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -1,21 +1,12 @@ from typing import Dict + from fastapi.testclient import TestClient from app.database.session import SessionLocal from app.database.base import Base from app.api.deps import get_db from app.main import app -<<<<<<< HEAD - -Base.metadata -def overried_get_db(): - try: - db = SessionLocal() - yield db - finally: - db.close() -======= Base.metadata @@ -27,38 +18,14 @@ def overried_get_db(): finally: db.close() -<<<<<<< HEAD -======= ->>>>>>> 1e939ba... 추가: Study Room ->>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 def client(): with TestClient(app) as client: yield client -<<<<<<< HEAD -def client(): - with TestClient(app) as client: - yield client -======= ->>>>>>> 1e939ba... 추가: Study Room - -app.dependency_overrides[get_db] = overried_get_db -<<<<<<< HEAD -======= -<<<<<<< HEAD app.dependency_overrides[get_db] = overried_get_db -<<<<<<< HEAD -@pytest.fixture(scope="module") -def random_product() -> Dict[str, str]: - return { - "id": 1, - "name": "Test Product", - "price": 80, - } ->>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 def test_user() -> Dict[str, str]: @@ -69,11 +36,4 @@ def test_user() -> Dict[str, str]: "nickname": "test" } -client = TestClient(app) -<<<<<<< HEAD -======= ->>>>>>> 15048eb... 수정: 전체적인 폴더 구조 리팩토링 -======= -client = TestClient(app) ->>>>>>> 1e939ba... 추가: Study Room ->>>>>>> bdaf617... 수정: Conflict 해결 및 사용자 라우터 추가 +client = TestClient(app) \ No newline at end of file From b706f114a340dde7fcb5e0402989a700a3af79f5 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:10:41 +0900 Subject: [PATCH 037/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflict=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 4 ---- app/main.py | 2 -- app/models/study_rooms.py | 7 +------ 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index db3ee33..67816a0 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -3,15 +3,11 @@ from pydantic import BaseSettings - class CommonSettings(BaseSettings): COMMON_API: str = '/api' PROJECT_NAME: str = "studeep" SECRET_KEY: str = secrets.token_urlsafe(32) SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" - PROJECT_NAME: str = "studeep" - SECRET_KEY: str = secrets.token_urlsafe(32) - SQLALCHEMY_DATABASE_URI: str = "postgresql://localhost:5432/studeep" class Config: env_file = ".env" diff --git a/app/main.py b/app/main.py index 5d54537..bb30564 100644 --- a/app/main.py +++ b/app/main.py @@ -12,5 +12,3 @@ if __name__ == "__main__": uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) - - diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index f974744..fd325e7 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -23,9 +23,4 @@ class StudyRooms(Base): current_join_counts = Column(SmallInteger(), nullable=False, default=0) created_at = Column(DateTime(), default=KOR_NOW) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) -<<<<<<< HEAD - owner = relation('User', back_populates = "study_rooms") -======= - - owner = relation('User', back_populates = "study_rooms") ->>>>>>> 1e939ba... 추가: Study Room + owner = relation('User', back_populates = "study_rooms") \ No newline at end of file From b63306074ad52fdb6ab9a87134701560530f257d Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:12:37 +0900 Subject: [PATCH 038/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20Conflcit=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index f516006..86fdfdf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ greenlet==1.0.0 h11==0.12.0 idna==2.10 iniconfig==1.1.1 +jose==1.0.0 Mako==1.1.4 MarkupSafe==1.1.1 packaging==20.9 From 101c18e12bb53d429f406e7d08c8a2aa188c0852 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:14:36 +0900 Subject: [PATCH 039/147] =?UTF-8?q?=E3=85=85=EC=88=98=EC=A0=95:=20.env=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 80d754d..0000000 --- a/.env +++ /dev/null @@ -1,3 +0,0 @@ -API_V1_STR="/api/v1" -PROJECT_NAME="Studeep" -SQLALCHEMY_DATABASE_URI="postgresql://localhost:5432/studeep" From a04590035596f735b408197f82242551a9bacbba Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:16:16 +0900 Subject: [PATCH 040/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Product=20Schema?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/product.py | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 app/schemas/product.py diff --git a/app/schemas/product.py b/app/schemas/product.py deleted file mode 100644 index 628ff4c..0000000 --- a/app/schemas/product.py +++ /dev/null @@ -1,24 +0,0 @@ -from typing import Optional - -from pydantic import BaseModel - - -class ProductBase(BaseModel): - id: Optional[int] - name: Optional[str] - price: Optional[float] - - -class ProductCreate(ProductBase): - name: str - price: float - - -class ProductUpdate(ProductBase): - id: int - pass - - -class ProductResponse(ProductBase): - class Config: - orm_mode = True \ No newline at end of file From 7b16627a3f68621f308cb6500341314a704f338c Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 19:37:08 +0900 Subject: [PATCH 041/147] =?UTF-8?q?=EA=B8=B0=ED=83=80:=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=97=86=EB=8A=94=20=EC=8A=A4=ED=82=A4=EB=A7=88=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/users.py | 28 ---------------------------- app/service/auth.py | 10 +++++----- 2 files changed, 5 insertions(+), 33 deletions(-) delete mode 100644 app/schemas/users.py diff --git a/app/schemas/users.py b/app/schemas/users.py deleted file mode 100644 index 4a14127..0000000 --- a/app/schemas/users.py +++ /dev/null @@ -1,28 +0,0 @@ -from uuid import UUID - -from typing import Optional - -from pydantic import BaseModel - -class StudyRoomsBase(BaseModel): - title: str - description: str - is_public: bool - password: Optional[str] - owner_id: int - - -class StudyRoomsCreate(StudyRoomsBase): - title: str - description: str - is_public: bool - owner_id: int - - -class StudyRoomsUpdate(StudyRoomsBase): - pass - - -class StudyRoomResponse(StudyRoomsBase): - class Config: - orm_mode = True \ No newline at end of file diff --git a/app/service/auth.py b/app/service/auth.py index 0f6ad30..1a6aa9d 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -1,9 +1,9 @@ -from datetime import datetime, timedelta -from typing import Optional - import requests -from fastapi import HTTPException -from jose import jwt, JWTError, ExpiredSignatureError +from datetime import datetime, timedelta +from typing import Optional + +from fastapi import HTTPException +from jose import jwt, JWTError, ExpiredSignatureError from jose.exceptions import JWTClaimsError from app.core import user_settings From 54ab10f88dcdc3e29f981eed596899ffc3343dd4 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 9 May 2021 20:23:53 +0900 Subject: [PATCH 042/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EA=B4=80=EB=A0=A8=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 35 ++++++++++++++++------------ app/crud/study_rooms.py | 47 +++++++++++++++++++------------------- app/schemas/study_rooms.py | 7 +++--- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 08379c1..6436c53 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -1,8 +1,9 @@ -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, status +from fastapi.responses import JSONResponse from sqlalchemy.orm.session import Session +from sqlalchemy.sql.sqltypes import JSON from app.api.deps import get_db -from app.erros.study_rooms import CustomException from app.crud import ( get_study_room, get_study_rooms, @@ -17,36 +18,40 @@ ) - router = APIRouter() @router.get('/{room_id}', response_model=StudyRoomResponse) def get(room_id: str, db: Session = Depends(get_db)): - study_room = get_study_room(db, room_id) - if study_room: - return study_room + data = get_study_room(db, room_id) + if data: + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data, 'message': ''}) else: - raise CustomException(message = 'NOT_FOUND') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'data': data, 'message': 'NOT_FOUND'}) -@router.patch('/{room_id}') +@router.patch('/{room_id}', response_model=StudyRoomResponse) def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): response = update_study_room(db, room_id, room_info) return response -@router.delete('/{room_id}') +@router.delete('/{room_id}', response_model=StudyRoomResponse) def delete(room_id: str, db: Session = Depends(get_db)): - _ = delete_study_room(db, room_id) + response = delete_study_room(db, room_id) + return response -@router.get('') +@router.get('', response_model=StudyRoomResponse) def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): - response = get_study_rooms(db, skip, limit, option) - return response + data = get_study_rooms(db, skip, limit, option) + if data: + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data, 'message': ''}) + else: + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'data': data, 'message': ''}) -@router.post('') +@router.post('', response_model=StudyRoomResponse) def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): - create_study_room(db, rooms) \ No newline at end of file + data = create_study_room(db, rooms) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': '', 'message': ''}) \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index e449d3d..c1dded5 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,20 +1,15 @@ from uuid import UUID -from typing import TypeVar +from typing import Union from fastapi import HTTPException, status from fastapi.encoders import jsonable_encoder -from pydantic import BaseModel from sqlalchemy.orm import Session from app.models import StudyRooms from app.schemas import StudyRoomsCreate, StudyRoomsUpdate -from app.erros.study_rooms.handling import CustomException, NotFoundHandler -ModelSchema = TypeVar('ModelSchema', bound=BaseModel) - - -def password_exception_handler(room_info: ModelSchema): +def password_exception_handler(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): detail = [ { "loc": [ @@ -27,25 +22,25 @@ def password_exception_handler(room_info: ModelSchema): ] if (not room_info.is_public) and (not room_info.password): raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) - else: - pass def get_study_room(db: Session, room_id: str): - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() - if study_room: - return study_room + try: + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() + if study_room: + return jsonable_encoder(study_room) + except: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='ROOM_ID_ERROR') - def get_study_rooms(db: Session, skip: int, limit: int, option: str): study_rooms = db.query(StudyRooms).filter(StudyRooms.current_join_counts < 5).order_by(f'{option}').offset(skip).limit(limit).all() - return study_rooms + if study_rooms: + return jsonable_encoder(study_rooms) + - def create_study_room(db: Session, room_info: StudyRoomsCreate): - print(room_info.is_public) - password_exception_handler(StudyRoomsCreate) + password_exception_handler(room_info) room_info.current_join_counts += 1 response = StudyRooms(**jsonable_encoder(room_info)) db.add(response) @@ -54,11 +49,14 @@ def create_study_room(db: Session, room_info: StudyRoomsCreate): def update_study_room(db: Session, room_id: str, room_info: StudyRoomsUpdate): - password_exception_handler(StudyRoomsUpdate) - update_data = room_info.dict(exclude_none=True) - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) - db.commit() - return study_room + try: + password_exception_handler(room_info) + update_data = room_info.dict(exclude_none=True) + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) + db.commit() + return study_room + except: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='ROOM_ID_ERROR') def delete_study_room(db: Session, room_id: str): @@ -69,6 +67,7 @@ def delete_study_room(db: Session, room_id: str): db.commit() else: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') - except ValueError: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') + except: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='ROOM_ID_ERROR') + \ No newline at end of file diff --git a/app/schemas/study_rooms.py b/app/schemas/study_rooms.py index 59ef5cc..0d1da1f 100644 --- a/app/schemas/study_rooms.py +++ b/app/schemas/study_rooms.py @@ -1,5 +1,5 @@ from uuid import UUID -from typing import Optional, Union +from typing import Optional from pydantic import BaseModel @@ -24,9 +24,10 @@ class StudyRoomsUpdate(BaseModel): password: Optional[str] -class StudyRoomResponse(BaseModel): - data: Union[str, StudyRoomsBase] +class StudyRoomResponse(StudyRoomsBase): + data: Optional[list] message: str + class Config: orm_mode = True schema_extra = { From 0165e572efc834fdb7602024f2d1f4ab5be76064 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 10 May 2021 00:19:36 +0900 Subject: [PATCH 043/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=97=A8=EB=93=A4=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 24 +++---- app/crud/study_rooms.py | 115 +++++++++++++++++++----------- app/erros/__init__.py | 6 ++ app/erros/handling.py | 24 +++++++ app/erros/study_rooms/__init__.py | 2 +- app/erros/study_rooms/handling.py | 32 +++------ app/schemas/__init__.py | 5 +- app/schemas/responses.py | 13 ++++ app/schemas/study_rooms.py | 71 +++++++++++++++--- app/utils/logger.py | 0 10 files changed, 204 insertions(+), 88 deletions(-) create mode 100644 app/erros/handling.py create mode 100644 app/schemas/responses.py create mode 100644 app/utils/logger.py diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 6436c53..f667dd8 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -13,6 +13,8 @@ ) from app.schemas import ( StudyRoomResponse, + GetStudyRoomResponse, + GetStudyRoomsResponse, StudyRoomsCreate, StudyRoomsUpdate ) @@ -21,19 +23,16 @@ router = APIRouter() -@router.get('/{room_id}', response_model=StudyRoomResponse) +@router.get('/{room_id}', response_model=GetStudyRoomResponse) def get(room_id: str, db: Session = Depends(get_db)): data = get_study_room(db, room_id) - if data: - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data, 'message': ''}) - else: - return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'data': data, 'message': 'NOT_FOUND'}) + return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': data}) @router.patch('/{room_id}', response_model=StudyRoomResponse) def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): - response = update_study_room(db, room_id, room_info) - return response + _ = update_study_room(db, room_id, room_info) + return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': ''}) @router.delete('/{room_id}', response_model=StudyRoomResponse) @@ -42,16 +41,13 @@ def delete(room_id: str, db: Session = Depends(get_db)): return response -@router.get('', response_model=StudyRoomResponse) +@router.get('', response_model=GetStudyRoomsResponse) def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): data = get_study_rooms(db, skip, limit, option) - if data: - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data, 'message': ''}) - else: - return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'data': data, 'message': ''}) + return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': data}) @router.post('', response_model=StudyRoomResponse) def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): - data = create_study_room(db, rooms) - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': '', 'message': ''}) \ No newline at end of file + _ = create_study_room(db, rooms) + return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': ''}) \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index c1dded5..a0bca1e 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,44 +1,73 @@ -from uuid import UUID -from typing import Union - -from fastapi import HTTPException, status -from fastapi.encoders import jsonable_encoder -from sqlalchemy.orm import Session - -from app.models import StudyRooms -from app.schemas import StudyRoomsCreate, StudyRoomsUpdate - - -def password_exception_handler(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): - detail = [ - { - "loc": [ - "body", - "password" - ], - "msg": "field required", - "type": "value_error.missing" - } - ] - if (not room_info.is_public) and (not room_info.password): - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) - - -def get_study_room(db: Session, room_id: str): - try: - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() - if study_room: +from uuid import UUID +from typing import Union + +from fastapi import HTTPException, status +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from app.crud.base import CRUDBase +from app.models import StudyRooms +from app.schemas import StudyRoomsCreate, StudyRoomsUpdate + + +class StudyRoomCRUD(CRUDBase[StudyRooms, StudyRoomsCreate, StudyRoomsUpdate]): + def get(self, db: Session, room_id: UUID): + try: + study_room = db.query(self.model).filter(StudyRooms.id == UUID(room_id)).first() return jsonable_encoder(study_room) - except: - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='ROOM_ID_ERROR') - - -def get_study_rooms(db: Session, skip: int, limit: int, option: str): - study_rooms = db.query(StudyRooms).filter(StudyRooms.current_join_counts < 5).order_by(f'{option}').offset(skip).limit(limit).all() - if study_rooms: - return jsonable_encoder(study_rooms) + except ValueError: + + return 'INVALID_UUID' + except: + return 'UNCAUGHT' + + + def get_multi(self, db: Session, *, skip: int, limit: int, option: str): + try: + study_rooms = db.query(self.model).filter( + self.model.current_join_counts < 5 + ).order_by(f'{option}').offset(skip).limit(limit).all() + if study_rooms: + return jsonable_encoder(study_rooms) + else: + not_found_exception_handler() + except: + uncaught_exception_handler() + + + def create(self, db: Session, *, obj_in: StudyRoomsCreate): + return super().create(db, obj_in) - + + def update(self, db: Session, *, room_id: str, room_info: StudyRoomsUpdate): + try: + password_exception_handler(room_info) + update_data = room_info.dict(exclude_none=True) + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) + db.commit() + return study_room + except ValueError: + not_found_exception_handler() + except: + uncaught_exception_handler() + + + def remove(self, db: Session, *, room_id: str): + try: + study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() + if study_room: + db.delete(study_room) + db.commit() + else: + not_found_exception_handler() + except ValueError: + not_found_exception_handler() + except: + uncaught_exception_handler() + + + + def create_study_room(db: Session, room_info: StudyRoomsCreate): password_exception_handler(room_info) room_info.current_join_counts += 1 @@ -55,8 +84,8 @@ def update_study_room(db: Session, room_id: str, room_info: StudyRoomsUpdate): study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) db.commit() return study_room - except: - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='ROOM_ID_ERROR') + except ValueError: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') def delete_study_room(db: Session, room_id: str): @@ -67,7 +96,7 @@ def delete_study_room(db: Session, room_id: str): db.commit() else: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') - except: - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='ROOM_ID_ERROR') + except ValueError: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') \ No newline at end of file diff --git a/app/erros/__init__.py b/app/erros/__init__.py index e69de29..7c7f58d 100644 --- a/app/erros/__init__.py +++ b/app/erros/__init__.py @@ -0,0 +1,6 @@ +from app.erros.study_rooms import password_exception_handler +from app.erros.handling import ( + get_detail, + not_found_exception_handler, + uncaught_exception_handler + ) \ No newline at end of file diff --git a/app/erros/handling.py b/app/erros/handling.py new file mode 100644 index 0000000..ffce6b7 --- /dev/null +++ b/app/erros/handling.py @@ -0,0 +1,24 @@ +from fastapi import status +from fastapi.exceptions import HTTPException + + +def get_detail(param: str, field: str, err: str): + detail = [ + { + 'loc': [ + f'{param}', # ex. body + f'{field}' # ex. + ], + "msg": "field required", + "type": f"{err}.missing" # ex. value_error + } + ] + return detail + + +def not_found_exception_handler(param, field, err): + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=get_detail(param, field, err)) + + +def uncaught_exception_handler(): + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail='server error') diff --git a/app/erros/study_rooms/__init__.py b/app/erros/study_rooms/__init__.py index 65f1c7c..78f705a 100644 --- a/app/erros/study_rooms/__init__.py +++ b/app/erros/study_rooms/__init__.py @@ -1 +1 @@ -from app.erros.study_rooms.handling import CustomException \ No newline at end of file +from app.erros.study_rooms.handling import password_exception_handler \ No newline at end of file diff --git a/app/erros/study_rooms/handling.py b/app/erros/study_rooms/handling.py index 400e8d7..a118e61 100644 --- a/app/erros/study_rooms/handling.py +++ b/app/erros/study_rooms/handling.py @@ -1,28 +1,18 @@ -from fastapi import FastAPI, Request, status, Request -from fastapi.encoders import jsonable_encoder -from fastapi.exceptions import RequestValidationError -from fastapi.responses import JSONResponse +from typing import Union +from fastapi import status +from fastapi.exceptions import HTTPException -app = FastAPI() +from app.schemas import StudyRoomsCreate, StudyRoomsUpdate +from app.erros.handling import get_detail -class CustomException(Exception): - def __init__(self, message: str): - self.message = message +def password_exception_handler(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): + detail = get_detail(param='body', field='password', err='value_error') + if (not room_info.is_public) and (not room_info.password): + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) -@app.exception_handler(RequestValidationError) -def validation_exception_handler(request: Request, exc: RequestValidationError): - loc = exc.errors()[0]['loc'][0].upper() - item = exc.errors()[0]['loc'][1].upper() - return JSONResponse( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, - content=jsonable_encoder({'data': '', 'message': f'ERROR_{item}_IN_{loc}'}) - ) - - -@app.exception_handler(CustomException) -def NotFoundHandler(request: Request, exc: CustomException): - return JSONResponse(status_code = 404, content = {'data': '', 'message': exc.message}) +def invalid_uuid_exception_handler(): + pass diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 44d1169..5c95994 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -3,6 +3,9 @@ StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, - StudyRoomResponse + StudyRoomResponse, + GetStudyRoomResponse, + GetStudyRoomsResponse, + CreateStudyRoomResponse ) diff --git a/app/schemas/responses.py b/app/schemas/responses.py new file mode 100644 index 0000000..fa844df --- /dev/null +++ b/app/schemas/responses.py @@ -0,0 +1,13 @@ +from typing import Union + +from pydantic import BaseModel + +class Response(BaseModel): + data: Union[list, dict, None] + + class Config: + schema_extra = { + 'example': { + 'data': '' + } + } \ No newline at end of file diff --git a/app/schemas/study_rooms.py b/app/schemas/study_rooms.py index 0d1da1f..0a17d85 100644 --- a/app/schemas/study_rooms.py +++ b/app/schemas/study_rooms.py @@ -1,5 +1,5 @@ from uuid import UUID -from typing import Optional +from typing import Optional, Union from pydantic import BaseModel @@ -16,6 +16,17 @@ class StudyRoomsCreate(StudyRoomsBase): password: Optional[str] current_join_counts: int = 0 + class Config: + schema_extra = { + 'example': { + 'title': '주 4시간 이상 고시 공부방 🔥', + 'description': '같이 열심히 공부하실 분들만!', + 'is_public': False, + 'password': 'TestPassword!234', + 'owner_id': 1 + } + } + class StudyRoomsUpdate(BaseModel): title: Optional[str] @@ -25,6 +36,56 @@ class StudyRoomsUpdate(BaseModel): class StudyRoomResponse(StudyRoomsBase): + data: Union[list, dict, None] + + +class GetStudyRoomResponse(StudyRoomResponse): + + class Config: + schema_extra = { + 'example': { + 'data': { + 'title': '주 4시간 이상 고시 공부방 🔥', + 'description': '같이 열심히 공부하실 분들만!', + 'is_public': False, + 'password': 'TestPassword!234', + 'owner_id': 1 + } + } + } + + +class GetStudyRoomsResponse(StudyRoomsBase): + + class Config: + schema_extra = { + 'example': { + 'data': [ + { + "title": "스터디 룸 제목 수정", + "is_public": False, + "password": "Test!234", + "created_at": "2021-05-09T20:50:11.782727", + "description": "스터디룸 설명", + "id": "3d37627c-d87d-469e-8bf3-db7e796838cf", + "current_join_counts": 1, + "owner_id": 1 + }, + { + "title": "스터디룸 생성 제목", + "is_public": True, + "created_at": "2021-05-09T20:50:11.782727", + "description": "스터디룸 설명", + "id": "3b199025-92d7-4214-8f9c-b8224d81fca5", + "current_join_counts": 3, + "owner_id": 1 + } + ] + } + } + + +class CreateStudyRoomResponse(StudyRoomsBase): data: Optional[list] message: str @@ -32,12 +93,6 @@ class Config: orm_mode = True schema_extra = { 'example': { - 'id': 'd7e3a12f-5669-4eb4-96db-b27efc6d96a2', - 'title': '주 4시간 이상 고시 공부방 🔥', - 'description': '같이 열심히 공부하실 분들만!', - 'is_public': False, - 'password': 'TestPassword!234', - 'current_join_counts': 1, - 'owner_id': 1 + 'data': '' } } \ No newline at end of file diff --git a/app/utils/logger.py b/app/utils/logger.py new file mode 100644 index 0000000..e69de29 From c0e048a7d2cfde785903bb36562193b0bc80f0bd Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 11 May 2021 15:29:16 +0900 Subject: [PATCH 044/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EA=B4=80=EB=A0=A8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=97=A8=EB=93=A4=EB=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 197 +++++++++++++++++++++++----- app/crud/study_rooms.py | 138 ++++++++++--------- app/erros/handling.py | 10 +- app/erros/study_rooms/handling.py | 14 +- app/models/study_rooms.py | 2 +- app/schemas/__init__.py | 5 +- app/schemas/responses.py | 25 +++- app/schemas/study_rooms.py | 98 -------------- app/schemas/study_rooms/__init__.py | 11 ++ app/schemas/study_rooms/crud.py | 33 +++++ app/schemas/study_rooms/handling.py | 89 +++++++++++++ app/schemas/study_rooms/success.py | 46 +++++++ app/schemas/users/__init__.py | 3 + app/schemas/users/handling.py | 19 +++ app/tests/conftest.py | 1 - requirements.txt | 17 ++- 16 files changed, 491 insertions(+), 217 deletions(-) delete mode 100644 app/schemas/study_rooms.py create mode 100644 app/schemas/study_rooms/__init__.py create mode 100644 app/schemas/study_rooms/crud.py create mode 100644 app/schemas/study_rooms/handling.py create mode 100644 app/schemas/study_rooms/success.py create mode 100644 app/schemas/users/__init__.py create mode 100644 app/schemas/users/handling.py diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index f667dd8..7eb6c71 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -1,53 +1,188 @@ from fastapi import APIRouter, Depends, status +from fastapi.param_functions import Query from fastapi.responses import JSONResponse from sqlalchemy.orm.session import Session -from sqlalchemy.sql.sqltypes import JSON from app.api.deps import get_db -from app.crud import ( - get_study_room, - get_study_rooms, - create_study_room, - update_study_room, - delete_study_room - ) +from app.crud import study_rooms from app.schemas import ( - StudyRoomResponse, + SuccessResponseBase, + ErrorResponseBase, + StudyRoomsCreate, + StudyRoomsUpdate, GetStudyRoomResponse, GetStudyRoomsResponse, - StudyRoomsCreate, - StudyRoomsUpdate + NotFoundStudyRoomHandling, + PasswordNeedyStudyRoomHandling, + BodyNeedyStudyRoomHandling, + QueryNeedyStudyRoomHandling, + MethodNotAllowedHandling + ) +from app.erros import ( + password_exception_handler, + not_found_exception_handler, + uncaught_exception_handler ) router = APIRouter() -@router.get('/{room_id}', response_model=GetStudyRoomResponse) -def get(room_id: str, db: Session = Depends(get_db)): - data = get_study_room(db, room_id) - return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': data}) +@router.get( + '/{room_id}', + responses = { + 200: { + "model": GetStudyRoomResponse, + "description": "스터디룸 조회 성공" + }, + 404: { + "model": NotFoundStudyRoomHandling, + "description": "조회한 스터디룸이 존재하지 않는 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def get_study_room(room_id: str, db: Session = Depends(get_db)): + response, data = study_rooms.get(db, room_id) + if response == 'SUCCESS': + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + elif response == 'NOT_FOUND_ROOM': + not_found_exception_handler(param='database', field='study room', message='not found', err='database') + elif response == 'UNCAUGHT': + uncaught_exception_handler() + +@router.patch( + '/{room_id}', + responses = { + 200: { + "model": SuccessResponseBase, + "description": "스터디룸 수정 성공" + }, + 404: { + "model": NotFoundStudyRoomHandling, + "description": "수정을 시도한 스터디룸이 이미 존재하지 않는 경우" + }, + 405: { + "model": MethodNotAllowedHandling, + "description": "엔드포인트 경로에 스터디룸 아이디가 넘어오지 않을 경우" + }, + 422: { + "model": PasswordNeedyStudyRoomHandling, + "description": "비공개 스터디룸으로 설정하고 비밀번호를 입력하지 않은 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } -@router.patch('/{room_id}', response_model=StudyRoomResponse) -def update(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): - _ = update_study_room(db, room_id, room_info) - return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': ''}) +) +def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): + response, _ = study_rooms.update(db, room_id, room_info) + if response == 'SUCCESS': + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + elif response == 'NOT_FOUN_ROOM': + not_found_exception_handler(param='database', field='study room', message='not found', err='database') + elif response == 'PASSWORD': + password_exception_handler() + elif response == 'UNCAUGHT': + uncaught_exception_handler() -@router.delete('/{room_id}', response_model=StudyRoomResponse) -def delete(room_id: str, db: Session = Depends(get_db)): - response = delete_study_room(db, room_id) - return response +@router.delete( + '/{room_id}', + responses = { + 200: { + "model": SuccessResponseBase, + "description": "스터디룸 삭제 성공" + }, + 404: { + "model": NotFoundStudyRoomHandling, + "description": "삭제를 시도한 스터디룸이 이미 존재하지 않는 경우" + }, + 405: { + "model": MethodNotAllowedHandling, + "description": "엔드포인트 경로에 스터디룸 아이디가 넘어오지 않을 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def delete_study_room(room_id: str, db: Session = Depends(get_db)): + response, _ = study_rooms.remove(db, room_id) + if response == 'SUCCESS': + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + elif response == 'NOT_FOUND_ROOM': + not_found_exception_handler(param='database', field='study room', message='not found', err='database') + elif response == 'UNCAUGHT': + uncaught_exception_handler() -@router.get('', response_model=GetStudyRoomsResponse) -def get(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): - data = get_study_rooms(db, skip, limit, option) - return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': data}) +@router.get( + '', + responses = { + 200: { + "model": GetStudyRoomsResponse, + "description": "스터디룸 조희 성공" + }, + 404: { + "model": NotFoundStudyRoomHandling, + "description": "조회한 스터디룸이 존재하지 않는 경우" + }, + 422: { + "model": QueryNeedyStudyRoomHandling, + "description": "쿼리 파라미터를 제대로 전달하지 않은 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): + response, data = study_rooms.get_multi(db, skip, limit, option) + if response == 'SUCCESS': + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + elif response == 'NOT_FOUND_ROOM': + not_found_exception_handler(param='database', field='study room', message='not found', err='database') + elif response == 'UNCAUGHT': + uncaught_exception_handler() -@router.post('', response_model=StudyRoomResponse) -def create(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): - _ = create_study_room(db, rooms) - return JSONResponse(status_code=status.HTTP_200_OK, content={'detail': ''}) \ No newline at end of file +@router.post( + '', + responses = { + 200: { + "model": SuccessResponseBase, + "description": "스터디룸 생성 성공" + }, + 404: { + "model": NotFoundStudyRoomHandling, + "description": "방을 만드려는 사용자가 존재하지 않는 경우 (Postman 등을 통한 악용 방지)" + }, + 422: { + "model": BodyNeedyStudyRoomHandling, + "description": "제목, 설명과 같이 필요한 스터디룸 정보를 입력하지 않은 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): + response, _ = study_rooms.create(db, rooms) + if response == 'SUCCESS': + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + elif response == 'NOT_FOUND_USER': + not_found_exception_handler(param='database', field='user', message='not found', err='database') + elif response == 'PASSWORD': + password_exception_handler() + elif response == 'UNCAUGHT': + uncaught_exception_handler() \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index a0bca1e..a933fec 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,102 +1,116 @@ from uuid import UUID from typing import Union -from fastapi import HTTPException, status from fastapi.encoders import jsonable_encoder from sqlalchemy.orm import Session +from sqlalchemy.exc import IntegrityError from app.crud.base import CRUDBase from app.models import StudyRooms from app.schemas import StudyRoomsCreate, StudyRoomsUpdate -class StudyRoomCRUD(CRUDBase[StudyRooms, StudyRoomsCreate, StudyRoomsUpdate]): +def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): + return False if (not room_info.is_public) and (not room_info.password) else True + + +class CRUDStudyRoom(CRUDBase[StudyRooms, StudyRoomsCreate, StudyRoomsUpdate]): def get(self, db: Session, room_id: UUID): try: - study_room = db.query(self.model).filter(StudyRooms.id == UUID(room_id)).first() - return jsonable_encoder(study_room) + study_room = db.query(self.model).filter( + self.model.id == UUID(room_id) + ).with_entities( + self.model.id, + self.model.title, + self.model.description, + self.model.is_public, + self.model.current_join_counts, + self.model.created_at, + self.model.owner_id + ).first() + if study_room: + return 'SUCCESS', jsonable_encoder(study_room) + else: + return 'NOT_FOUND_ROOM', None except ValueError: + return 'NOT_FOUND_ROOM', None + except Exception as error: + print(error) + print(error.__class__.__name__) + return 'UNCAUGHT', None - return 'INVALID_UUID' - except: - return 'UNCAUGHT' - - def get_multi(self, db: Session, *, skip: int, limit: int, option: str): + def get_multi(self, db: Session, skip: int, limit: int, option: str): try: study_rooms = db.query(self.model).filter( self.model.current_join_counts < 5 + ).with_entities( + self.model.id, + self.model.title, + self.model.description, + self.model.is_public, + self.model.current_join_counts, + self.model.created_at, + self.model.owner_id ).order_by(f'{option}').offset(skip).limit(limit).all() if study_rooms: - return jsonable_encoder(study_rooms) + return 'SUCCESS', jsonable_encoder(study_rooms) else: - not_found_exception_handler() - except: - uncaught_exception_handler() + return 'NOT_FOUND_ROOM', None + except Exception as error: + print(error) + print(error.__class__.__name__) + return 'UNCAUGHT', None - def create(self, db: Session, *, obj_in: StudyRoomsCreate): - return super().create(db, obj_in) + def create(self, db: Session, room_info: StudyRoomsCreate): + try: + if not check_password_exist(room_info): + return 'PASSWORD', None + room_info.current_join_counts += 1 + response = self.model(**jsonable_encoder(room_info)) + db.add(response) + db.commit() + return 'SUCCESS', None + except IntegrityError: + return 'NOT_FOUND_USER', None + except Exception as error: + print(error) + print(error.__class__.__name__) + return 'UNCAUGHT', None - def update(self, db: Session, *, room_id: str, room_info: StudyRoomsUpdate): + def update(self, db: Session, room_id: str, room_info: StudyRoomsUpdate): try: - password_exception_handler(room_info) + if not check_password_exist(room_info): + return 'PASSWORD', None update_data = room_info.dict(exclude_none=True) - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) + study_room = db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) db.commit() - return study_room + return 'SUCCESS', study_room except ValueError: - not_found_exception_handler() - except: - uncaught_exception_handler() + return 'NOT_FOUND_ROOM', None + except Exception as error: + print(error) + print(error.__class__.__name__) + return 'UNCAUGHT', None - def remove(self, db: Session, *, room_id: str): + def remove(self, db: Session, room_id: str): try: - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() + study_room = db.query(self.model).filter(self.model.id == UUID(room_id)).first() if study_room: db.delete(study_room) db.commit() + return 'SUCCESS', None else: - not_found_exception_handler() + return 'NOT_FOUND_ROOM', None except ValueError: - not_found_exception_handler() - except: - uncaught_exception_handler() - + return 'NOT_FOUND_ROOM', None + except Exception as error: + print(error) + print(error.__class__.__name__) + return 'UNCAUGHT', None - -def create_study_room(db: Session, room_info: StudyRoomsCreate): - password_exception_handler(room_info) - room_info.current_join_counts += 1 - response = StudyRooms(**jsonable_encoder(room_info)) - db.add(response) - db.commit() - return response - - -def update_study_room(db: Session, room_id: str, room_info: StudyRoomsUpdate): - try: - password_exception_handler(room_info) - update_data = room_info.dict(exclude_none=True) - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).update(update_data) - db.commit() - return study_room - except ValueError: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') - - -def delete_study_room(db: Session, room_id: str): - try: - study_room = db.query(StudyRooms).filter(StudyRooms.id == UUID(room_id)).first() - if study_room: - db.delete(study_room) - db.commit() - else: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') - except ValueError: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='NOT_FOUND') - - \ No newline at end of file +study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file diff --git a/app/erros/handling.py b/app/erros/handling.py index ffce6b7..184bef5 100644 --- a/app/erros/handling.py +++ b/app/erros/handling.py @@ -2,22 +2,22 @@ from fastapi.exceptions import HTTPException -def get_detail(param: str, field: str, err: str): +def get_detail(param: str, field: str, message: str, err: str): detail = [ { 'loc': [ f'{param}', # ex. body - f'{field}' # ex. + f'{field}' # ex. title ], - "msg": "field required", + "msg": message, # ex. field required, not found "type": f"{err}.missing" # ex. value_error } ] return detail -def not_found_exception_handler(param, field, err): - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=get_detail(param, field, err)) +def not_found_exception_handler(param, field, message, err): + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=get_detail(param, field, message, err)) def uncaught_exception_handler(): diff --git a/app/erros/study_rooms/handling.py b/app/erros/study_rooms/handling.py index a118e61..60658bc 100644 --- a/app/erros/study_rooms/handling.py +++ b/app/erros/study_rooms/handling.py @@ -1,18 +1,10 @@ -from typing import Union - from fastapi import status from fastapi.exceptions import HTTPException -from app.schemas import StudyRoomsCreate, StudyRoomsUpdate from app.erros.handling import get_detail -def password_exception_handler(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): - detail = get_detail(param='body', field='password', err='value_error') - if (not room_info.is_public) and (not room_info.password): - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) - - -def invalid_uuid_exception_handler(): - pass +def password_exception_handler(): + detail = get_detail(param='body', field='password', message='field required' ,err='value_error') + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index fd325e7..f618df5 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -23,4 +23,4 @@ class StudyRooms(Base): current_join_counts = Column(SmallInteger(), nullable=False, default=0) created_at = Column(DateTime(), default=KOR_NOW) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) - owner = relation('User', back_populates = "study_rooms") \ No newline at end of file + owner = relation('User', back_populates = "study_rooms") diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 5c95994..44d1169 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -3,9 +3,6 @@ StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, - StudyRoomResponse, - GetStudyRoomResponse, - GetStudyRoomsResponse, - CreateStudyRoomResponse + StudyRoomResponse ) diff --git a/app/schemas/responses.py b/app/schemas/responses.py index fa844df..2fec137 100644 --- a/app/schemas/responses.py +++ b/app/schemas/responses.py @@ -1,8 +1,9 @@ -from typing import Union +from typing import Union from pydantic import BaseModel -class Response(BaseModel): + +class SuccessResponseBase(BaseModel): data: Union[list, dict, None] class Config: @@ -10,4 +11,24 @@ class Config: 'example': { 'data': '' } + } + + +class ErrorResponseBase(BaseModel): + detail: Union[dict, str] + + class Config: + schema_extra = { + 'example': { + 'detail': 'server error' + } + } + + +class MethodNotAllowedHandling(ErrorResponseBase): + class Config: + schema_extra = { + "example": { + "detail": "Method Not Allowed" + } } \ No newline at end of file diff --git a/app/schemas/study_rooms.py b/app/schemas/study_rooms.py deleted file mode 100644 index 0a17d85..0000000 --- a/app/schemas/study_rooms.py +++ /dev/null @@ -1,98 +0,0 @@ -from uuid import UUID -from typing import Optional, Union - -from pydantic import BaseModel - - -class StudyRoomsBase(BaseModel): - title: str - description: str - is_public: bool - current_join_counts: int - owner_id: int - - -class StudyRoomsCreate(StudyRoomsBase): - password: Optional[str] - current_join_counts: int = 0 - - class Config: - schema_extra = { - 'example': { - 'title': '주 4시간 이상 고시 공부방 🔥', - 'description': '같이 열심히 공부하실 분들만!', - 'is_public': False, - 'password': 'TestPassword!234', - 'owner_id': 1 - } - } - - -class StudyRoomsUpdate(BaseModel): - title: Optional[str] - description: Optional[str] - is_public: Optional[bool] - password: Optional[str] - - -class StudyRoomResponse(StudyRoomsBase): - data: Union[list, dict, None] - - -class GetStudyRoomResponse(StudyRoomResponse): - - class Config: - schema_extra = { - 'example': { - 'data': { - 'title': '주 4시간 이상 고시 공부방 🔥', - 'description': '같이 열심히 공부하실 분들만!', - 'is_public': False, - 'password': 'TestPassword!234', - 'owner_id': 1 - } - } - } - - -class GetStudyRoomsResponse(StudyRoomsBase): - - class Config: - schema_extra = { - 'example': { - 'data': [ - { - "title": "스터디 룸 제목 수정", - "is_public": False, - "password": "Test!234", - "created_at": "2021-05-09T20:50:11.782727", - "description": "스터디룸 설명", - "id": "3d37627c-d87d-469e-8bf3-db7e796838cf", - "current_join_counts": 1, - "owner_id": 1 - }, - { - "title": "스터디룸 생성 제목", - "is_public": True, - "created_at": "2021-05-09T20:50:11.782727", - "description": "스터디룸 설명", - "id": "3b199025-92d7-4214-8f9c-b8224d81fca5", - "current_join_counts": 3, - "owner_id": 1 - } - ] - } - } - - -class CreateStudyRoomResponse(StudyRoomsBase): - data: Optional[list] - message: str - - class Config: - orm_mode = True - schema_extra = { - 'example': { - 'data': '' - } - } \ No newline at end of file diff --git a/app/schemas/study_rooms/__init__.py b/app/schemas/study_rooms/__init__.py new file mode 100644 index 0000000..445b38e --- /dev/null +++ b/app/schemas/study_rooms/__init__.py @@ -0,0 +1,11 @@ +from app.schemas.study_rooms.crud import StudyRoomsCreate, StudyRoomsUpdate +from app.schemas.study_rooms.success import ( + GetStudyRoomResponse, + GetStudyRoomsResponse + ) +from app.schemas.study_rooms.handling import ( + NotFoundStudyRoomHandling, + PasswordNeedyStudyRoomHandling, + BodyNeedyStudyRoomHandling, + QueryNeedyStudyRoomHandling + ) \ No newline at end of file diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py new file mode 100644 index 0000000..105d0dd --- /dev/null +++ b/app/schemas/study_rooms/crud.py @@ -0,0 +1,33 @@ +from typing import Optional + +from pydantic import BaseModel + + +class StudyRoomsBase(BaseModel): + title: str + description: str + is_public: bool + password: Optional[str] + + +class StudyRoomsCreate(StudyRoomsBase): + current_join_counts: int = 0 + owner_id: int + + class Config: + schema_extra = { + 'example': { + 'title': '주 4시간 이상 고시 공부방 🔥', + 'description': '같이 열심히 공부하실 분들만!', + 'is_public': False, + 'password': 'TestPassword!234', + 'owner_id': 1 + } + } + + +class StudyRoomsUpdate(StudyRoomsBase): + title: Optional[str] + description: Optional[str] + is_public: Optional[bool] + password: Optional[str] \ No newline at end of file diff --git a/app/schemas/study_rooms/handling.py b/app/schemas/study_rooms/handling.py new file mode 100644 index 0000000..42ca86a --- /dev/null +++ b/app/schemas/study_rooms/handling.py @@ -0,0 +1,89 @@ +from app.schemas.responses import ErrorResponseBase + + +class NotFoundStudyRoomHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "study room" + ], + "msg": "not found", + "type": "database.missing" + } + ] + } + } + + +class PasswordNeedyStudyRoomHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "body", + "password" + ], + "msg": "field required", + "type": "value_error.missing" + } + ] + } + } + + +class BodyNeedyStudyRoomHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "body", + "title" + ], + "msg": "field required", + "type": "value_error.missing" + }, + { + "loc": [ + "body", + "description" + ], + "msg": "field required", + "type": "value_error.missing" + } + ] + } + } + + +class QueryNeedyStudyRoomHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "query", + "skip" + ], + "msg": "field required", + "type": "value_error.missing" + }, + { + "loc": [ + "query", + "limit" + ], + "msg": "field required", + "type": "value_error.missing" + } + ] + } + } \ No newline at end of file diff --git a/app/schemas/study_rooms/success.py b/app/schemas/study_rooms/success.py new file mode 100644 index 0000000..02e5136 --- /dev/null +++ b/app/schemas/study_rooms/success.py @@ -0,0 +1,46 @@ +from app.schemas.responses import SuccessResponseBase + + +class GetStudyRoomResponse(SuccessResponseBase): + class Config: + schema_extra = { + 'example': { + 'data': { + "is_public": False, + "title": "스터디 룸 제목 수정", + "created_at": "2021-05-09T20:50:11.782727", + "id": "3d37627c-d87d-469e-8bf3-db7e796838cf", + "description": "스터디룸 설명", + "current_join_counts": 1, + "owner_id": 1 + } + } + } + + +class GetStudyRoomsResponse(SuccessResponseBase): + class Config: + schema_extra = { + 'example': { + 'data': [ + { + "title": "스터디 룸 제목 수정", + "is_public": False, + "created_at": "2021-05-09T20:50:11.782727", + "description": "스터디룸 설명", + "id": "3d37627c-d87d-469e-8bf3-db7e796838cf", + "current_join_counts": 1, + "owner_id": 1 + }, + { + "title": "스터디룸 생성 제목", + "is_public": True, + "created_at": "2021-05-09T20:50:11.782727", + "description": "스터디룸 설명", + "id": "3b199025-92d7-4214-8f9c-b8224d81fca5", + "current_join_counts": 3, + "owner_id": 1 + } + ] + } + } \ No newline at end of file diff --git a/app/schemas/users/__init__.py b/app/schemas/users/__init__.py new file mode 100644 index 0000000..6351393 --- /dev/null +++ b/app/schemas/users/__init__.py @@ -0,0 +1,3 @@ +from app.schemas.users.handling import ( + NotFoundUserHandling + ) \ No newline at end of file diff --git a/app/schemas/users/handling.py b/app/schemas/users/handling.py new file mode 100644 index 0000000..a218d00 --- /dev/null +++ b/app/schemas/users/handling.py @@ -0,0 +1,19 @@ +from app.schemas.responses import ErrorResponseBase + + +class NotFoundUserHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "study room" + ], + "msg": "not found", + "type": "database.missing" + } + ] + } + } \ No newline at end of file diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 2938e00..db230e6 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -27,7 +27,6 @@ def client(): app.dependency_overrides[get_db] = overried_get_db - def test_user() -> Dict[str, str]: return { "id": 1, diff --git a/requirements.txt b/requirements.txt index 86fdfdf..93f5151 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ chardet==4.0.0 click==7.1.2 cryptography==3.4.7 ecdsa==0.14.1 -fastapi==0.63.0 +fastapi==0.65.0 greenlet==1.0.0 h11==0.12.0 idna==2.10 @@ -16,17 +16,30 @@ MarkupSafe==1.1.1 packaging==20.9 pluggy==0.13.1 psycopg2==2.8.6 +<<<<<<< HEAD py==1.10.0 +======= +psycopg2-binary==2.8.6 +py==1.10.0 +pyasn1==0.4.8 +pycparser==2.20 +>>>>>>> 109f5bc... 수정: 스터디룸 관련 코드 리팩토링 및 에러 헨들링 추가 pydantic==1.8.1 pyparsing==2.4.7 pytest==6.2.4 python-dateutil==2.8.1 python-dotenv==0.17.1 python-editor==1.0.4 +<<<<<<< HEAD +requests==2.25.1 +======= +python-jose==3.2.0 requests==2.25.1 +rsa==4.7.2 +>>>>>>> 109f5bc... 수정: 스터디룸 관련 코드 리팩토링 및 에러 헨들링 추가 six==1.16.0 SQLAlchemy==1.4.6 -starlette==0.13.6 +starlette==0.14.2 toml==0.10.2 typing-extensions==3.7.4.3 urllib3==1.26.4 From cf4fefeff1305de3fabe5ed7011aeb9325091dd8 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 11 May 2021 15:37:19 +0900 Subject: [PATCH 045/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Update=20Schema?= =?UTF-8?q?=20=EC=98=88=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/study_rooms/crud.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index 105d0dd..a34dd72 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -30,4 +30,13 @@ class StudyRoomsUpdate(StudyRoomsBase): title: Optional[str] description: Optional[str] is_public: Optional[bool] - password: Optional[str] \ No newline at end of file + password: Optional[str] + + class Config: + schema_extra = { + 'example': { + 'description': '매일 매일 캠 스터디 가능하신 분들만!', + 'is_public': False, + 'password': 'TestPassword!234' + } + } \ No newline at end of file From 46d3786472ec171181c74e03fe93f3e0f3611cf2 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 12 May 2021 20:30:55 +0900 Subject: [PATCH 046/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=97=90=EB=9F=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 109 ++++++++++++++++++------------ app/core/config.py | 12 ++-- app/crud/__init__.py | 8 +-- app/crud/study_rooms.py | 70 +++++++++++-------- app/erros/__init__.py | 7 +- app/erros/customs.py | 39 +++++++++++ app/erros/handling.py | 24 ------- app/erros/study_rooms/__init__.py | 1 - app/erros/study_rooms/handling.py | 10 --- app/schemas/__init__.py | 16 ++++- 10 files changed, 170 insertions(+), 126 deletions(-) create mode 100644 app/erros/customs.py delete mode 100644 app/erros/handling.py delete mode 100644 app/erros/study_rooms/__init__.py delete mode 100644 app/erros/study_rooms/handling.py diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 7eb6c71..b631ac9 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -1,5 +1,4 @@ from fastapi import APIRouter, Depends, status -from fastapi.param_functions import Query from fastapi.responses import JSONResponse from sqlalchemy.orm.session import Session @@ -19,9 +18,9 @@ MethodNotAllowedHandling ) from app.erros import ( - password_exception_handler, - not_found_exception_handler, - uncaught_exception_handler + get_detail, + NoSuchElementException, + InvalidArgumentException ) @@ -46,13 +45,17 @@ } ) def get_study_room(room_id: str, db: Session = Depends(get_db)): - response, data = study_rooms.get(db, room_id) - if response == 'SUCCESS': + try: + data = study_rooms.get(db, room_id) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) - elif response == 'NOT_FOUND_ROOM': - not_found_exception_handler(param='database', field='study room', message='not found', err='database') - elif response == 'UNCAUGHT': - uncaught_exception_handler() + + except NoSuchElementException as error: + message = error.message + detail = get_detail(param='database', field='study room', message=message, err='database') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + + except Exception: + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @router.patch( @@ -82,15 +85,22 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): ) def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): - response, _ = study_rooms.update(db, room_id, room_info) - if response == 'SUCCESS': - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) - elif response == 'NOT_FOUN_ROOM': - not_found_exception_handler(param='database', field='study room', message='not found', err='database') - elif response == 'PASSWORD': - password_exception_handler() - elif response == 'UNCAUGHT': - uncaught_exception_handler() + try: + data = study_rooms.update(db, room_id, room_info) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + + except InvalidArgumentException as argument_err: + message = argument_err + detail = get_detail(param='body', field='password', message=message, err='value_error') + return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={'detail': detail}) + + except NoSuchElementException as element_err: + message = element_err + detail = get_detail(param='database', field='study room', message=message, err='database') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + + except Exception: + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @router.delete( @@ -115,14 +125,18 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D } ) def delete_study_room(room_id: str, db: Session = Depends(get_db)): - response, _ = study_rooms.remove(db, room_id) - if response == 'SUCCESS': - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) - elif response == 'NOT_FOUND_ROOM': - not_found_exception_handler(param='database', field='study room', message='not found', err='database') - elif response == 'UNCAUGHT': - uncaught_exception_handler() - + try: + data = study_rooms.remove(db, room_id) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail(param='database', field='study room', message=message, err='database') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + + except Exception: + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) + @router.get( '', @@ -146,13 +160,17 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): } ) def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): - response, data = study_rooms.get_multi(db, skip, limit, option) - if response == 'SUCCESS': + try: + data = study_rooms.get_multi(db, skip, limit, option) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) - elif response == 'NOT_FOUND_ROOM': - not_found_exception_handler(param='database', field='study room', message='not found', err='database') - elif response == 'UNCAUGHT': - uncaught_exception_handler() + + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail(param='database', field='user', message=message, err='database') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + + except Exception: + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @router.post( @@ -177,12 +195,19 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session } ) def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): - response, _ = study_rooms.create(db, rooms) - if response == 'SUCCESS': - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) - elif response == 'NOT_FOUND_USER': - not_found_exception_handler(param='database', field='user', message='not found', err='database') - elif response == 'PASSWORD': - password_exception_handler() - elif response == 'UNCAUGHT': - uncaught_exception_handler() \ No newline at end of file + try: + data = study_rooms.create(db, rooms) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + + except InvalidArgumentException as argument_err: + message = argument_err.message + detail = get_detail(param='body', field='password', message=message, err='value_error') + return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={'detail': detail}) + + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail(param='database', field='user', message='not found', err='database') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + + except Exception: + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index 67816a0..ba57d35 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -13,10 +13,6 @@ class Config: env_file = ".env" -class StudyRoomSettings(BaseSettings): - API_STUDY_ROOM: str = '/study-rooms' - - class UserSettings(BaseSettings): API_USER: str = '/user' SECRET_KEY: str = secrets.token_urlsafe(32) @@ -24,6 +20,10 @@ class UserSettings(BaseSettings): ACCESS_TOKEN_EXPIRE_MINUTES = 30 -common_settings = CommonSettings() +class StudyRoomSettings(BaseSettings): + API_STUDY_ROOM: str = '/study-rooms' + + +common_settings = CommonSettings() +user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() -user_settings = UserSettings() diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 70de615..531c8ea 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,9 +1,3 @@ from app.crud.user import user -from app.crud.study_rooms import ( - get_study_room, - get_study_rooms, - create_study_room, - update_study_room, - delete_study_room - ) +from app.crud.study_rooms import study_rooms diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index a933fec..5c7e3ee 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -8,6 +8,7 @@ from app.crud.base import CRUDBase from app.models import StudyRooms from app.schemas import StudyRoomsCreate, StudyRoomsUpdate +from app.erros import NoSuchElementException, InvalidArgumentException def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): @@ -17,7 +18,7 @@ def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): class CRUDStudyRoom(CRUDBase[StudyRooms, StudyRoomsCreate, StudyRoomsUpdate]): def get(self, db: Session, room_id: UUID): try: - study_room = db.query(self.model).filter( + data = db.query(self.model).filter( self.model.id == UUID(room_id) ).with_entities( self.model.id, @@ -28,21 +29,23 @@ def get(self, db: Session, room_id: UUID): self.model.created_at, self.model.owner_id ).first() - if study_room: - return 'SUCCESS', jsonable_encoder(study_room) + if data: + return '' else: - return 'NOT_FOUND_ROOM', None + raise NoSuchElementException(message='not found') + except ValueError: - return 'NOT_FOUND_ROOM', None + raise NoSuchElementException(message='not found') + except Exception as error: print(error) print(error.__class__.__name__) - return 'UNCAUGHT', None + raise Exception def get_multi(self, db: Session, skip: int, limit: int, option: str): try: - study_rooms = db.query(self.model).filter( + data = db.query(self.model).filter( self.model.current_join_counts < 5 ).with_entities( self.model.id, @@ -53,64 +56,73 @@ def get_multi(self, db: Session, skip: int, limit: int, option: str): self.model.created_at, self.model.owner_id ).order_by(f'{option}').offset(skip).limit(limit).all() - if study_rooms: - return 'SUCCESS', jsonable_encoder(study_rooms) + if data: + return jsonable_encoder(data) else: - return 'NOT_FOUND_ROOM', None + raise NoSuchElementException(message='not found') + except Exception as error: print(error) print(error.__class__.__name__) - return 'UNCAUGHT', None + raise Exception def create(self, db: Session, room_info: StudyRoomsCreate): try: if not check_password_exist(room_info): - return 'PASSWORD', None + raise InvalidArgumentException(message='filed required') + room_info.current_join_counts += 1 - response = self.model(**jsonable_encoder(room_info)) - db.add(response) + data = self.model(**jsonable_encoder(room_info)) + db.add(data) db.commit() - return 'SUCCESS', None + return '' + except IntegrityError: - return 'NOT_FOUND_USER', None + raise NoSuchElementException(message='not found') + except Exception as error: print(error) print(error.__class__.__name__) - return 'UNCAUGHT', None + raise Exception def update(self, db: Session, room_id: str, room_info: StudyRoomsUpdate): try: if not check_password_exist(room_info): - return 'PASSWORD', None + raise InvalidArgumentException(message='filed required') + update_data = room_info.dict(exclude_none=True) - study_room = db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) + db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) db.commit() - return 'SUCCESS', study_room + return '' + except ValueError: - return 'NOT_FOUND_ROOM', None + raise NoSuchElementException(message='not found') + except Exception as error: print(error) print(error.__class__.__name__) - return 'UNCAUGHT', None + raise Exception def remove(self, db: Session, room_id: str): try: - study_room = db.query(self.model).filter(self.model.id == UUID(room_id)).first() - if study_room: - db.delete(study_room) + data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() + if data: + db.delete(data) db.commit() - return 'SUCCESS', None + return '' else: - return 'NOT_FOUND_ROOM', None + raise NoSuchElementException(message='not found') + except ValueError: - return 'NOT_FOUND_ROOM', None + raise NoSuchElementException(message='not fund') + except Exception as error: print(error) print(error.__class__.__name__) - return 'UNCAUGHT', None + raise Exception study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file diff --git a/app/erros/__init__.py b/app/erros/__init__.py index 7c7f58d..405d0cc 100644 --- a/app/erros/__init__.py +++ b/app/erros/__init__.py @@ -1,6 +1,5 @@ -from app.erros.study_rooms import password_exception_handler -from app.erros.handling import ( +from app.erros.customs import ( get_detail, - not_found_exception_handler, - uncaught_exception_handler + NoSuchElementException, + InvalidArgumentException ) \ No newline at end of file diff --git a/app/erros/customs.py b/app/erros/customs.py new file mode 100644 index 0000000..4fc99cd --- /dev/null +++ b/app/erros/customs.py @@ -0,0 +1,39 @@ +def get_detail(param: str, field: str, message: str, err: str): + detail = [ + { + 'loc': [ + f'{param}', # ex. body + f'{field}' # ex. title + ], + "msg": message, # ex. field required, not found + "type": f"{err}.missing" # ex. value_error + } + ] + return detail + + +class NoSuchElementException(Exception): + def __init__(self, message): + self.message = message + + + def __str__(self): + return self.message + + +class InvalidArgumentException(Exception): + def __init__(self, message): + self.message = message + + + def __str__(self): + return self.message + + + def get_response(self): + return create_detail( + param = self.param, + field = self.field, + message = self.message, + error = self.error + ) \ No newline at end of file diff --git a/app/erros/handling.py b/app/erros/handling.py deleted file mode 100644 index 184bef5..0000000 --- a/app/erros/handling.py +++ /dev/null @@ -1,24 +0,0 @@ -from fastapi import status -from fastapi.exceptions import HTTPException - - -def get_detail(param: str, field: str, message: str, err: str): - detail = [ - { - 'loc': [ - f'{param}', # ex. body - f'{field}' # ex. title - ], - "msg": message, # ex. field required, not found - "type": f"{err}.missing" # ex. value_error - } - ] - return detail - - -def not_found_exception_handler(param, field, message, err): - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=get_detail(param, field, message, err)) - - -def uncaught_exception_handler(): - raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail='server error') diff --git a/app/erros/study_rooms/__init__.py b/app/erros/study_rooms/__init__.py deleted file mode 100644 index 78f705a..0000000 --- a/app/erros/study_rooms/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from app.erros.study_rooms.handling import password_exception_handler \ No newline at end of file diff --git a/app/erros/study_rooms/handling.py b/app/erros/study_rooms/handling.py deleted file mode 100644 index 60658bc..0000000 --- a/app/erros/study_rooms/handling.py +++ /dev/null @@ -1,10 +0,0 @@ -from fastapi import status -from fastapi.exceptions import HTTPException - -from app.erros.handling import get_detail - - -def password_exception_handler(): - detail = get_detail(param='body', field='password', message='field required' ,err='value_error') - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail) - diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 44d1169..844e523 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,8 +1,18 @@ from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse +from app.schemas.responses import ( + SuccessResponseBase, + ErrorResponseBase, + MethodNotAllowedHandling + ) +from app.schemas.users import NotFoundUserHandling from app.schemas.study_rooms import ( - StudyRoomsBase, StudyRoomsCreate, StudyRoomsUpdate, - StudyRoomResponse - ) + GetStudyRoomResponse, + GetStudyRoomsResponse, + NotFoundStudyRoomHandling, + PasswordNeedyStudyRoomHandling, + BodyNeedyStudyRoomHandling, + QueryNeedyStudyRoomHandling + ) From f89748741c397c127abfece093ab721ab8eabc2a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 12 May 2021 21:31:44 +0900 Subject: [PATCH 047/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EB=AA=A8?= =?UTF-8?q?=ED=98=B8=ED=95=9C=20return=20value=20=EB=B0=8F=20CRUD,=20API?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20?= =?UTF-8?q?-=20=EA=B8=B0=EC=A1=B4=20else=EC=97=90=EC=84=9C=20raise?= =?UTF-8?q?=ED=95=9C=20error=EA=B0=80=20=ED=95=B4=EB=8B=B9=20=EB=B8=94?= =?UTF-8?q?=EB=9D=BD=20=EB=82=B4=EC=9D=98=20Exception=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9E=A1=ED=9E=88=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20=EB=95=8C?= =?UTF-8?q?=EB=AC=B8=EC=97=90=20CRUD=20=EB=82=B4=20Exception=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 27 ++++++++++------ app/crud/study_rooms.py | 68 +++++++++++++---------------------------- app/erros/__init__.py | 1 + app/erros/customs.py | 9 ++++++ requirements.txt | 8 ----- 5 files changed, 48 insertions(+), 65 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index b631ac9..ccb2a52 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -1,3 +1,5 @@ +import traceback + from fastapi import APIRouter, Depends, status from fastapi.responses import JSONResponse from sqlalchemy.orm.session import Session @@ -49,12 +51,13 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): data = study_rooms.get(db, room_id) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) - except NoSuchElementException as error: - message = error.message + except NoSuchElementException as element_err: + message = element_err.message detail = get_detail(param='database', field='study room', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) except Exception: + print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @@ -86,20 +89,21 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): ) def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): try: - data = study_rooms.update(db, room_id, room_info) - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + study_rooms.update(db, room_id, room_info) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) except InvalidArgumentException as argument_err: - message = argument_err + message = argument_err.message detail = get_detail(param='body', field='password', message=message, err='value_error') return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={'detail': detail}) except NoSuchElementException as element_err: - message = element_err + message = element_err.message detail = get_detail(param='database', field='study room', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) except Exception: + print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @@ -126,8 +130,8 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D ) def delete_study_room(room_id: str, db: Session = Depends(get_db)): try: - data = study_rooms.remove(db, room_id) - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + study_rooms.remove(db, room_id) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) except NoSuchElementException as element_err: message = element_err.message @@ -135,6 +139,7 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) except Exception: + print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @@ -170,6 +175,7 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) except Exception: + print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) @@ -196,8 +202,8 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session ) def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): try: - data = study_rooms.create(db, rooms) - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) + study_rooms.create(db, rooms) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) except InvalidArgumentException as argument_err: message = argument_err.message @@ -210,4 +216,5 @@ def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) except Exception: + print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 5c7e3ee..4ff1ec8 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -30,41 +30,30 @@ def get(self, db: Session, room_id: UUID): self.model.owner_id ).first() if data: - return '' + return data else: raise NoSuchElementException(message='not found') except ValueError: raise NoSuchElementException(message='not found') - except Exception as error: - print(error) - print(error.__class__.__name__) - raise Exception - def get_multi(self, db: Session, skip: int, limit: int, option: str): - try: - data = db.query(self.model).filter( - self.model.current_join_counts < 5 - ).with_entities( - self.model.id, - self.model.title, - self.model.description, - self.model.is_public, - self.model.current_join_counts, - self.model.created_at, - self.model.owner_id - ).order_by(f'{option}').offset(skip).limit(limit).all() - if data: - return jsonable_encoder(data) - else: - raise NoSuchElementException(message='not found') - - except Exception as error: - print(error) - print(error.__class__.__name__) - raise Exception + data = db.query(self.model).filter( + self.model.current_join_counts < 5 + ).with_entities( + self.model.id, + self.model.title, + self.model.description, + self.model.is_public, + self.model.current_join_counts, + self.model.created_at, + self.model.owner_id + ).order_by(f'{option}').offset(skip).limit(limit).all() + if data: + return jsonable_encoder(data) + else: + raise NoSuchElementException(message='not found') def create(self, db: Session, room_info: StudyRoomsCreate): @@ -76,16 +65,10 @@ def create(self, db: Session, room_info: StudyRoomsCreate): data = self.model(**jsonable_encoder(room_info)) db.add(data) db.commit() - return '' except IntegrityError: raise NoSuchElementException(message='not found') - except Exception as error: - print(error) - print(error.__class__.__name__) - raise Exception - def update(self, db: Session, room_id: str, room_info: StudyRoomsUpdate): try: @@ -93,18 +76,15 @@ def update(self, db: Session, room_id: str, room_info: StudyRoomsUpdate): raise InvalidArgumentException(message='filed required') update_data = room_info.dict(exclude_none=True) - db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) - db.commit() - return '' + data = db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) + if data: + db.commit() + else: + raise NoSuchElementException(message='not found') except ValueError: raise NoSuchElementException(message='not found') - except Exception as error: - print(error) - print(error.__class__.__name__) - raise Exception - def remove(self, db: Session, room_id: str): try: @@ -112,17 +92,11 @@ def remove(self, db: Session, room_id: str): if data: db.delete(data) db.commit() - return '' else: raise NoSuchElementException(message='not found') except ValueError: raise NoSuchElementException(message='not fund') - except Exception as error: - print(error) - print(error.__class__.__name__) - raise Exception - study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file diff --git a/app/erros/__init__.py b/app/erros/__init__.py index 405d0cc..72f1e7c 100644 --- a/app/erros/__init__.py +++ b/app/erros/__init__.py @@ -1,5 +1,6 @@ from app.erros.customs import ( get_detail, + InternalException, NoSuchElementException, InvalidArgumentException ) \ No newline at end of file diff --git a/app/erros/customs.py b/app/erros/customs.py index 4fc99cd..99da24a 100644 --- a/app/erros/customs.py +++ b/app/erros/customs.py @@ -12,6 +12,15 @@ def get_detail(param: str, field: str, message: str, err: str): return detail +class InternalException(Exception): + def __init__(self, message): + self.message = message + + + def __str__(self): + return self.message + + class NoSuchElementException(Exception): def __init__(self, message): self.message = message diff --git a/requirements.txt b/requirements.txt index 93f5151..2a69587 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,27 +16,19 @@ MarkupSafe==1.1.1 packaging==20.9 pluggy==0.13.1 psycopg2==2.8.6 -<<<<<<< HEAD -py==1.10.0 -======= psycopg2-binary==2.8.6 py==1.10.0 pyasn1==0.4.8 pycparser==2.20 ->>>>>>> 109f5bc... 수정: 스터디룸 관련 코드 리팩토링 및 에러 헨들링 추가 pydantic==1.8.1 pyparsing==2.4.7 pytest==6.2.4 python-dateutil==2.8.1 python-dotenv==0.17.1 python-editor==1.0.4 -<<<<<<< HEAD -requests==2.25.1 -======= python-jose==3.2.0 requests==2.25.1 rsa==4.7.2 ->>>>>>> 109f5bc... 수정: 스터디룸 관련 코드 리팩토링 및 에러 헨들링 추가 six==1.16.0 SQLAlchemy==1.4.6 starlette==0.14.2 From df6fea858bf2ba405d4243e527911207cd9db0d8 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 12 May 2021 23:09:15 +0900 Subject: [PATCH 048/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EB=B0=8F=20=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8?= =?UTF-8?q?=ED=8A=B8=EC=97=90=20=EC=9E=A1=ED=9E=88=EC=A7=80=20=EB=AA=BB?= =?UTF-8?q?=ED=95=9C=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 20 ++++++++++---------- app/crud/study_rooms.py | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index ccb2a52..9dc0216 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -56,9 +56,9 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): detail = get_detail(param='database', field='study room', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) - except Exception: + except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) @router.patch( @@ -102,9 +102,9 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D detail = get_detail(param='database', field='study room', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) - except Exception: + except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) @router.delete( @@ -138,9 +138,9 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): detail = get_detail(param='database', field='study room', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) - except Exception: + except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) @router.get( @@ -174,9 +174,9 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session detail = get_detail(param='database', field='user', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) - except Exception: + except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) @router.post( @@ -215,6 +215,6 @@ def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): detail = get_detail(param='database', field='user', message='not found', err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) - except Exception: + except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': 'server error'}) \ No newline at end of file + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 4ff1ec8..c48fa6b 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -59,7 +59,7 @@ def get_multi(self, db: Session, skip: int, limit: int, option: str): def create(self, db: Session, room_info: StudyRoomsCreate): try: if not check_password_exist(room_info): - raise InvalidArgumentException(message='filed required') + raise InvalidArgumentException(message='field required') room_info.current_join_counts += 1 data = self.model(**jsonable_encoder(room_info)) @@ -73,7 +73,7 @@ def create(self, db: Session, room_info: StudyRoomsCreate): def update(self, db: Session, room_id: str, room_info: StudyRoomsUpdate): try: if not check_password_exist(room_info): - raise InvalidArgumentException(message='filed required') + raise InvalidArgumentException(message='field required') update_data = room_info.dict(exclude_none=True) data = db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) From 980494387c1982afbfb1abfa50c8d96b15c1be7d Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 12 May 2021 23:14:27 +0900 Subject: [PATCH 049/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index c48fa6b..c540d77 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -96,7 +96,7 @@ def remove(self, db: Session, room_id: str): raise NoSuchElementException(message='not found') except ValueError: - raise NoSuchElementException(message='not fund') + raise NoSuchElementException(message='not found') study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file From a0beee3a3e003bf3933c13b703fde222f2f42554 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sat, 15 May 2021 23:51:04 +0900 Subject: [PATCH 050/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20bearer=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=8D=B0=EC=BD=94=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/service/auth.py b/app/service/auth.py index 1a6aa9d..923a085 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -9,6 +9,12 @@ from app.core import user_settings +def parsing_token_decorator(func): + def wrapper(token: str): + return func(token.split(" ")[1]) + return wrapper + + def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): to_encode = data.copy() if expires_delta: @@ -20,6 +26,7 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): return encoded_jwt +@parsing_token_decorator def auth_google_token(token: str): result = requests.get("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + token) @@ -30,6 +37,7 @@ def auth_google_token(token: str): raise JWTError +@parsing_token_decorator def check_access_token_valid(token: str): try: decode_token = jwt.decode(token, user_settings.SECRET_KEY, algorithms=[user_settings.ALGORITHM]) From 2e5ee253b4bf029269703484ca440734bab27d19 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sat, 15 May 2021 23:51:32 +0900 Subject: [PATCH 051/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20auth=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20logging=20=EB=B0=8F=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/app/service/auth.py b/app/service/auth.py index 923a085..eea50f5 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -1,3 +1,5 @@ +import logging + import requests from datetime import datetime, timedelta from typing import Optional @@ -41,22 +43,17 @@ def auth_google_token(token: str): def check_access_token_valid(token: str): try: decode_token = jwt.decode(token, user_settings.SECRET_KEY, algorithms=[user_settings.ALGORITHM]) - return True - - except ExpiredSignatureError: - print("time") - return False + return decode_token["sub"] + except ExpiredSignatureError as err: + logging.info("Token has expired") + # todo: Refresh Token Check + raise JWTError() except JWTClaimsError: - print("claim") - return False + logging.info("token has any claims") + raise JWTError() except JWTError: - print("jwt") - return False - - -def get_token_in_header(header: str) -> str: - # bearer gkwlfnbnklvjbopw.wegwedvkls.234352ewfdsv - return header.split(" ")[1] + logging.info("Invalid Signature token") + raise JWTError() def check_refresh_token(param): From cccd3d18a6aee410e46d04afdcc7748b8648d688 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sat, 15 May 2021 23:53:36 +0900 Subject: [PATCH 052/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20schemas=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=98=88?= =?UTF-8?q?=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/__init__.py | 11 ++++++--- app/schemas/user.py | 27 --------------------- app/schemas/users/__init__.py | 11 +++++++-- app/schemas/users/crud.py | 44 +++++++++++++++++++++++++++++++++++ app/schemas/users/handling.py | 20 +++++++++++++++- 5 files changed, 80 insertions(+), 33 deletions(-) delete mode 100644 app/schemas/user.py create mode 100644 app/schemas/users/crud.py diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 844e523..45934a6 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,10 +1,16 @@ -from app.schemas.user import UserBase, UserCreate, UserUpdate, UserResponse from app.schemas.responses import ( SuccessResponseBase, ErrorResponseBase, MethodNotAllowedHandling ) -from app.schemas.users import NotFoundUserHandling +from app.schemas.users import ( + NotFoundUserHandling, + UnauthorizedHandler, + UserBase, + UserCreate, + UserUpdate, + UserResponse + ) from app.schemas.study_rooms import ( StudyRoomsCreate, StudyRoomsUpdate, @@ -15,4 +21,3 @@ BodyNeedyStudyRoomHandling, QueryNeedyStudyRoomHandling ) - diff --git a/app/schemas/user.py b/app/schemas/user.py deleted file mode 100644 index e4ed682..0000000 --- a/app/schemas/user.py +++ /dev/null @@ -1,27 +0,0 @@ -import enum -from typing import Optional - -from pydantic import BaseModel - - -class UserBase(BaseModel): - id: Optional[int] - provider: Optional[str] - social_id: Optional[str] - nickname: Optional[str] - - -class UserCreate(UserBase): - provider: str - social_id: str - nickname: str - - -class UserUpdate(UserBase): - id: int - pass - - -class UserResponse(UserBase): - class Config: - orm_mode = True diff --git a/app/schemas/users/__init__.py b/app/schemas/users/__init__.py index 6351393..ed5f22a 100644 --- a/app/schemas/users/__init__.py +++ b/app/schemas/users/__init__.py @@ -1,3 +1,10 @@ from app.schemas.users.handling import ( - NotFoundUserHandling - ) \ No newline at end of file + NotFoundUserHandling, + UnauthorizedHandler + ) +from app.schemas.users.crud import ( + UserBase, + UserCreate, + UserUpdate, + UserResponse + ) diff --git a/app/schemas/users/crud.py b/app/schemas/users/crud.py new file mode 100644 index 0000000..ff72af9 --- /dev/null +++ b/app/schemas/users/crud.py @@ -0,0 +1,44 @@ +import enum +from typing import Optional + +from pydantic import BaseModel + + +class UserBase(BaseModel): + id: Optional[int] + provider: Optional[str] + social_id: Optional[str] + nickname: Optional[str] + + +class UserCreate(UserBase): + provider: str + nickname: str + + class Config: + schema_extra = { + 'example': { + 'provider': 'google', + 'nickname': 'Studeep_User' + } + } + + +class UserUpdate(UserBase): + id: int + pass + + class Config: + schema_extra = { + 'example': { + 'id': 1, + 'provider': 'google', + 'social_id': 'example@gmail.com', + 'nickname': 'new Nickname' + } + } + + +class UserResponse(UserBase): + class Config: + orm_mode = True diff --git a/app/schemas/users/handling.py b/app/schemas/users/handling.py index a218d00..6a12a25 100644 --- a/app/schemas/users/handling.py +++ b/app/schemas/users/handling.py @@ -9,11 +9,29 @@ class Config: { "loc": [ "database", - "study room" + "user" ], "msg": "not found", "type": "database.missing" } ] } + } + + +class UnauthorizedHandler(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "token", + "user" + ], + "msg": "Unauthorized", + "type": "Token Unauthorized" + } + ] + } } \ No newline at end of file From 855f970e10adc2bc599694bfa5f5462b8470ac27 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sat, 15 May 2021 23:54:03 +0900 Subject: [PATCH 053/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20init=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/user.py | 2 +- app/service/__init__.py | 1 + app/service/user/__init__.py | 0 3 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 app/service/user/__init__.py diff --git a/app/crud/user.py b/app/crud/user.py index c7c57ca..7a006f9 100644 --- a/app/crud/user.py +++ b/app/crud/user.py @@ -4,7 +4,7 @@ from app.crud.base import CRUDBase from app.models import User -from app.schemas import UserCreate, UserUpdate +from app.schemas.users import UserCreate, UserUpdate class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]): diff --git a/app/service/__init__.py b/app/service/__init__.py index e69de29..c65c71d 100644 --- a/app/service/__init__.py +++ b/app/service/__init__.py @@ -0,0 +1 @@ +# from user_service import * diff --git a/app/service/user/__init__.py b/app/service/user/__init__.py deleted file mode 100644 index e69de29..0000000 From a15f2d544041fc12db8499fa05cd182eb58e8a02 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sat, 15 May 2021 23:55:36 +0900 Subject: [PATCH 054/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20user=20api=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B0=8F=20response=20=ED=98=95=ED=83=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 103 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 24 deletions(-) diff --git a/app/api/users.py b/app/api/users.py index 33f1775..a87ab47 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -1,52 +1,107 @@ import logging +import traceback from datetime import timedelta from typing import Optional -from fastapi import APIRouter, Depends, Header, HTTPException, Response -from fastapi.logger import logger +from fastapi import APIRouter, Depends, Header, Response from jose import JWTError from sqlalchemy.orm import Session +from starlette import status +from starlette.responses import JSONResponse from app import schemas, crud from app.api.deps import get_db -from app.schemas import UserResponse +from app.erros import get_detail, NoSuchElementException +from app.schemas import SuccessResponseBase, ErrorResponseBase, NotFoundUserHandling, UnauthorizedHandler from app.service import auth from app.core import user_settings -from app.service.auth import get_token_in_header router = APIRouter() -@router.post("/signup", response_model=UserResponse) +@router.post( + "/signup", + responses = { + 200: { + "model": SuccessResponseBase, + "description": "회원가입 성공" + }, + 401: { + "model": UnauthorizedHandler, + "description": "JWT 토큰 인증에 실패하였을 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "Generic Error" + } + } +) def sign_up(*, db: Session = Depends(get_db), user_in: schemas.UserCreate, authorization: Optional[str] = Header(None)): - jwt = get_token_in_header(authorization) - if auth.check_access_token_valid(jwt): + try: + email = auth.check_access_token_valid(authorization) + user_in.social_id = email user = crud.user.create(db, obj_in=user_in) - return user - else: - raise HTTPException(status_code=401, detail='Invalid token') + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': user}) + except JWTError: + message = traceback.format_exc() + detail = get_detail(param='token', field='authorize', message=message, err='invalid token') + return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED, content={'detail': detail}) + except Exception as error: + logging.error(traceback.format_exc()) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content={'detail': f'server error: {traceback.format_exc()}'}) + finally: + db.close() -@router.get("/signin", response_model=UserResponse) +@router.get( + "/signin", + responses = { + 200: { + "model": SuccessResponseBase, + "description": "로그인 성공" + }, + 401: { + "model": UnauthorizedHandler, + "description": "Google 토큰 인증에 실패하였을 경우" + }, + 404: { + "model": NotFoundUserHandling, + "description": "user가 존재하지 않는 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "Generic Error" + } + } +) def sign_in(*, db: Session = Depends(get_db), response: Response, authorization: Optional[str] = Header(None) ): try: - email = auth.auth_google_token(get_token_in_header(authorization)) - except JWTError: - raise HTTPException(status_code=401, detail="Invalid Token") + # raise JWT Error + email = auth.auth_google_token(authorization) + user = crud.user.get_one_by_email(db, email) - user = crud.user.get_one_by_email(db, email) + token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) - token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) + if user is None: + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, + content={'detail': "user(email: " + email + ") not exist."}, + headers={"Authorization": 'bearer ' + token} + ) - if user is None: - raise HTTPException(status_code=404, - detail="user(email: " + email + ") not exist.", - headers={"Authorization": 'bearer ' + token} - ) + response.headers["Authorization"] = 'bearer ' + token - response.headers["Authorization"] = 'bearer ' + token - - return user + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': user}) + except JWTError: + message = traceback.format_exc() + detail = get_detail(param='token', field='authorize', message=message, err='invalid Google token') + return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED, content={'detail': detail}) + except Exception as error: + logging.error(traceback.format_exc()) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content={'detail': f'server error: {traceback.format_exc()}'}) + finally: + db.close() From cbbc3a16785a03257633641076be3a2aee9be0ee Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 15:43:51 +0900 Subject: [PATCH 055/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20=20:=20errors=20?= =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 2 +- app/api/users.py | 2 +- app/crud/study_rooms.py | 2 +- app/{erros => errors}/__init__.py | 2 +- app/{erros => errors}/customs.py | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename app/{erros => errors}/__init__.py (85%) rename app/{erros => errors}/customs.py (100%) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 9dc0216..6818de0 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -19,7 +19,7 @@ QueryNeedyStudyRoomHandling, MethodNotAllowedHandling ) -from app.erros import ( +from app.errors import ( get_detail, NoSuchElementException, InvalidArgumentException diff --git a/app/api/users.py b/app/api/users.py index a87ab47..cf6f9d2 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -11,7 +11,7 @@ from app import schemas, crud from app.api.deps import get_db -from app.erros import get_detail, NoSuchElementException +from app.errors import get_detail, NoSuchElementException from app.schemas import SuccessResponseBase, ErrorResponseBase, NotFoundUserHandling, UnauthorizedHandler from app.service import auth from app.core import user_settings diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index c540d77..3d59a17 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -8,7 +8,7 @@ from app.crud.base import CRUDBase from app.models import StudyRooms from app.schemas import StudyRoomsCreate, StudyRoomsUpdate -from app.erros import NoSuchElementException, InvalidArgumentException +from app.errors import NoSuchElementException, InvalidArgumentException def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): diff --git a/app/erros/__init__.py b/app/errors/__init__.py similarity index 85% rename from app/erros/__init__.py rename to app/errors/__init__.py index 72f1e7c..f6b5d84 100644 --- a/app/erros/__init__.py +++ b/app/errors/__init__.py @@ -1,4 +1,4 @@ -from app.erros.customs import ( +from app.errors.customs import ( get_detail, InternalException, NoSuchElementException, diff --git a/app/erros/customs.py b/app/errors/customs.py similarity index 100% rename from app/erros/customs.py rename to app/errors/customs.py From 488c3448350f771c77eb72a9889b1745c01a7c87 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:28:24 +0900 Subject: [PATCH 056/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20Forbidden=20Ha?= =?UTF-8?q?ndler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/__init__.py | 1 + app/schemas/users/__init__.py | 3 ++- app/schemas/users/handling.py | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 45934a6..02ea839 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -6,6 +6,7 @@ from app.schemas.users import ( NotFoundUserHandling, UnauthorizedHandler, + ForbiddenHandler, UserBase, UserCreate, UserUpdate, diff --git a/app/schemas/users/__init__.py b/app/schemas/users/__init__.py index ed5f22a..07c23d2 100644 --- a/app/schemas/users/__init__.py +++ b/app/schemas/users/__init__.py @@ -1,6 +1,7 @@ from app.schemas.users.handling import ( NotFoundUserHandling, - UnauthorizedHandler + UnauthorizedHandler, + ForbiddenHandler ) from app.schemas.users.crud import ( UserBase, diff --git a/app/schemas/users/handling.py b/app/schemas/users/handling.py index 6a12a25..d8264b0 100644 --- a/app/schemas/users/handling.py +++ b/app/schemas/users/handling.py @@ -34,4 +34,22 @@ class Config: } ] } + } + + +class ForbiddenHandler(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "token", + "user" + ], + "msg": "Forbidden", + "type": "Forbidden Token" + } + ] + } } \ No newline at end of file From 7dbc260fc0c6724f8aa8313a900d990ec6e7ac4f Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:29:30 +0900 Subject: [PATCH 057/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20response=20?= =?UTF-8?q?=EC=96=91=EC=8B=9D=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/app/api/users.py b/app/api/users.py index cf6f9d2..04d8826 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -4,17 +4,24 @@ from typing import Optional from fastapi import APIRouter, Depends, Header, Response +from fastapi.encoders import jsonable_encoder from jose import JWTError from sqlalchemy.orm import Session from starlette import status from starlette.responses import JSONResponse -from app import schemas, crud -from app.api.deps import get_db +from app import schemas, crud +from app.api.deps import get_db from app.errors import get_detail, NoSuchElementException -from app.schemas import SuccessResponseBase, ErrorResponseBase, NotFoundUserHandling, UnauthorizedHandler -from app.service import auth -from app.core import user_settings +from app.schemas import ( + SuccessResponseBase, + ErrorResponseBase, + NotFoundUserHandling, + UnauthorizedHandler, + ForbiddenHandler + ) +from app.service import auth +from app.core import user_settings router = APIRouter() @@ -30,22 +37,35 @@ "model": UnauthorizedHandler, "description": "JWT 토큰 인증에 실패하였을 경우" }, + 403: { + "model": ForbiddenHandler, + "description": "올바른 유형의 토큰이 아닌 경우(on-board / access)" + }, 500: { "model": ErrorResponseBase, "description": "Generic Error" } } ) -def sign_up(*, db: Session = Depends(get_db), user_in: schemas.UserCreate, authorization: Optional[str] = Header(None)): +def sign_up(*, db: Session = Depends(get_db), + user_in: schemas.UserCreate, + authorization: Optional[str] = Header(None)): try: - email = auth.check_access_token_valid(authorization) + email = auth.check_access_token_valid(authorization, on_board=True) user_in.social_id = email user = crud.user.create(db, obj_in=user_in) - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': user}) + token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) + return JSONResponse(status_code=status.HTTP_200_OK, + content={'data': jsonable_encoder(user)}, + headers={'Authorization' : 'bearer ' + token}) except JWTError: message = traceback.format_exc() detail = get_detail(param='token', field='authorize', message=message, err='invalid token') return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED, content={'detail': detail}) + except NameError: + message = traceback.format_exc() + detail = get_detail(param='token', field='forbidden', message=message, err='This token is not on-boarding token') + return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) except Exception as error: logging.error(traceback.format_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -87,6 +107,8 @@ def sign_in(*, db: Session = Depends(get_db), token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) if user is None: + token = auth.create_access_token({"on_board": email}, + timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': "user(email: " + email + ") not exist."}, headers={"Authorization": 'bearer ' + token} @@ -94,7 +116,7 @@ def sign_in(*, db: Session = Depends(get_db), response.headers["Authorization"] = 'bearer ' + token - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': user}) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': jsonable_encoder(user)}) except JWTError: message = traceback.format_exc() detail = get_detail(param='token', field='authorize', message=message, err='invalid Google token') From bbb06fa2b1c9077f36d7a5d646dc268fb04ebc99 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:30:16 +0900 Subject: [PATCH 058/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20get=5Fuser=20?= =?UTF-8?q?=EB=B0=8F=20user=20backdoor=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/app/api/users.py b/app/api/users.py index 04d8826..6ad1bce 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -127,3 +127,70 @@ def sign_in(*, db: Session = Depends(get_db), content={'detail': f'server error: {traceback.format_exc()}'}) finally: db.close() + + +@router.get( + "/get", + responses = { + 200: { + "model": SuccessResponseBase, + "description": "정상 Response" + }, + 401: { + "model": UnauthorizedHandler, + "description": "JWT 토큰 인증에 실패하였을 경우" + }, + 403: { + "model": ForbiddenHandler, + "description": "올바른 유형의 토큰이 아닌 경우(on-board / access)" + }, + 404: { + "model": NotFoundUserHandling, + "description": "user가 존재하지 않는 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "Generic Error" + } + } +) +def get_user( + *, + db: Session = Depends(get_db), + authorization: Optional[str] = Header(None) +): + try: + # raise JWT Error + email = auth.check_access_token_valid(authorization) + user = crud.user.get_one_by_email(db, email) + + if user is None: + raise NoSuchElementException("user(email: " + email + ") not exist.") + + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': jsonable_encoder(user)}) + except JWTError: + message = traceback.format_exc() + detail = get_detail(param='token', field='authorize', message=message, err='invalid Google token') + return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED, content={'detail': detail}) + except NameError: + message = traceback.format_exc() + detail = get_detail(param='token', field='forbidden', message=message, + err='This token is not access token') + return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) + except Exception as error: + logging.error(traceback.format_exc()) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content={'detail': f'server error: {traceback.format_exc()}'}) + finally: + db.close() + + +# todo: 서비스 시작 시, 필히 제거! +@router.get('/test/{email}/{token_type}', response_model=SuccessResponseBase, description='토큰 발급 백도어') +def back_door_access(email: str, token_type: str): + if token_type == 'onboard': + token = auth.create_access_token({"on_board": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) + else: + token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) + + return JSONResponse(status_code=status.HTTP_200_OK, content={'token': token}) From 7d706d89349753110605b7943b78042bdb6aca2e Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:30:43 +0900 Subject: [PATCH 059/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20settings=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD=EC=97=90=20=EC=9D=98?= =?UTF-8?q?=ED=95=9C=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- migrations/env.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/env.py b/migrations/env.py index ea564ab..ad3d4f4 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -2,7 +2,7 @@ from logging.config import fileConfig from sqlalchemy import engine_from_config, pool -from app.core import settings +from app.core import common_settings from app.database.base import Base # this is the Alembic Config object, which provides @@ -36,7 +36,7 @@ def run_migrations_offline(): script output. """ - url = settings.SQLALCHEMY_DATABASE_URI + url = common_settings.SQLALCHEMY_DATABASE_URI context.configure(url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, compare_type=True) @@ -52,7 +52,7 @@ def run_migrations_online(): """ configuration = config.get_section(config.config_ini_section) - configuration["sqlalchemy.url"] = settings.SQLALCHEMY_DATABASE_URI + configuration["sqlalchemy.url"] = common_settings.SQLALCHEMY_DATABASE_URI connectable = engine_from_config(configuration, prefix="sqlalchemy.", poolclass=pool.NullPool) with connectable.connect() as connection: From d8fe5ae1eab943bba64068fca3c496afb08ed762 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:32:33 +0900 Subject: [PATCH 060/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20study=5Frooms?= =?UTF-8?q?=20crud=20get=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=20=ED=98=95=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 3d59a17..052376e 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -30,7 +30,7 @@ def get(self, db: Session, room_id: UUID): self.model.owner_id ).first() if data: - return data + return jsonable_encoder(data) else: raise NoSuchElementException(message='not found') From 51aae2a1484db10c297503b71d9415c37432fd3e Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:32:57 +0900 Subject: [PATCH 061/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20user=EC=97=90?= =?UTF-8?q?=20goal=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/users.py | 2 ++ app/schemas/users/crud.py | 26 ++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/models/users.py b/app/models/users.py index 1d7584c..3421ade 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -2,6 +2,7 @@ from sqlalchemy import Column, Integer, Enum, String from sqlalchemy.orm import relation +from sqlalchemy.dialects.postgresql import JSON from app.database.base_class import Base @@ -17,4 +18,5 @@ class User(Base): provider = Column('user_provider', Enum(Provider), nullable=False) social_id = Column('user_social_id', String, nullable=False, unique=True) nickname = Column('user_nickname', String, nullable=False, unique=True) + goal = Column('user_goal', JSON, nullable=False) study_rooms = relation('StudyRooms', back_populates = "owner") \ No newline at end of file diff --git a/app/schemas/users/crud.py b/app/schemas/users/crud.py index ff72af9..53afa15 100644 --- a/app/schemas/users/crud.py +++ b/app/schemas/users/crud.py @@ -1,7 +1,9 @@ import enum +import json from typing import Optional from pydantic import BaseModel +from sqlalchemy.dialects.postgresql import JSON class UserBase(BaseModel): @@ -9,17 +11,28 @@ class UserBase(BaseModel): provider: Optional[str] social_id: Optional[str] nickname: Optional[str] + goal: Optional[dict] class UserCreate(UserBase): provider: str nickname: str + goal: dict class Config: schema_extra = { 'example': { 'provider': 'google', - 'nickname': 'Studeep_User' + 'nickname': 'Studeep_User', + 'goal': { + '월': 2, + '화': 2, + '수': 2, + '목': 2, + '금': 2, + '토': 2, + '일': 2 + } } } @@ -34,7 +47,16 @@ class Config: 'id': 1, 'provider': 'google', 'social_id': 'example@gmail.com', - 'nickname': 'new Nickname' + 'nickname': 'new Nickname', + 'goal': { + '월': 2, + '화': 2, + '수': 2, + '목': 2, + '금': 2, + '토': 2, + '일': 2 + } } } From 9efaf4127860ac0185c086eb1018c94482231f77 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:33:49 +0900 Subject: [PATCH 062/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20=EB=8B=A4?= =?UTF-8?q?=EC=96=91=ED=95=9C=20=EC=9E=85=EB=A0=A5=20=EC=BB=A4=EB=B2=84?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EB=8D=B0=EC=BD=94=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/service/auth.py b/app/service/auth.py index eea50f5..ec157bd 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -1,19 +1,20 @@ import logging import requests -from datetime import datetime, timedelta -from typing import Optional +from datetime import datetime, timedelta +from typing import Optional -from fastapi import HTTPException -from jose import jwt, JWTError, ExpiredSignatureError +from fastapi import HTTPException +from jose import jwt, JWTError, ExpiredSignatureError from jose.exceptions import JWTClaimsError from app.core import user_settings def parsing_token_decorator(func): - def wrapper(token: str): - return func(token.split(" ")[1]) + def wrapper(token: str, **kwargs): + return func(token.split(" ")[1], **kwargs) + return wrapper @@ -40,9 +41,11 @@ def auth_google_token(token: str): @parsing_token_decorator -def check_access_token_valid(token: str): +def check_access_token_valid(token: str, on_board=False): try: decode_token = jwt.decode(token, user_settings.SECRET_KEY, algorithms=[user_settings.ALGORITHM]) + if on_board: + return decode_token["on_board"] return decode_token["sub"] except ExpiredSignatureError as err: logging.info("Token has expired") From 8418112d8eb44fcfd17ce7ccaf17b317526fed19 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 16 May 2021 17:34:08 +0900 Subject: [PATCH 063/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20authDecorator?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/service/auth.py b/app/service/auth.py index ec157bd..5a946e1 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -18,6 +18,16 @@ def wrapper(token: str, **kwargs): return wrapper +def auth_decorator(token): + def inner_decorator(fun): + def wrapper(*args, **kwargs): + check_access_token_valid(token) + fun(*args, **kwargs) + + return wrapper + return inner_decorator + + def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): to_encode = data.copy() if expires_delta: From aa632b019242fd6be2090d56922eec67c2aa57cf Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 20:16:52 +0900 Subject: [PATCH 064/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20starlette=20->?= =?UTF-8?q?=20fastapi=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/api/users.py b/app/api/users.py index 6ad1bce..da152c3 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -7,8 +7,8 @@ from fastapi.encoders import jsonable_encoder from jose import JWTError from sqlalchemy.orm import Session -from starlette import status -from starlette.responses import JSONResponse +from fastapi import status +from fastapi.responses import JSONResponse from app import schemas, crud from app.api.deps import get_db From d786c28912e649ebf9780a0814544814df853d21 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 20:17:39 +0900 Subject: [PATCH 065/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20=20:=20goal?= =?UTF-8?q?=EC=9D=98=20dict=ED=83=80=EC=9E=85=20=EC=98=88=EC=8B=9C=20?= =?UTF-8?q?=EC=9A=94=EC=9D=BC=20=EC=98=81=EC=96=B4=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/users/crud.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/schemas/users/crud.py b/app/schemas/users/crud.py index 53afa15..1f6103a 100644 --- a/app/schemas/users/crud.py +++ b/app/schemas/users/crud.py @@ -25,13 +25,13 @@ class Config: 'provider': 'google', 'nickname': 'Studeep_User', 'goal': { - '월': 2, - '화': 2, - '수': 2, - '목': 2, - '금': 2, - '토': 2, - '일': 2 + 'MON': 2, + 'TUE': 2, + 'WED': 2, + 'THU': 2, + 'FRI': 2, + 'SAT': 2, + 'SUN': 2 } } } @@ -49,13 +49,13 @@ class Config: 'social_id': 'example@gmail.com', 'nickname': 'new Nickname', 'goal': { - '월': 2, - '화': 2, - '수': 2, - '목': 2, - '금': 2, - '토': 2, - '일': 2 + 'MON': 2, + 'TUE': 2, + 'WED': 2, + 'THU': 2, + 'FRI': 2, + 'SAT': 2, + 'SUN': 2 } } } From cfbcd75e571cfc820db48e4002bd0a423336b294 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 20:20:02 +0900 Subject: [PATCH 066/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20UserResponse?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20success/UserDataResponse=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/__init__.py | 4 ++-- app/schemas/users/__init__.py | 9 +++++---- app/schemas/users/crud.py | 5 ----- app/schemas/users/success.py | 22 ++++++++++++++++++++++ 4 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 app/schemas/users/success.py diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 02ea839..2c305bd 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -7,10 +7,10 @@ NotFoundUserHandling, UnauthorizedHandler, ForbiddenHandler, + UserDataResponse, UserBase, UserCreate, - UserUpdate, - UserResponse + UserUpdate ) from app.schemas.study_rooms import ( StudyRoomsCreate, diff --git a/app/schemas/users/__init__.py b/app/schemas/users/__init__.py index 07c23d2..fcc20f5 100644 --- a/app/schemas/users/__init__.py +++ b/app/schemas/users/__init__.py @@ -1,11 +1,12 @@ -from app.schemas.users.handling import ( +from app.schemas.users.handling import ( NotFoundUserHandling, UnauthorizedHandler, ForbiddenHandler ) -from app.schemas.users.crud import ( +from app.schemas.users.crud import ( UserBase, UserCreate, - UserUpdate, - UserResponse + UserUpdate ) + +from app.schemas.users.success import UserDataResponse diff --git a/app/schemas/users/crud.py b/app/schemas/users/crud.py index 1f6103a..7d6b539 100644 --- a/app/schemas/users/crud.py +++ b/app/schemas/users/crud.py @@ -59,8 +59,3 @@ class Config: } } } - - -class UserResponse(UserBase): - class Config: - orm_mode = True diff --git a/app/schemas/users/success.py b/app/schemas/users/success.py new file mode 100644 index 0000000..d8a016a --- /dev/null +++ b/app/schemas/users/success.py @@ -0,0 +1,22 @@ +from app.schemas import SuccessResponseBase + + +class UserDataResponse(SuccessResponseBase): + class Config: + schema_extra = { + 'example': { + 'id': 1, + 'provider': 'google', + 'social_id': 'example@gmail.com', + 'nickname': 'new Nickname', + 'goal': { + 'MON': 2, + 'TUE': 2, + 'WED': 2, + 'THU': 2, + 'FRI': 2, + 'SAT': 2, + 'SUN': 2 + } + } + } \ No newline at end of file From 254f182488c55b55a834f2f8ad3ddd2db1eca299 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 20:29:50 +0900 Subject: [PATCH 067/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20UserDataRespon?= =?UTF-8?q?se=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/api/users.py b/app/api/users.py index da152c3..137ca64 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -16,6 +16,7 @@ from app.schemas import ( SuccessResponseBase, ErrorResponseBase, + UserDataResponse, NotFoundUserHandling, UnauthorizedHandler, ForbiddenHandler @@ -30,7 +31,7 @@ "/signup", responses = { 200: { - "model": SuccessResponseBase, + "model": UserDataResponse, "description": "회원가입 성공" }, 401: { @@ -78,7 +79,7 @@ def sign_up(*, db: Session = Depends(get_db), "/signin", responses = { 200: { - "model": SuccessResponseBase, + "model": UserDataResponse, "description": "로그인 성공" }, 401: { @@ -133,7 +134,7 @@ def sign_in(*, db: Session = Depends(get_db), "/get", responses = { 200: { - "model": SuccessResponseBase, + "model": UserDataResponse, "description": "정상 Response" }, 401: { From dd3b244121a112e9a86021983e158d357793fc00 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 20:30:20 +0900 Subject: [PATCH 068/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20crud/user=20->?= =?UTF-8?q?=20users?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/__init__.py | 2 +- app/crud/{user.py => users.py} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename app/crud/{user.py => users.py} (83%) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 531c8ea..5d95ee9 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,3 +1,3 @@ -from app.crud.user import user +from app.crud.users import users from app.crud.study_rooms import study_rooms diff --git a/app/crud/user.py b/app/crud/users.py similarity index 83% rename from app/crud/user.py rename to app/crud/users.py index 7a006f9..ba9f1a5 100644 --- a/app/crud/user.py +++ b/app/crud/users.py @@ -4,7 +4,7 @@ from app.crud.base import CRUDBase from app.models import User -from app.schemas.users import UserCreate, UserUpdate +from app.schemas import UserCreate, UserUpdate class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]): @@ -13,4 +13,4 @@ def get_one_by_email(self, db: Session, email: str): return db.query(User).filter(User.social_id == email).first() -user = CRUDUser(User) +users = CRUDUser(User) From 46f4c8d086584bd37f9ab5d807a6fd66a617b8c9 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 20:30:46 +0900 Subject: [PATCH 069/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20api/users=20im?= =?UTF-8?q?port=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/api/users.py b/app/api/users.py index 137ca64..5b31a9a 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -10,13 +10,14 @@ from fastapi import status from fastapi.responses import JSONResponse -from app import schemas, crud +from app.crud import users from app.api.deps import get_db from app.errors import get_detail, NoSuchElementException from app.schemas import ( SuccessResponseBase, ErrorResponseBase, UserDataResponse, + UserCreate, NotFoundUserHandling, UnauthorizedHandler, ForbiddenHandler @@ -49,12 +50,12 @@ } ) def sign_up(*, db: Session = Depends(get_db), - user_in: schemas.UserCreate, + user_in: UserCreate, authorization: Optional[str] = Header(None)): try: email = auth.check_access_token_valid(authorization, on_board=True) user_in.social_id = email - user = crud.user.create(db, obj_in=user_in) + user = users.create(db, obj_in=user_in) token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': jsonable_encoder(user)}, @@ -103,7 +104,7 @@ def sign_in(*, db: Session = Depends(get_db), try: # raise JWT Error email = auth.auth_google_token(authorization) - user = crud.user.get_one_by_email(db, email) + user = users.get_one_by_email(db, email) token = auth.create_access_token({"sub": email}, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) @@ -163,7 +164,7 @@ def get_user( try: # raise JWT Error email = auth.check_access_token_valid(authorization) - user = crud.user.get_one_by_email(db, email) + user = users.get_one_by_email(db, email) if user is None: raise NoSuchElementException("user(email: " + email + ") not exist.") From 514e3e0c9faf3771ffe2f634cff2930922036552 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Mon, 17 May 2021 22:42:37 +0900 Subject: [PATCH 070/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20DI=EB=A5=BC=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20auth=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/app/service/auth.py b/app/service/auth.py index 5a946e1..24fddcf 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -1,14 +1,17 @@ import logging +import traceback import requests from datetime import datetime, timedelta from typing import Optional -from fastapi import HTTPException +from fastapi import status, Header +from fastapi.responses import JSONResponse from jose import jwt, JWTError, ExpiredSignatureError from jose.exceptions import JWTClaimsError from app.core import user_settings +from app.errors import get_detail def parsing_token_decorator(func): @@ -18,14 +21,14 @@ def wrapper(token: str, **kwargs): return wrapper -def auth_decorator(token): - def inner_decorator(fun): - def wrapper(*args, **kwargs): - check_access_token_valid(token) - fun(*args, **kwargs) - - return wrapper - return inner_decorator +# DI +def auth_token(authorization: Optional[str] = Header(None)): + try: + check_access_token_valid(authorization) + except JWTError: + message = traceback.format_exc() + detail = get_detail(param='token', field='authorize', message=message, err='invalid Google token') + return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED, content={'detail': detail}) def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): From 05806a140f881c0b137a12508b136ea554de274a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 18 May 2021 23:48:42 +0900 Subject: [PATCH 071/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20socket=20server?= =?UTF-8?q?=20&=20=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20/join=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/__init__.py | 2 +- app/api/study_rooms.py | 88 ++++++++++++++++++++++++++--- app/core/__init__.py | 3 +- app/core/config.py | 6 ++ app/crud/study_rooms.py | 45 ++++++++++++++- app/database/__init__.py | 1 + app/database/base_class.py | 8 ++- app/errors/customs.py | 29 ++++++---- app/main.py | 14 +++-- app/schemas/__init__.py | 5 +- app/schemas/study_rooms/__init__.py | 10 +++- app/schemas/study_rooms/crud.py | 24 +++++--- app/schemas/study_rooms/handling.py | 38 ++++++++++++- app/service/__init__.py | 3 +- app/service/cors.py | 14 +++++ app/service/sockets.py | 61 ++++++++++++++++++++ 16 files changed, 309 insertions(+), 42 deletions(-) create mode 100644 app/service/cors.py create mode 100644 app/service/sockets.py diff --git a/app/api/__init__.py b/app/api/__init__.py index 81f9443..1a8abc3 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -14,4 +14,4 @@ study_rooms.router, prefix=study_rooms_settings.API_STUDY_ROOM, tags=['study_rooms'] -) +) \ No newline at end of file diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 6818de0..b449c0a 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -1,6 +1,10 @@ import traceback -from fastapi import APIRouter, Depends, status +from fastapi import ( + APIRouter, + Depends, + status + ) from fastapi.responses import JSONResponse from sqlalchemy.orm.session import Session @@ -11,18 +15,23 @@ ErrorResponseBase, StudyRoomsCreate, StudyRoomsUpdate, + StudyRoomJoin, GetStudyRoomResponse, GetStudyRoomsResponse, NotFoundStudyRoomHandling, PasswordNeedyStudyRoomHandling, BodyNeedyStudyRoomHandling, QueryNeedyStudyRoomHandling, - MethodNotAllowedHandling + MethodNotAllowedHandling, + NoEmptyRoomHandling, + ForbiddenUserHandling ) -from app.errors import ( +from app.errors import ( get_detail, NoSuchElementException, - InvalidArgumentException + InvalidArgumentException, + RequestConflictException, + ForbiddenException ) @@ -48,6 +57,7 @@ ) def get_study_room(room_id: str, db: Session = Depends(get_db)): try: + print(db) data = study_rooms.get(db, room_id) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) @@ -59,6 +69,9 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): except Exception as error: print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) + + finally: + db.close() @router.patch( @@ -104,7 +117,7 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {detail}'}) @router.delete( @@ -200,9 +213,9 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session } } ) -def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): +def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db)): try: - study_rooms.create(db, rooms) + study_rooms.create(db, room_info) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) except InvalidArgumentException as argument_err: @@ -215,6 +228,67 @@ def create_study_room(rooms: StudyRoomsCreate, db: Session = Depends(get_db)): detail = get_detail(param='database', field='user', message='not found', err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + except Exception as error: + print(traceback.print_exc()) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) + + +@router.post( + '/{room_id}/join', + responses = { + 200: { + "model": SuccessResponseBase, + "description": "스터디룸 생성 성공" + }, + 403: { + "model": ForbiddenUserHandling, + "description": "비공개 방의 비밀번호 오입력 한 경우" + }, + 404: { + "model": NotFoundStudyRoomHandling, + "description": "존재하지 않으려는 방에 접근하려는 경우" + }, + 409: { + "model": NoEmptyRoomHandling, + "description": "이미 스터디룸의 참가 인원 수가 5명인 경우" + }, + 422: { + "model": PasswordNeedyStudyRoomHandling, + "description": "비공개 스터디룸일 때 비밀번호를 입력하지 않은 경우 \ + 만약 공개된 스터디룸인데 비밀번호와 넘어올 경우 `msg` 부분에 `field not required` 반환" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def join_study_room(room_id: str, room_info: StudyRoomJoin, db: Session = Depends(get_db)): + try: + print(room_id) + study_rooms.join(db, room_id, room_info) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + + except ForbiddenException as forbidden_err: + message = forbidden_err.message + detail = get_detail(param='body', field='password', message=message, err='invalid') + return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) + + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail(param='database', field='study room', message=message, err='database') + return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + + except RequestConflictException as conflict_err: + message = conflict_err.message + detail = get_detail(param='database', field='study room', message=message, err='database') + return JSONResponse(status_code=status.HTTP_409_CONFLICT, content={'detail': detail}) + + except InvalidArgumentException as argument_err: + message = argument_err.message + detail = get_detail(param='body', field='password', message=message, err='value_error') + return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={'detail': detail}) + except Exception as error: print(traceback.print_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) \ No newline at end of file diff --git a/app/core/__init__.py b/app/core/__init__.py index 3a62a5b..468a60e 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -1,5 +1,6 @@ from app.core.config import ( common_settings, study_rooms_settings, - user_settings + user_settings, + socket_settinngs ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index ba57d35..7aaa3be 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,4 +1,5 @@ import secrets +from uuid import NAMESPACE_URL from pydantic import BaseSettings @@ -24,6 +25,11 @@ class StudyRoomSettings(BaseSettings): API_STUDY_ROOM: str = '/study-rooms' +class SocketSettings(BaseSettings): + NAMESPACE_URL: str = '/study' + + common_settings = CommonSettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() +socket_settinngs = SocketSettings() diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 052376e..aa84265 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,14 +1,22 @@ from uuid import UUID from typing import Union - from fastapi.encoders import jsonable_encoder from sqlalchemy.orm import Session from sqlalchemy.exc import IntegrityError from app.crud.base import CRUDBase from app.models import StudyRooms -from app.schemas import StudyRoomsCreate, StudyRoomsUpdate -from app.errors import NoSuchElementException, InvalidArgumentException +from app.schemas import ( + StudyRoomsCreate, + StudyRoomsUpdate, + StudyRoomJoin + ) +from app.errors import ( + NoSuchElementException, + InvalidArgumentException, + RequestConflictException, + ForbiddenException + ) def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): @@ -29,6 +37,7 @@ def get(self, db: Session, room_id: UUID): self.model.created_at, self.model.owner_id ).first() + if data: return jsonable_encoder(data) else: @@ -50,6 +59,7 @@ def get_multi(self, db: Session, skip: int, limit: int, option: str): self.model.created_at, self.model.owner_id ).order_by(f'{option}').offset(skip).limit(limit).all() + if data: return jsonable_encoder(data) else: @@ -99,4 +109,33 @@ def remove(self, db: Session, room_id: str): raise NoSuchElementException(message='not found') + def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): + try: + if not room_id: + raise NoSuchElementException(message='not found') + data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() + study_room = jsonable_encoder(data) + if study_room: + if study_room['current_join_counts'] >= 5: + raise RequestConflictException(message='no empty') + + if study_room['is_public']: + if room_info.password: + raise InvalidArgumentException(message='field not required') + else: + if not room_info.password: + raise InvalidArgumentException(message='field required') + elif room_info.password != study_room['password']: + raise ForbiddenException(message='forbidden') + + data.current_join_counts += 1 + db.commit() + + else: + raise NoSuchElementException(message='not found') + + except ValueError: + raise NoSuchElementException(message='not found') + + study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file diff --git a/app/database/__init__.py b/app/database/__init__.py index e69de29..0cc812c 100644 --- a/app/database/__init__.py +++ b/app/database/__init__.py @@ -0,0 +1 @@ +from app.database.session import SessionLocal \ No newline at end of file diff --git a/app/database/base_class.py b/app/database/base_class.py index 366f739..fd71453 100644 --- a/app/database/base_class.py +++ b/app/database/base_class.py @@ -1,8 +1,9 @@ -from typing import Any - +from typing import Any +from sqlalchemy import inspect from sqlalchemy.ext.declarative import as_declarative, declared_attr + @as_declarative() class Base: id: Any @@ -12,3 +13,6 @@ class Base: @declared_attr def __tablename__(self) -> str: return self.__name__.lower() + + def as_dict(self) -> dict: + return {c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs} diff --git a/app/errors/customs.py b/app/errors/customs.py index 99da24a..0e46682 100644 --- a/app/errors/customs.py +++ b/app/errors/customs.py @@ -13,7 +13,7 @@ def get_detail(param: str, field: str, message: str, err: str): class InternalException(Exception): - def __init__(self, message): + def __init__(self, message: str): self.message = message @@ -22,7 +22,7 @@ def __str__(self): class NoSuchElementException(Exception): - def __init__(self, message): + def __init__(self, message: str): self.message = message @@ -31,18 +31,27 @@ def __str__(self): class InvalidArgumentException(Exception): - def __init__(self, message): + def __init__(self, message: str): self.message = message + def __str__(self): + return self.message + + +class RequestConflictException(Exception): + def __init__(self, message: str): + self.message = message + + def __str__(self): return self.message - def get_response(self): - return create_detail( - param = self.param, - field = self.field, - message = self.message, - error = self.error - ) \ No newline at end of file +class ForbiddenException(Exception): + def __init__(self, message: str): + self.message = message + + + def __str__(self): + return self.message \ No newline at end of file diff --git a/app/main.py b/app/main.py index bb30564..b9a6183 100644 --- a/app/main.py +++ b/app/main.py @@ -1,14 +1,18 @@ +import socketio import uvicorn -from fastapi import FastAPI +from fastapi import FastAPI -from app.api import api_router -from app.core import common_settings +from app.api import api_router +from app.core import common_settings +from app.service import sio -server = FastAPI(title=common_settings.PROJECT_NAME) +server = FastAPI(title=common_settings.PROJECT_NAME) server.include_router(api_router, prefix=common_settings.COMMON_API) +server.mount('/', socketio.ASGIApp(sio, other_asgi_app=server)) + if __name__ == "__main__": - uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) + uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True, debug=True) diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 2c305bd..75cee53 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -15,10 +15,13 @@ from app.schemas.study_rooms import ( StudyRoomsCreate, StudyRoomsUpdate, + StudyRoomJoin, GetStudyRoomResponse, GetStudyRoomsResponse, NotFoundStudyRoomHandling, PasswordNeedyStudyRoomHandling, BodyNeedyStudyRoomHandling, - QueryNeedyStudyRoomHandling + QueryNeedyStudyRoomHandling, + NoEmptyRoomHandling, + ForbiddenUserHandling ) diff --git a/app/schemas/study_rooms/__init__.py b/app/schemas/study_rooms/__init__.py index 445b38e..c09610d 100644 --- a/app/schemas/study_rooms/__init__.py +++ b/app/schemas/study_rooms/__init__.py @@ -1,4 +1,8 @@ -from app.schemas.study_rooms.crud import StudyRoomsCreate, StudyRoomsUpdate +from app.schemas.study_rooms.crud import ( + StudyRoomsCreate, + StudyRoomsUpdate, + StudyRoomJoin + ) from app.schemas.study_rooms.success import ( GetStudyRoomResponse, GetStudyRoomsResponse @@ -7,5 +11,7 @@ NotFoundStudyRoomHandling, PasswordNeedyStudyRoomHandling, BodyNeedyStudyRoomHandling, - QueryNeedyStudyRoomHandling + QueryNeedyStudyRoomHandling, + NoEmptyRoomHandling, + ForbiddenUserHandling ) \ No newline at end of file diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index a34dd72..897dc25 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -1,16 +1,15 @@ -from typing import Optional - -from pydantic import BaseModel +from typing import Optional +from pydantic import BaseModel class StudyRoomsBase(BaseModel): - title: str - description: str - is_public: bool password: Optional[str] class StudyRoomsCreate(StudyRoomsBase): + title: str + description: str + is_public: bool current_join_counts: int = 0 owner_id: int @@ -30,7 +29,6 @@ class StudyRoomsUpdate(StudyRoomsBase): title: Optional[str] description: Optional[str] is_public: Optional[bool] - password: Optional[str] class Config: schema_extra = { @@ -39,4 +37,14 @@ class Config: 'is_public': False, 'password': 'TestPassword!234' } - } \ No newline at end of file + } + + +class StudyRoomJoin(StudyRoomsBase): + + class Config: + schema_extra = { + 'example': { + 'password': 'TestPassword!234' + } + } \ No newline at end of file diff --git a/app/schemas/study_rooms/handling.py b/app/schemas/study_rooms/handling.py index 42ca86a..1b82d32 100644 --- a/app/schemas/study_rooms/handling.py +++ b/app/schemas/study_rooms/handling.py @@ -86,4 +86,40 @@ class Config: } ] } - } \ No newline at end of file + } + + +class NoEmptyRoomHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "study room" + ], + "msg": "no empty", + "type": "database" + } + ] + } + } + + +class ForbiddenUserHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "body", + "password" + ], + "msg": "forbidden", + "type": "invalid" + } + ] + } + } \ No newline at end of file diff --git a/app/service/__init__.py b/app/service/__init__.py index c65c71d..17be6cb 100644 --- a/app/service/__init__.py +++ b/app/service/__init__.py @@ -1 +1,2 @@ -# from user_service import * +from app.service.auth import check_access_token_valid +from app.service.sockets import sio diff --git a/app/service/cors.py b/app/service/cors.py new file mode 100644 index 0000000..6f13669 --- /dev/null +++ b/app/service/cors.py @@ -0,0 +1,14 @@ +from fastapi.middleware.cors import CORSMiddleware + +from app.main import server + + +origins = ["*"] + +server.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=False, + allow_methods=["*"], + allow_headers=["*"], +) \ No newline at end of file diff --git a/app/service/sockets.py b/app/service/sockets.py new file mode 100644 index 0000000..338726e --- /dev/null +++ b/app/service/sockets.py @@ -0,0 +1,61 @@ +from app.service.auth import check_access_token_valid +import socketio + +from uuid import UUID +from fastapi.encoders import jsonable_encoder + +from app.core import socket_settinngs +from app.service import check_access_token_valid +from app.models import StudyRooms +from app.database import SessionLocal + + +sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*') +namespace_url = socket_settinngs.NAMESPACE_URL +db = SessionLocal() +model = StudyRooms + + +@sio.event(namespace=namespace_url) +async def connect(sid, environ, auth): + print('sid: ', sid) + print('token: ', auth) + # token = auth['access_token'] + # email = check_access_token_valid(token) + # await sio.save_session(sid, {'user_email': email}, namespace=namespace_url) + + +@sio.event(namespace=namespace_url) +async def joinRoom(sid, room_id): + sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) + print(sio.rooms(sid=sid, namespace=namespace_url)) + # session = await sio.get_session(sid, namespace=namespace_url) + await sio.emit('response', {'message': 'room joined'}, room=room_id, namespace=namespace_url) + print(sio.rooms(sid=sid, namespace=namespace_url)) + + +@sio.event(namespace=namespace_url) +async def leaveRoom(sid, room_id): + print('sid: ', sid) + print('room_id: ', room_id) + print('leave') + print(sio.rooms(sid=sid, namespace=namespace_url)) + sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) + print(sio.rooms(sid=sid, namespace=namespace_url)) + study_room = db.query(model).filter(model.id == UUID(room_id)).update( + {'current_join_counts': model.current_join_counts - 1} + ) + if study_room: + db.commit() + db.close() + print('here') + await sio.emit('response', {'message': 'room leaved'}, room=room_id, namespace=namespace_url) + print('emit done') + else: + await sio.emit('response', {'message': 'error'}, room=room_id, namespace=namespace_url) + + +@sio.event(namespace=namespace_url) +async def status(sid, data): + # Redis + pass \ No newline at end of file From 69e6179bc22b4b2107a6fdaf60c9473519995f78 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 19 May 2021 16:02:54 +0900 Subject: [PATCH 072/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=9E=85=EC=9E=A5=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EB=B0=8F=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=ED=86=B5=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 2 +- app/errors/__init__.py | 4 +++- app/service/__init__.py | 1 - app/service/cors.py | 2 +- app/service/sockets.py | 30 +++++++++--------------------- 5 files changed, 14 insertions(+), 25 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index b449c0a..277cf71 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -265,7 +265,7 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) ) def join_study_room(room_id: str, room_info: StudyRoomJoin, db: Session = Depends(get_db)): try: - print(room_id) + # Redis 통해서 현재 사용자가 특정 방에 접속 중일 경우 에러 반환 로직 필요 study_rooms.join(db, room_id, room_info) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) diff --git a/app/errors/__init__.py b/app/errors/__init__.py index f6b5d84..2e9c254 100644 --- a/app/errors/__init__.py +++ b/app/errors/__init__.py @@ -2,5 +2,7 @@ get_detail, InternalException, NoSuchElementException, - InvalidArgumentException + InvalidArgumentException, + RequestConflictException, + ForbiddenException ) \ No newline at end of file diff --git a/app/service/__init__.py b/app/service/__init__.py index 17be6cb..c5ee7d3 100644 --- a/app/service/__init__.py +++ b/app/service/__init__.py @@ -1,2 +1 @@ -from app.service.auth import check_access_token_valid from app.service.sockets import sio diff --git a/app/service/cors.py b/app/service/cors.py index 6f13669..0fdcd31 100644 --- a/app/service/cors.py +++ b/app/service/cors.py @@ -1,6 +1,6 @@ from fastapi.middleware.cors import CORSMiddleware -from app.main import server +from app.main import server origins = ["*"] diff --git a/app/service/sockets.py b/app/service/sockets.py index 338726e..7d24202 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,11 +1,8 @@ -from app.service.auth import check_access_token_valid import socketio from uuid import UUID -from fastapi.encoders import jsonable_encoder from app.core import socket_settinngs -from app.service import check_access_token_valid from app.models import StudyRooms from app.database import SessionLocal @@ -14,48 +11,39 @@ namespace_url = socket_settinngs.NAMESPACE_URL db = SessionLocal() model = StudyRooms +clients = dict() @sio.event(namespace=namespace_url) async def connect(sid, environ, auth): - print('sid: ', sid) - print('token: ', auth) - # token = auth['access_token'] - # email = check_access_token_valid(token) - # await sio.save_session(sid, {'user_email': email}, namespace=namespace_url) - + # Redis 사용자 정보 추가 + clients[sid] = auth['email'] + @sio.event(namespace=namespace_url) async def joinRoom(sid, room_id): + # Redis 사용자가 이용중인 스터디룸 정보 추가 sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) - print(sio.rooms(sid=sid, namespace=namespace_url)) - # session = await sio.get_session(sid, namespace=namespace_url) await sio.emit('response', {'message': 'room joined'}, room=room_id, namespace=namespace_url) - print(sio.rooms(sid=sid, namespace=namespace_url)) @sio.event(namespace=namespace_url) async def leaveRoom(sid, room_id): - print('sid: ', sid) - print('room_id: ', room_id) - print('leave') - print(sio.rooms(sid=sid, namespace=namespace_url)) sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) - print(sio.rooms(sid=sid, namespace=namespace_url)) study_room = db.query(model).filter(model.id == UUID(room_id)).update( {'current_join_counts': model.current_join_counts - 1} ) if study_room: + clients.pop(sid) db.commit() db.close() - print('here') await sio.emit('response', {'message': 'room leaved'}, room=room_id, namespace=namespace_url) - print('emit done') else: - await sio.emit('response', {'message': 'error'}, room=room_id, namespace=namespace_url) + await sio.emit('response', {'message': 'database error'}, room=room_id, namespace=namespace_url) @sio.event(namespace=namespace_url) async def status(sid, data): - # Redis + # Redis 사용자의 학습 상태 정보 추가 + # await sio.emit('response', {'message': 'success'}, room=room_id, namespace=namespace_url) pass \ No newline at end of file From 2c7a309bb26bf9513aa785514b810db8eff7c3cf Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 19 May 2021 23:25:39 +0900 Subject: [PATCH 073/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=9E=85=EC=9E=A5=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EB=B0=8F=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EA=B4=80=EB=A0=A8=20DB=20=EB=A1=9C=EC=A7=81=20CRUD?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EA=B4=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 6 +++--- app/core/config.py | 2 ++ app/crud/study_rooms.py | 24 +++++++++++++++++++++-- app/database/base_class.py | 1 + app/main.py | 2 +- app/service/sockets.py | 39 ++++++++++++++++++-------------------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 277cf71..07ed30b 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -57,7 +57,6 @@ ) def get_study_room(room_id: str, db: Session = Depends(get_db)): try: - print(db) data = study_rooms.get(db, room_id) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) @@ -234,7 +233,8 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) @router.post( - '/{room_id}/join', + # Endpoint 이름 변경 + '/{room_id}/join-check', responses = { 200: { "model": SuccessResponseBase, @@ -265,7 +265,7 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) ) def join_study_room(room_id: str, room_info: StudyRoomJoin, db: Session = Depends(get_db)): try: - # Redis 통해서 현재 사용자가 특정 방에 접속 중일 경우 에러 반환 로직 필요 + # TODO: Redis 통해서 현재 사용자가 특정 방에 접속 중일 경우 에러 반환 로직 필요 study_rooms.join(db, room_id, room_info) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) diff --git a/app/core/config.py b/app/core/config.py index 7aaa3be..53dbda9 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -23,6 +23,8 @@ class UserSettings(BaseSettings): class StudyRoomSettings(BaseSettings): API_STUDY_ROOM: str = '/study-rooms' + MIN_CAPACITY: int = 0 + MAX_CAPACITY: int = 5 class SocketSettings(BaseSettings): diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index aa84265..72e405f 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -4,6 +4,7 @@ from sqlalchemy.orm import Session from sqlalchemy.exc import IntegrityError +from app.core import study_rooms_settings from app.crud.base import CRUDBase from app.models import StudyRooms from app.schemas import ( @@ -19,6 +20,9 @@ ) +MAX_CAPACITY = study_rooms_settings.MAX_CAPACITY + + def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): return False if (not room_info.is_public) and (not room_info.password) else True @@ -49,7 +53,7 @@ def get(self, db: Session, room_id: UUID): def get_multi(self, db: Session, skip: int, limit: int, option: str): data = db.query(self.model).filter( - self.model.current_join_counts < 5 + self.model.current_join_counts < MAX_CAPACITY ).with_entities( self.model.id, self.model.title, @@ -116,7 +120,7 @@ def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() study_room = jsonable_encoder(data) if study_room: - if study_room['current_join_counts'] >= 5: + if study_room['current_join_counts'] >= MAX_CAPACITY: raise RequestConflictException(message='no empty') if study_room['is_public']: @@ -138,4 +142,20 @@ def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): raise NoSuchElementException(message='not found') + def leave(self, db: Session, room_id: str): + try: + db.query(self.model).filter(self.model.id == UUID(room_id)).update( + {'current_join_counts': self.model.current_join_counts - 1} + ) + db.commit() + return 'room leaved' + + except Exception as error: + # TODO: 더 구체적인 에러 핸들링 필요 ex. Positive Integer(MIN_CAPACITY) + return error + + finally: + db.close() + + study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file diff --git a/app/database/base_class.py b/app/database/base_class.py index fd71453..d6519cc 100644 --- a/app/database/base_class.py +++ b/app/database/base_class.py @@ -15,4 +15,5 @@ def __tablename__(self) -> str: return self.__name__.lower() def as_dict(self) -> dict: + # TODO: jsonable_encoder로 인해 발생하는 것으로 추정되는 오류 해결을 위한 함수 return {c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs} diff --git a/app/main.py b/app/main.py index b9a6183..3f0bb01 100644 --- a/app/main.py +++ b/app/main.py @@ -15,4 +15,4 @@ if __name__ == "__main__": - uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True, debug=True) + uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) diff --git a/app/service/sockets.py b/app/service/sockets.py index 7d24202..12e0837 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,49 +1,46 @@ import socketio -from uuid import UUID +from sqlalchemy.orm.session import Session -from app.core import socket_settinngs -from app.models import StudyRooms -from app.database import SessionLocal +from app.core import socket_settinngs +from app.crud import study_rooms +from app.database import SessionLocal -sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*') -namespace_url = socket_settinngs.NAMESPACE_URL db = SessionLocal() -model = StudyRooms +sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*', debug=True) +namespace_url = socket_settinngs.NAMESPACE_URL clients = dict() @sio.event(namespace=namespace_url) async def connect(sid, environ, auth): - # Redis 사용자 정보 추가 + # TODO: Redis 사용자 정보 추가 clients[sid] = auth['email'] @sio.event(namespace=namespace_url) async def joinRoom(sid, room_id): - # Redis 사용자가 이용중인 스터디룸 정보 추가 + # TODO: Redis 사용자가 이용중인 스터디룸 정보 추가 sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) await sio.emit('response', {'message': 'room joined'}, room=room_id, namespace=namespace_url) @sio.event(namespace=namespace_url) -async def leaveRoom(sid, room_id): - sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) - study_room = db.query(model).filter(model.id == UUID(room_id)).update( - {'current_join_counts': model.current_join_counts - 1} - ) - if study_room: +async def leaveRoom(sid, room_id, db: Session = db): + try: + # TODO: 축적된 학습 데이터 Redis > PostgreSQL 이동 필요 + message = study_rooms.leave(db, room_id=room_id) + await sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) clients.pop(sid) - db.commit() - db.close() - await sio.emit('response', {'message': 'room leaved'}, room=room_id, namespace=namespace_url) - else: - await sio.emit('response', {'message': 'database error'}, room=room_id, namespace=namespace_url) + await sio.emit('response', {'message': message}, room=room_id, namespace=namespace_url) + + except Exception as error: + await sio.emit('response', {'message': error}, room=room_id, namespace=namespace_url) @sio.event(namespace=namespace_url) async def status(sid, data): - # Redis 사용자의 학습 상태 정보 추가 + # TODO: Redis 사용자의 학습 상태 정보 추가 # await sio.emit('response', {'message': 'success'}, room=room_id, namespace=namespace_url) pass \ No newline at end of file From 7bce3bd6d7eddc3522e42007ef17e24fd061b544 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 20 May 2021 21:29:04 +0900 Subject: [PATCH 074/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20requirements.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/requirements.txt b/requirements.txt index 2a69587..6246f71 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1,23 @@ alembic==1.6.2 attrs==20.3.0 +bidict==0.21.2 certifi==2020.12.5 +cffi==1.14.5 chardet==4.0.0 click==7.1.2 cryptography==3.4.7 ecdsa==0.14.1 fastapi==0.65.0 +fastapi-socketio==0.0.6 greenlet==1.0.0 h11==0.12.0 +httptools==0.1.2 idna==2.10 iniconfig==1.1.1 jose==1.0.0 Mako==1.1.4 MarkupSafe==1.1.1 +netifaces==0.10.9 packaging==20.9 pluggy==0.13.1 psycopg2==2.8.6 @@ -26,7 +31,10 @@ pytest==6.2.4 python-dateutil==2.8.1 python-dotenv==0.17.1 python-editor==1.0.4 +python-engineio==4.2.0 python-jose==3.2.0 +python-socketio==5.3.0 +PyYAML==5.4.1 requests==2.25.1 rsa==4.7.2 six==1.16.0 @@ -36,3 +44,6 @@ toml==0.10.2 typing-extensions==3.7.4.3 urllib3==1.26.4 uvicorn==0.13.4 +uvloop==0.15.2 +watchgod==0.7 +websockets==8.1 From eb190596c55bdea50176087b3c65fdc8e614dba7 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 20 May 2021 22:30:20 +0900 Subject: [PATCH 075/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Error=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20stackoverflow=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 2 -- app/database/base_class.py | 4 ---- app/main.py | 4 +--- app/service/sockets.py | 2 ++ 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 07ed30b..3231d2c 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -233,7 +233,6 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) @router.post( - # Endpoint 이름 변경 '/{room_id}/join-check', responses = { 200: { @@ -265,7 +264,6 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) ) def join_study_room(room_id: str, room_info: StudyRoomJoin, db: Session = Depends(get_db)): try: - # TODO: Redis 통해서 현재 사용자가 특정 방에 접속 중일 경우 에러 반환 로직 필요 study_rooms.join(db, room_id, room_info) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) diff --git a/app/database/base_class.py b/app/database/base_class.py index d6519cc..ee344ad 100644 --- a/app/database/base_class.py +++ b/app/database/base_class.py @@ -13,7 +13,3 @@ class Base: @declared_attr def __tablename__(self) -> str: return self.__name__.lower() - - def as_dict(self) -> dict: - # TODO: jsonable_encoder로 인해 발생하는 것으로 추정되는 오류 해결을 위한 함수 - return {c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs} diff --git a/app/main.py b/app/main.py index 3f0bb01..cf466f4 100644 --- a/app/main.py +++ b/app/main.py @@ -5,13 +5,11 @@ from app.api import api_router from app.core import common_settings -from app.service import sio +# from app.service import sio server = FastAPI(title=common_settings.PROJECT_NAME) server.include_router(api_router, prefix=common_settings.COMMON_API) -server.mount('/', socketio.ASGIApp(sio, other_asgi_app=server)) - if __name__ == "__main__": diff --git a/app/service/sockets.py b/app/service/sockets.py index 12e0837..1a9449d 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -7,6 +7,8 @@ from app.database import SessionLocal +# TODO: server.mount 외에 소켓 route 통신 방법 + db = SessionLocal() sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*', debug=True) namespace_url = socket_settinngs.NAMESPACE_URL From 35982ec0b0f8d879d5f42da665bb9ccffd9a0e5a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 20 May 2021 22:31:22 +0900 Subject: [PATCH 076/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1c8c093..b03c4a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,6 @@ ADD . /code COPY ./requirements.txt /code/requirements.txt RUN pip install -r requirements.txt COPY . /code -ENV DOCKERIZE_VERSION v0.6.1\\ +ENV DOCKERIZE_VERSION v0.6.1 CMD ["python3", "-m", "app.main"] \ No newline at end of file From ea1ea71270cd678bd8122997263c1e5ba9b36e5a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 20 May 2021 23:14:57 +0900 Subject: [PATCH 077/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20update=20?= =?UTF-8?q?=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20Exception=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=B6=80=EB=B6=84=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 3231d2c..4cf16a0 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -116,7 +116,7 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {detail}'}) + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) @router.delete( From d9d8f7db0be7111602a5daea9c4b441f946e4d32 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 21 May 2021 00:07:07 +0900 Subject: [PATCH 078/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=ED=86=B5=EC=8B=A0=20=EC=97=B0=EA=B2=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/__init__.py | 11 +++++++---- app/main.py | 4 +++- app/service/__init__.py | 1 + app/service/sockets.py | 3 +-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/api/__init__.py b/app/api/__init__.py index 1a8abc3..156f7a0 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -1,7 +1,8 @@ -from fastapi import APIRouter +from fastapi import APIRouter, Depends -from app.api import users, study_rooms -from app.core import study_rooms_settings, user_settings +from app.api import users, study_rooms +from app.core import study_rooms_settings, user_settings +from app.service import auth_token api_router = APIRouter() @@ -10,8 +11,10 @@ prefix=user_settings.API_USER, tags=['users'] ) +# TODO: 의존성 추가 api_router.include_router( study_rooms.router, prefix=study_rooms_settings.API_STUDY_ROOM, + # dependencies=[Depends(auth_token),], tags=['study_rooms'] -) \ No newline at end of file +) \ No newline at end of file diff --git a/app/main.py b/app/main.py index cf466f4..1c74337 100644 --- a/app/main.py +++ b/app/main.py @@ -5,10 +5,12 @@ from app.api import api_router from app.core import common_settings -# from app.service import sio +from app.service import sio server = FastAPI(title=common_settings.PROJECT_NAME) +sio_app = socketio.ASGIApp(socketio_server=sio, other_asgi_app=server) +server.add_websocket_route("/socket.io/", sio_app) server.include_router(api_router, prefix=common_settings.COMMON_API) diff --git a/app/service/__init__.py b/app/service/__init__.py index c5ee7d3..62e6530 100644 --- a/app/service/__init__.py +++ b/app/service/__init__.py @@ -1 +1,2 @@ +from app.service.auth import auth_token from app.service.sockets import sio diff --git a/app/service/sockets.py b/app/service/sockets.py index 1a9449d..640a17e 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -7,14 +7,13 @@ from app.database import SessionLocal -# TODO: server.mount 외에 소켓 route 통신 방법 - db = SessionLocal() sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*', debug=True) namespace_url = socket_settinngs.NAMESPACE_URL clients = dict() + @sio.event(namespace=namespace_url) async def connect(sid, environ, auth): # TODO: Redis 사용자 정보 추가 From bafe97624aee4911ea12537c58142db2b5f06188 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 21 May 2021 19:00:18 +0900 Subject: [PATCH 079/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20CORS=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20ORIGIN=20&=20HOST=20=EB=93=B1=EC=9D=98=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 1 + app/core/config.py | 10 +++++++++- app/main.py | 22 ++++++++++++++++++---- app/service/cors.py | 14 -------------- 4 files changed, 28 insertions(+), 19 deletions(-) delete mode 100644 app/service/cors.py diff --git a/app/core/__init__.py b/app/core/__init__.py index 468a60e..0adba94 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -1,5 +1,6 @@ from app.core.config import ( common_settings, + develop_settings, study_rooms_settings, user_settings, socket_settinngs diff --git a/app/core/config.py b/app/core/config.py index 53dbda9..7f89ef9 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,5 +1,4 @@ import secrets -from uuid import NAMESPACE_URL from pydantic import BaseSettings @@ -14,6 +13,14 @@ class Config: env_file = ".env" +class DevelopSettings(BaseSettings): + ALLOW_ORIGIN: list = ['*'] + ALLOW_CREDENTIAL: bool = True + ALLOW_METHODS: list = ['*'] + ALLOW_HEADERS: list = ['*'] + ALLOW_HOST: list = ['*'] + + class UserSettings(BaseSettings): API_USER: str = '/user' SECRET_KEY: str = secrets.token_urlsafe(32) @@ -32,6 +39,7 @@ class SocketSettings(BaseSettings): common_settings = CommonSettings() +develop_settings = DevelopSettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() socket_settinngs = SocketSettings() diff --git a/app/main.py b/app/main.py index 1c74337..86ea377 100644 --- a/app/main.py +++ b/app/main.py @@ -1,15 +1,29 @@ import socketio import uvicorn -from fastapi import FastAPI +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from fastapi.middleware.trustedhost import TrustedHostMiddleware -from app.api import api_router -from app.core import common_settings -from app.service import sio +from app.api import api_router +from app.core import common_settings, develop_settings +from app.service import sio server = FastAPI(title=common_settings.PROJECT_NAME) sio_app = socketio.ASGIApp(socketio_server=sio, other_asgi_app=server) + +server.add_middleware( + CORSMiddleware, + allow_origins = develop_settings.ALLOW_ORIGIN, + allow_credentials = develop_settings.ALLOW_CREDENTIAL, + allow_methods = develop_settings.ALLOW_METHODS, + allow_headers = develop_settings.ALLOW_HEADERS +) +server.add_middleware( + TrustedHostMiddleware, + allowed_hosts = develop_settings.ALLOW_HOST, +) server.add_websocket_route("/socket.io/", sio_app) server.include_router(api_router, prefix=common_settings.COMMON_API) diff --git a/app/service/cors.py b/app/service/cors.py deleted file mode 100644 index 0fdcd31..0000000 --- a/app/service/cors.py +++ /dev/null @@ -1,14 +0,0 @@ -from fastapi.middleware.cors import CORSMiddleware - -from app.main import server - - -origins = ["*"] - -server.add_middleware( - CORSMiddleware, - allow_origins=origins, - allow_credentials=False, - allow_methods=["*"], - allow_headers=["*"], -) \ No newline at end of file From 228bfa5a6539adcb39dab9d0960196a464f061b7 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 21 May 2021 19:06:01 +0900 Subject: [PATCH 080/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20CORS=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20DeploySetting=20=EC=B6=94=EA=B0=80=20(=EC=B0=A8?= =?UTF-8?q?=ED=9B=84=20=EC=83=81=EC=84=B8=20=EB=82=B4=EC=97=AD=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=ED=95=84=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/core/config.py b/app/core/config.py index 7f89ef9..5fe720e 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -21,6 +21,15 @@ class DevelopSettings(BaseSettings): ALLOW_HOST: list = ['*'] +class DeploySettings(BaseSettings): + # TODO: 차후 배포 전 상세 설정 필요 + ALLOW_ORIGIN: list = ['*'] + ALLOW_CREDENTIAL: bool = True + ALLOW_METHODS: list = ['*'] + ALLOW_HEADERS: list = ['*'] + ALLOW_HOST: list = ['*'] + + class UserSettings(BaseSettings): API_USER: str = '/user' SECRET_KEY: str = secrets.token_urlsafe(32) @@ -40,6 +49,7 @@ class SocketSettings(BaseSettings): common_settings = CommonSettings() develop_settings = DevelopSettings() +deploy_settings = DeploySettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() socket_settinngs = SocketSettings() From f613365c11f7d913c1be612382a91ba1abf9d9a2 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 21 May 2021 23:18:39 +0900 Subject: [PATCH 081/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=EB=A0=88=ED=8F=AC=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/database/__init__.py | 3 +- app/models/__init__.py | 2 + app/models/my_studies.py | 23 ++++++ app/models/reports.py | 25 +++++++ app/models/study_rooms.py | 19 +++-- app/models/users.py | 3 +- .../06c00f7d39e4_create_users_table.py | 73 +++++++++++++++++++ 7 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 app/models/my_studies.py create mode 100644 app/models/reports.py create mode 100644 migrations/versions/06c00f7d39e4_create_users_table.py diff --git a/app/database/__init__.py b/app/database/__init__.py index 0cc812c..9c85b3f 100644 --- a/app/database/__init__.py +++ b/app/database/__init__.py @@ -1 +1,2 @@ -from app.database.session import SessionLocal \ No newline at end of file +from app.database.base_class import Base +from app.database.session import SessionLocal \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py index 886b0c8..00a3c3a 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,2 +1,4 @@ from app.models.users import User from app.models.study_rooms import StudyRooms +from app.models.my_studies import MyStudies +from app.models.reports import Reports diff --git a/app/models/my_studies.py b/app/models/my_studies.py new file mode 100644 index 0000000..904b50e --- /dev/null +++ b/app/models/my_studies.py @@ -0,0 +1,23 @@ +from sqlalchemy import ( + Column, + Integer, + ForeignKey, + ARRAY, + JSON, + TIMESTAMP + ) +from sqlalchemy.orm import relation + +from app.database import Base + + +class MyStudies(Base): + __tablename__ = 'my_studies' + id = Column(Integer(), primary_key=True, autoincrement=True) + started_at = Column(TIMESTAMP, nullable=False) + ended_at = Column(TIMESTAMP, nullable=False) + total_time = Column(Integer(), nullable=True) + star_count = Column(Integer(), nullable=True) + disturbance = Column(ARRAY(JSON), nullable=True) + report_id = Column(Integer(), ForeignKey('reports.id', ondelete='CASCADE')) + report = relation('Reports', back_populates='my_studies') diff --git a/app/models/reports.py b/app/models/reports.py new file mode 100644 index 0000000..faad238 --- /dev/null +++ b/app/models/reports.py @@ -0,0 +1,25 @@ +from sqlalchemy import ( + Column, + ForeignKey, + Integer, + Date, + ARRAY, + JSON + ) +from sqlalchemy.orm import relation + +from app.database import Base + + +class Reports(Base): + __tablename__ = 'reports' + id = Column(Integer(), primary_key=True, autoincrement=True) + date = Column(Date, nullable=False) + achivement = Column(Integer(), nullable=False) + concentration = Column(Integer(), nullable=False) + total_time = Column(Integer(), nullable=False) + total_star_count = Column(Integer(), nullable=False) + total_disturbance = Column(ARRAY(JSON), nullable=True) + user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) + user = relation('User', back_populates='reports') + my_studies = relation('MyStudies', back_populates='report') \ No newline at end of file diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index f618df5..c19bedc 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -1,11 +1,18 @@ from uuid import uuid4 from datetime import datetime, timedelta - -from sqlalchemy import Column, ForeignKey, String, Boolean, Integer, SmallInteger, DateTime +from sqlalchemy import ( + Column, + ForeignKey, + String, + Boolean, + Integer, + SmallInteger, + DateTime + ) from sqlalchemy.orm import relation from sqlalchemy.dialects.postgresql import UUID -from app.database.base_class import Base +from app.database import Base UTC_NOW = datetime.utcnow() @@ -18,9 +25,9 @@ class StudyRooms(Base): id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4) title = Column(String(64), nullable=False) description = Column(String(256), nullable=False) - is_public = Column(Boolean(), default=False, nullable=False) + is_public = Column(Boolean(), nullable=False) password = Column(String(32), nullable=True) current_join_counts = Column(SmallInteger(), nullable=False, default=0) - created_at = Column(DateTime(), default=KOR_NOW) + created_at = Column(DateTime(), default=KOR_NOW, nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) - owner = relation('User', back_populates = "study_rooms") + owner = relation('User', back_populates='study_rooms') diff --git a/app/models/users.py b/app/models/users.py index 3421ade..9c85fdd 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -19,4 +19,5 @@ class User(Base): social_id = Column('user_social_id', String, nullable=False, unique=True) nickname = Column('user_nickname', String, nullable=False, unique=True) goal = Column('user_goal', JSON, nullable=False) - study_rooms = relation('StudyRooms', back_populates = "owner") \ No newline at end of file + study_rooms = relation('StudyRooms', back_populates = 'owner') + reports = relation('Reports', back_populates = 'user') \ No newline at end of file diff --git a/migrations/versions/06c00f7d39e4_create_users_table.py b/migrations/versions/06c00f7d39e4_create_users_table.py new file mode 100644 index 0000000..ffdaac8 --- /dev/null +++ b/migrations/versions/06c00f7d39e4_create_users_table.py @@ -0,0 +1,73 @@ +"""create table + +Revision ID: 06c00f7d39e4 +Revises: +Create Date: 2021-05-21 21:56:15.511772 + +""" +from uuid import uuid4 +from datetime import datetime, timedelta +from alembic import op +from sqlalchemy.dialects.postgresql import UUID +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '06c00f7d39e4' +down_revision = None +branch_labels = None +depends_on = None + +UTC_NOW = datetime.utcnow() +KST = timedelta(hours=9) +KOR_NOW = UTC_NOW + KST + + +def upgrade(): + op.create_table( + 'users', + sa.Column('user_id', sa.Integer(), autoincrement=True, primary_key=True), + ) + + op.create_table( + 'study_rooms', + sa.Column('id', UUID(as_uuid=True), primary_key=True, default=uuid4), + sa.Column('title', sa.String(64), nullable=False), + sa.Column('description', sa.String(256), nullable=False), + sa.Column('is_public', sa.Boolean(), nullable=False), + sa.Column('password', sa.String(32), nullable=True), + sa.Column('current_join_counts', sa.SmallInteger(), nullable=False, default=0), + sa.Column('created_at', sa.DateTime(), default=KOR_NOW, nullable=False), + sa.Column('owner_id', sa.Integer(), sa.ForeignKey('users.user_id', ondelete='CASCADE')), + ) + + op.create_table( + 'reports', + sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), + sa.Column('date', sa.Date, nullable=False), + sa.Column('achivement', sa.Integer(), nullable=False), + sa.Column('concentration', sa.Integer(), nullable=False), + sa.Column('total_time', sa.Integer(), nullable=False), + sa.Column('total_star_count', sa.Integer(), nullable=False), + sa.Column('total_disturbance', sa.ARRAY(sa.JSON), nullable=True), + sa.Column('user_id', sa.Integer(), sa.ForeignKey('users.user_id', ondelete='CASCADE')), + ) + + op.create_table( + 'my_studies', + sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), + sa.Column('started_at', sa.TIMESTAMP, nullable=False), + sa.Column('ended_at', sa.TIMESTAMP, nullable=False), + sa.Column('total_time', sa.Integer(), nullable=False), + sa.Column('star_count', sa.Integer, nullable=True), + sa.Column('disturbance', sa.ARRAY(sa.JSON), nullable=True), + sa.Column('report_id', sa.Integer(), sa.ForeignKey('reports.id', ondelete='CASCADE')), + ) + + + +def downgrade(): + op.drop_table('users') + op.drop_table('study_rooms') + op.drop_table('my_studies') + op.drop_table('reports') From 85dbc314658c210f3828490a42a474ea9e14a409 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 21 May 2021 23:40:23 +0900 Subject: [PATCH 082/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20My=20Study=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20study=5Froom=5Fid=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/my_studies.py | 23 +++++++++++-------- app/models/study_rooms.py | 1 + .../06c00f7d39e4_create_users_table.py | 1 + 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 904b50e..5eb0423 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -1,14 +1,15 @@ -from sqlalchemy import ( - Column, - Integer, - ForeignKey, - ARRAY, - JSON, - TIMESTAMP - ) -from sqlalchemy.orm import relation +from sqlalchemy import ( + Column, + Integer, + ForeignKey, + ARRAY, + JSON, + TIMESTAMP + ) +from sqlalchemy.orm import relation +from sqlalchemy.dialects.postgresql import UUID -from app.database import Base +from app.database import Base class MyStudies(Base): @@ -20,4 +21,6 @@ class MyStudies(Base): star_count = Column(Integer(), nullable=True) disturbance = Column(ARRAY(JSON), nullable=True) report_id = Column(Integer(), ForeignKey('reports.id', ondelete='CASCADE')) + study_room_id = Column(UUID(), ForeignKey('study_rooms.id', ondelete='CASCADE')) report = relation('Reports', back_populates='my_studies') + study_room = relation('StudyRooms', back_populates='my_study') diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index c19bedc..21e961b 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -31,3 +31,4 @@ class StudyRooms(Base): created_at = Column(DateTime(), default=KOR_NOW, nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) owner = relation('User', back_populates='study_rooms') + my_study = relation('MyStudies', back_populates='study_room') \ No newline at end of file diff --git a/migrations/versions/06c00f7d39e4_create_users_table.py b/migrations/versions/06c00f7d39e4_create_users_table.py index ffdaac8..45db89a 100644 --- a/migrations/versions/06c00f7d39e4_create_users_table.py +++ b/migrations/versions/06c00f7d39e4_create_users_table.py @@ -62,6 +62,7 @@ def upgrade(): sa.Column('star_count', sa.Integer, nullable=True), sa.Column('disturbance', sa.ARRAY(sa.JSON), nullable=True), sa.Column('report_id', sa.Integer(), sa.ForeignKey('reports.id', ondelete='CASCADE')), + sa.Column('study_room_id', UUID(), sa.ForeignKey('study_rooms.id', ondelete='CASCADE')) ) From f9d405d99dc8d1ce0e776f9840d734c1a9701732 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sat, 22 May 2021 11:33:42 +0900 Subject: [PATCH 083/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20My=20Study=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20date=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20Report=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20date=20=EC=BB=AC=EB=9F=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/my_studies.py | 2 ++ app/models/reports.py | 2 -- migrations/versions/06c00f7d39e4_create_users_table.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 5eb0423..d97a32d 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -2,6 +2,7 @@ Column, Integer, ForeignKey, + Date, ARRAY, JSON, TIMESTAMP @@ -15,6 +16,7 @@ class MyStudies(Base): __tablename__ = 'my_studies' id = Column(Integer(), primary_key=True, autoincrement=True) + date = Column(Date, nullable=False) started_at = Column(TIMESTAMP, nullable=False) ended_at = Column(TIMESTAMP, nullable=False) total_time = Column(Integer(), nullable=True) diff --git a/app/models/reports.py b/app/models/reports.py index faad238..0e2889b 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -2,7 +2,6 @@ Column, ForeignKey, Integer, - Date, ARRAY, JSON ) @@ -14,7 +13,6 @@ class Reports(Base): __tablename__ = 'reports' id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column(Date, nullable=False) achivement = Column(Integer(), nullable=False) concentration = Column(Integer(), nullable=False) total_time = Column(Integer(), nullable=False) diff --git a/migrations/versions/06c00f7d39e4_create_users_table.py b/migrations/versions/06c00f7d39e4_create_users_table.py index 45db89a..432c16c 100644 --- a/migrations/versions/06c00f7d39e4_create_users_table.py +++ b/migrations/versions/06c00f7d39e4_create_users_table.py @@ -44,7 +44,6 @@ def upgrade(): op.create_table( 'reports', sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), - sa.Column('date', sa.Date, nullable=False), sa.Column('achivement', sa.Integer(), nullable=False), sa.Column('concentration', sa.Integer(), nullable=False), sa.Column('total_time', sa.Integer(), nullable=False), @@ -56,6 +55,7 @@ def upgrade(): op.create_table( 'my_studies', sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), + sa.Column('date', sa.Date, nullable=False), sa.Column('started_at', sa.TIMESTAMP, nullable=False), sa.Column('ended_at', sa.TIMESTAMP, nullable=False), sa.Column('total_time', sa.Integer(), nullable=False), From 41c5034d1ea53e74c4dd668a14408a3fd2415873 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sat, 22 May 2021 13:25:54 +0900 Subject: [PATCH 084/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Report=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20date=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/my_studies.py | 2 +- app/models/reports.py | 2 ++ migrations/versions/06c00f7d39e4_create_users_table.py | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/models/my_studies.py b/app/models/my_studies.py index d97a32d..33fc642 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -16,7 +16,7 @@ class MyStudies(Base): __tablename__ = 'my_studies' id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column(Date, nullable=False) + date = Column('study_date', Date, nullable=False) started_at = Column(TIMESTAMP, nullable=False) ended_at = Column(TIMESTAMP, nullable=False) total_time = Column(Integer(), nullable=True) diff --git a/app/models/reports.py b/app/models/reports.py index 0e2889b..f854a60 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -2,6 +2,7 @@ Column, ForeignKey, Integer, + Date, ARRAY, JSON ) @@ -13,6 +14,7 @@ class Reports(Base): __tablename__ = 'reports' id = Column(Integer(), primary_key=True, autoincrement=True) + date = Column('report_date', Date, nullable=False) achivement = Column(Integer(), nullable=False) concentration = Column(Integer(), nullable=False) total_time = Column(Integer(), nullable=False) diff --git a/migrations/versions/06c00f7d39e4_create_users_table.py b/migrations/versions/06c00f7d39e4_create_users_table.py index 432c16c..77934c5 100644 --- a/migrations/versions/06c00f7d39e4_create_users_table.py +++ b/migrations/versions/06c00f7d39e4_create_users_table.py @@ -44,6 +44,7 @@ def upgrade(): op.create_table( 'reports', sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), + sa.Column('report_date', sa.Date, nullable=False), sa.Column('achivement', sa.Integer(), nullable=False), sa.Column('concentration', sa.Integer(), nullable=False), sa.Column('total_time', sa.Integer(), nullable=False), @@ -55,7 +56,7 @@ def upgrade(): op.create_table( 'my_studies', sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), - sa.Column('date', sa.Date, nullable=False), + sa.Column('study_date', sa.Date, nullable=False), sa.Column('started_at', sa.TIMESTAMP, nullable=False), sa.Column('ended_at', sa.TIMESTAMP, nullable=False), sa.Column('total_time', sa.Integer(), nullable=False), From 0ed410d6347a8d8ba05d09ba28713d18a976dfa5 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sat, 22 May 2021 16:25:21 +0900 Subject: [PATCH 085/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=20MyStudies=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20date=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 2 +- app/core/config.py | 2 +- app/models/my_studies.py | 3 +-- app/models/reports.py | 10 +++++----- app/service/sockets.py | 4 ++-- .../versions/06c00f7d39e4_create_users_table.py | 15 +++++++-------- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/app/core/__init__.py b/app/core/__init__.py index 0adba94..fd0995b 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -3,5 +3,5 @@ develop_settings, study_rooms_settings, user_settings, - socket_settinngs + socket_settings ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index 5fe720e..b15d7b3 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -52,4 +52,4 @@ class SocketSettings(BaseSettings): deploy_settings = DeploySettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() -socket_settinngs = SocketSettings() +socket_settings = SocketSettings() diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 33fc642..5fd34a9 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -16,9 +16,8 @@ class MyStudies(Base): __tablename__ = 'my_studies' id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column('study_date', Date, nullable=False) started_at = Column(TIMESTAMP, nullable=False) - ended_at = Column(TIMESTAMP, nullable=False) + ended_at = Column(TIMESTAMP, nullable=True) total_time = Column(Integer(), nullable=True) star_count = Column(Integer(), nullable=True) disturbance = Column(ARRAY(JSON), nullable=True) diff --git a/app/models/reports.py b/app/models/reports.py index f854a60..ea01ac3 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -14,11 +14,11 @@ class Reports(Base): __tablename__ = 'reports' id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column('report_date', Date, nullable=False) - achivement = Column(Integer(), nullable=False) - concentration = Column(Integer(), nullable=False) - total_time = Column(Integer(), nullable=False) - total_star_count = Column(Integer(), nullable=False) + date = Column(Date, nullable=False) + achivement = Column(Integer(), nullable=True) + concentration = Column(Integer(), nullable=True) + total_time = Column(Integer(), nullable=True) + total_star_count = Column(Integer(), nullable=True) total_disturbance = Column(ARRAY(JSON), nullable=True) user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) user = relation('User', back_populates='reports') diff --git a/app/service/sockets.py b/app/service/sockets.py index 640a17e..e4e6f07 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -2,14 +2,14 @@ from sqlalchemy.orm.session import Session -from app.core import socket_settinngs +from app.core import socket_settings from app.crud import study_rooms from app.database import SessionLocal db = SessionLocal() sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*', debug=True) -namespace_url = socket_settinngs.NAMESPACE_URL +namespace_url = socket_settings.NAMESPACE_URL clients = dict() diff --git a/migrations/versions/06c00f7d39e4_create_users_table.py b/migrations/versions/06c00f7d39e4_create_users_table.py index 77934c5..ca15823 100644 --- a/migrations/versions/06c00f7d39e4_create_users_table.py +++ b/migrations/versions/06c00f7d39e4_create_users_table.py @@ -44,11 +44,11 @@ def upgrade(): op.create_table( 'reports', sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), - sa.Column('report_date', sa.Date, nullable=False), - sa.Column('achivement', sa.Integer(), nullable=False), - sa.Column('concentration', sa.Integer(), nullable=False), - sa.Column('total_time', sa.Integer(), nullable=False), - sa.Column('total_star_count', sa.Integer(), nullable=False), + sa.Column('date', sa.Date, nullable=False), + sa.Column('achivement', sa.Integer(), nullable=True), + sa.Column('concentration', sa.Integer(), nullable=True), + sa.Column('total_time', sa.Integer(), nullable=True), + sa.Column('total_star_count', sa.Integer(), nullable=True), sa.Column('total_disturbance', sa.ARRAY(sa.JSON), nullable=True), sa.Column('user_id', sa.Integer(), sa.ForeignKey('users.user_id', ondelete='CASCADE')), ) @@ -56,10 +56,9 @@ def upgrade(): op.create_table( 'my_studies', sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), - sa.Column('study_date', sa.Date, nullable=False), sa.Column('started_at', sa.TIMESTAMP, nullable=False), - sa.Column('ended_at', sa.TIMESTAMP, nullable=False), - sa.Column('total_time', sa.Integer(), nullable=False), + sa.Column('ended_at', sa.TIMESTAMP, nullable=True), + sa.Column('total_time', sa.Integer(), nullable=True), sa.Column('star_count', sa.Integer, nullable=True), sa.Column('disturbance', sa.ARRAY(sa.JSON), nullable=True), sa.Column('report_id', sa.Integer(), sa.ForeignKey('reports.id', ondelete='CASCADE')), From 48863c659aab3bf23ff36df759caf4f91d7cc0d0 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 23 May 2021 23:11:44 +0900 Subject: [PATCH 086/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=B0=8F=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/reports.py | 2 +- .../06c00f7d39e4_create_users_table.py | 74 ------------------- 2 files changed, 1 insertion(+), 75 deletions(-) delete mode 100644 migrations/versions/06c00f7d39e4_create_users_table.py diff --git a/app/models/reports.py b/app/models/reports.py index ea01ac3..6f7c1dd 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -15,7 +15,7 @@ class Reports(Base): __tablename__ = 'reports' id = Column(Integer(), primary_key=True, autoincrement=True) date = Column(Date, nullable=False) - achivement = Column(Integer(), nullable=True) + achievement = Column(Integer(), nullable=True) concentration = Column(Integer(), nullable=True) total_time = Column(Integer(), nullable=True) total_star_count = Column(Integer(), nullable=True) diff --git a/migrations/versions/06c00f7d39e4_create_users_table.py b/migrations/versions/06c00f7d39e4_create_users_table.py deleted file mode 100644 index ca15823..0000000 --- a/migrations/versions/06c00f7d39e4_create_users_table.py +++ /dev/null @@ -1,74 +0,0 @@ -"""create table - -Revision ID: 06c00f7d39e4 -Revises: -Create Date: 2021-05-21 21:56:15.511772 - -""" -from uuid import uuid4 -from datetime import datetime, timedelta -from alembic import op -from sqlalchemy.dialects.postgresql import UUID -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '06c00f7d39e4' -down_revision = None -branch_labels = None -depends_on = None - -UTC_NOW = datetime.utcnow() -KST = timedelta(hours=9) -KOR_NOW = UTC_NOW + KST - - -def upgrade(): - op.create_table( - 'users', - sa.Column('user_id', sa.Integer(), autoincrement=True, primary_key=True), - ) - - op.create_table( - 'study_rooms', - sa.Column('id', UUID(as_uuid=True), primary_key=True, default=uuid4), - sa.Column('title', sa.String(64), nullable=False), - sa.Column('description', sa.String(256), nullable=False), - sa.Column('is_public', sa.Boolean(), nullable=False), - sa.Column('password', sa.String(32), nullable=True), - sa.Column('current_join_counts', sa.SmallInteger(), nullable=False, default=0), - sa.Column('created_at', sa.DateTime(), default=KOR_NOW, nullable=False), - sa.Column('owner_id', sa.Integer(), sa.ForeignKey('users.user_id', ondelete='CASCADE')), - ) - - op.create_table( - 'reports', - sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), - sa.Column('date', sa.Date, nullable=False), - sa.Column('achivement', sa.Integer(), nullable=True), - sa.Column('concentration', sa.Integer(), nullable=True), - sa.Column('total_time', sa.Integer(), nullable=True), - sa.Column('total_star_count', sa.Integer(), nullable=True), - sa.Column('total_disturbance', sa.ARRAY(sa.JSON), nullable=True), - sa.Column('user_id', sa.Integer(), sa.ForeignKey('users.user_id', ondelete='CASCADE')), - ) - - op.create_table( - 'my_studies', - sa.Column('id', sa.Integer(), autoincrement=True, primary_key=True), - sa.Column('started_at', sa.TIMESTAMP, nullable=False), - sa.Column('ended_at', sa.TIMESTAMP, nullable=True), - sa.Column('total_time', sa.Integer(), nullable=True), - sa.Column('star_count', sa.Integer, nullable=True), - sa.Column('disturbance', sa.ARRAY(sa.JSON), nullable=True), - sa.Column('report_id', sa.Integer(), sa.ForeignKey('reports.id', ondelete='CASCADE')), - sa.Column('study_room_id', UUID(), sa.ForeignKey('study_rooms.id', ondelete='CASCADE')) - ) - - - -def downgrade(): - op.drop_table('users') - op.drop_table('study_rooms') - op.drop_table('my_studies') - op.drop_table('reports') From a3bb56d0b526f66eac169c713101f8197242fd68 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 24 May 2021 22:07:56 +0900 Subject: [PATCH 087/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EC=8A=A4?= =?UTF-8?q?=ED=82=A4=EB=A7=88=20=EB=B0=8F=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=8A=A4=ED=82=A4=EB=A7=88=20-=20My=20Stu?= =?UTF-8?q?dy=20=EB=B0=8F=20Report=20=ED=85=8C=EC=9D=B4=EB=B8=94=20disturb?= =?UTF-8?q?ance=20=EC=BB=AC=EB=9F=BC=20=EC=82=AD=EC=A0=9C=20-=20Disturbanc?= =?UTF-8?q?e=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=B6=94=EA=B0=80=20-=20Stud?= =?UTF-8?q?y=20Room=20=ED=85=8C=EC=9D=B4=EB=B8=94=20style=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20description=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=84=A0=ED=83=9D=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20style=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=97=94=EB=93=9C?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=8A=A4=ED=82=A4=EB=A7=88=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 3 ++- app/core/config.py | 8 ++++++++ app/crud/study_rooms.py | 2 ++ app/models/__init__.py | 9 +++++---- app/models/disturbances.py | 30 ++++++++++++++++++++++++++++++ app/models/my_studies.py | 2 +- app/models/reports.py | 4 ++-- app/models/study_rooms.py | 21 ++++++++++++++------- app/schemas/study_rooms/crud.py | 11 +++++++---- app/schemas/study_rooms/success.py | 3 +++ 10 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 app/models/disturbances.py diff --git a/app/core/__init__.py b/app/core/__init__.py index fd0995b..7178a80 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -3,5 +3,6 @@ develop_settings, study_rooms_settings, user_settings, - socket_settings + socket_settings, + time_settings ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index b15d7b3..1fd88c7 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,5 +1,6 @@ import secrets +from datetime import datetime, timedelta from pydantic import BaseSettings @@ -47,9 +48,16 @@ class SocketSettings(BaseSettings): NAMESPACE_URL: str = '/study' +class TimeSettings(BaseSettings): + UTC_NOW = datetime.utcnow() + KST = timedelta(hours=9) + KOR_NOW = UTC_NOW + KST + + common_settings = CommonSettings() develop_settings = DevelopSettings() deploy_settings = DeploySettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() socket_settings = SocketSettings() +time_settings = TimeSettings() diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 72e405f..0f273bc 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -35,6 +35,7 @@ def get(self, db: Session, room_id: UUID): ).with_entities( self.model.id, self.model.title, + self.model.style, self.model.description, self.model.is_public, self.model.current_join_counts, @@ -57,6 +58,7 @@ def get_multi(self, db: Session, skip: int, limit: int, option: str): ).with_entities( self.model.id, self.model.title, + self.model.style, self.model.description, self.model.is_public, self.model.current_join_counts, diff --git a/app/models/__init__.py b/app/models/__init__.py index 00a3c3a..f8c351f 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,4 +1,5 @@ -from app.models.users import User -from app.models.study_rooms import StudyRooms -from app.models.my_studies import MyStudies -from app.models.reports import Reports +from app.models.users import User +from app.models.study_rooms import StudyRooms, Style +from app.models.my_studies import MyStudies +from app.models.reports import Reports +from app.models.disturbances import Disturbances, Type diff --git a/app/models/disturbances.py b/app/models/disturbances.py new file mode 100644 index 0000000..84c549c --- /dev/null +++ b/app/models/disturbances.py @@ -0,0 +1,30 @@ +import enum + +from sqlalchemy import ( + Column, + Enum, + Integer, + SmallInteger, + ForeignKey + ) +from sqlalchemy.orm import relation + +from app.database import Base + + +class Type(str, enum.Enum): + SMARTPHONE = 'smartphone' + AWAIT = 'await' + SLEEP = 'sleep' + + +class Disturbances(Base): + __tablename__ = 'disturbances' + id = Column(Integer(), primary_key=True, autoincrement=True) + type = Column(Enum(Type), nullable=False) + count = Column(SmallInteger(), nullable=False) + time = Column(SmallInteger(), nullable=False) + my_study_id = Column(Integer(), ForeignKey('my_studies.id', ondelete=True)) + report_id = Column(Integer(), ForeignKey('reports.id', ondelete=True)) + my_study = relation('MyStudies', back_populates='disturbance') + report = relation('Reports', back_populates='total_disturbance') \ No newline at end of file diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 5fd34a9..3b3aba9 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -20,8 +20,8 @@ class MyStudies(Base): ended_at = Column(TIMESTAMP, nullable=True) total_time = Column(Integer(), nullable=True) star_count = Column(Integer(), nullable=True) - disturbance = Column(ARRAY(JSON), nullable=True) report_id = Column(Integer(), ForeignKey('reports.id', ondelete='CASCADE')) study_room_id = Column(UUID(), ForeignKey('study_rooms.id', ondelete='CASCADE')) report = relation('Reports', back_populates='my_studies') study_room = relation('StudyRooms', back_populates='my_study') + disturbance = relation('Disturbances', back_populates='my_study') diff --git a/app/models/reports.py b/app/models/reports.py index 6f7c1dd..14ec7ba 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -19,7 +19,7 @@ class Reports(Base): concentration = Column(Integer(), nullable=True) total_time = Column(Integer(), nullable=True) total_star_count = Column(Integer(), nullable=True) - total_disturbance = Column(ARRAY(JSON), nullable=True) user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) user = relation('User', back_populates='reports') - my_studies = relation('MyStudies', back_populates='report') \ No newline at end of file + my_studies = relation('MyStudies', back_populates='report') + total_disturbance = relation('Disturbances', back_populates='report') \ No newline at end of file diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index 21e961b..77a6f9d 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -1,5 +1,6 @@ +import enum + from uuid import uuid4 -from datetime import datetime, timedelta from sqlalchemy import ( Column, ForeignKey, @@ -7,28 +8,34 @@ Boolean, Integer, SmallInteger, - DateTime + DateTime, + Enum ) from sqlalchemy.orm import relation from sqlalchemy.dialects.postgresql import UUID from app.database import Base +from app.core import time_settings + -UTC_NOW = datetime.utcnow() -KST = timedelta(hours=9) -KOR_NOW = UTC_NOW + KST +class Style(str, enum.Enum): + STYLE_1 = 'style_1' + STYLE_2 = 'style_2' + STYLE_3 = 'style_3' + STYLE_4 = 'style_4' class StudyRooms(Base): __tablename__ = 'study_rooms' id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4) title = Column(String(64), nullable=False) - description = Column(String(256), nullable=False) + style = Column(Enum(Style), nullable=False) + description = Column(String(256), nullable=True) is_public = Column(Boolean(), nullable=False) password = Column(String(32), nullable=True) current_join_counts = Column(SmallInteger(), nullable=False, default=0) - created_at = Column(DateTime(), default=KOR_NOW, nullable=False) + created_at = Column(DateTime(), default=time_settings.KOR_NOW, nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) owner = relation('User', back_populates='study_rooms') my_study = relation('MyStudies', back_populates='study_room') \ No newline at end of file diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index 897dc25..b7aefc5 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -1,14 +1,17 @@ -from typing import Optional -from pydantic import BaseModel +from typing import Optional +from pydantic import BaseModel + +from app.models import Style class StudyRoomsBase(BaseModel): + description: Optional[str] password: Optional[str] class StudyRoomsCreate(StudyRoomsBase): title: str - description: str + style: Style is_public: bool current_join_counts: int = 0 owner_id: int @@ -17,6 +20,7 @@ class Config: schema_extra = { 'example': { 'title': '주 4시간 이상 고시 공부방 🔥', + 'style': 'style_2', 'description': '같이 열심히 공부하실 분들만!', 'is_public': False, 'password': 'TestPassword!234', @@ -27,7 +31,6 @@ class Config: class StudyRoomsUpdate(StudyRoomsBase): title: Optional[str] - description: Optional[str] is_public: Optional[bool] class Config: diff --git a/app/schemas/study_rooms/success.py b/app/schemas/study_rooms/success.py index 02e5136..7ac6f48 100644 --- a/app/schemas/study_rooms/success.py +++ b/app/schemas/study_rooms/success.py @@ -7,6 +7,7 @@ class Config: 'example': { 'data': { "is_public": False, + "style": "style_1", "title": "스터디 룸 제목 수정", "created_at": "2021-05-09T20:50:11.782727", "id": "3d37627c-d87d-469e-8bf3-db7e796838cf", @@ -25,6 +26,7 @@ class Config: 'data': [ { "title": "스터디 룸 제목 수정", + "style": "style_2", "is_public": False, "created_at": "2021-05-09T20:50:11.782727", "description": "스터디룸 설명", @@ -34,6 +36,7 @@ class Config: }, { "title": "스터디룸 생성 제목", + "style": "style_2", "is_public": True, "created_at": "2021-05-09T20:50:11.782727", "description": "스터디룸 설명", From 815b80b81909f8f5721fc2c86327d5002579d1f4 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 24 May 2021 22:34:47 +0900 Subject: [PATCH 088/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20time=5Fsettings=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 3 +-- app/core/config.py | 7 ------- app/models/disturbances.py | 5 ++--- app/models/my_studies.py | 8 +++++++- app/models/reports.py | 19 ++++++++++++++----- app/models/study_rooms.py | 8 ++++++-- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/app/core/__init__.py b/app/core/__init__.py index 7178a80..fd0995b 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -3,6 +3,5 @@ develop_settings, study_rooms_settings, user_settings, - socket_settings, - time_settings + socket_settings ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index 1fd88c7..fe8893f 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -48,16 +48,9 @@ class SocketSettings(BaseSettings): NAMESPACE_URL: str = '/study' -class TimeSettings(BaseSettings): - UTC_NOW = datetime.utcnow() - KST = timedelta(hours=9) - KOR_NOW = UTC_NOW + KST - - common_settings = CommonSettings() develop_settings = DevelopSettings() deploy_settings = DeploySettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() socket_settings = SocketSettings() -time_settings = TimeSettings() diff --git a/app/models/disturbances.py b/app/models/disturbances.py index 84c549c..898dd9c 100644 --- a/app/models/disturbances.py +++ b/app/models/disturbances.py @@ -4,7 +4,6 @@ Column, Enum, Integer, - SmallInteger, ForeignKey ) from sqlalchemy.orm import relation @@ -22,8 +21,8 @@ class Disturbances(Base): __tablename__ = 'disturbances' id = Column(Integer(), primary_key=True, autoincrement=True) type = Column(Enum(Type), nullable=False) - count = Column(SmallInteger(), nullable=False) - time = Column(SmallInteger(), nullable=False) + count = Column(Integer(), nullable=False) + time = Column(Integer(), nullable=False) my_study_id = Column(Integer(), ForeignKey('my_studies.id', ondelete=True)) report_id = Column(Integer(), ForeignKey('reports.id', ondelete=True)) my_study = relation('MyStudies', back_populates='disturbance') diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 3b3aba9..47db8b5 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -1,3 +1,4 @@ +from datetime import datetime, timedelta from sqlalchemy import ( Column, Integer, @@ -13,10 +14,15 @@ from app.database import Base +UTC_NOW = datetime.utcnow() +KST = timedelta(hours=9) +KOR_NOW = UTC_NOW + KST + + class MyStudies(Base): __tablename__ = 'my_studies' id = Column(Integer(), primary_key=True, autoincrement=True) - started_at = Column(TIMESTAMP, nullable=False) + started_at = Column(TIMESTAMP, default=KOR_NOW, nullable=False) ended_at = Column(TIMESTAMP, nullable=True) total_time = Column(Integer(), nullable=True) star_count = Column(Integer(), nullable=True) diff --git a/app/models/reports.py b/app/models/reports.py index 14ec7ba..e36f5c4 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -1,20 +1,29 @@ +from datetime import datetime, timedelta from sqlalchemy import ( Column, ForeignKey, Integer, - Date, - ARRAY, - JSON + Date ) from sqlalchemy.orm import relation from app.database import Base +UTC_NOW = datetime.utcnow() +KST = timedelta(hours=9) +KOR_NOW = UTC_NOW + KST + +if (KOR_NOW.hour >= 00) and (KOR_NOW.hour < 5): + KOR_DATE = datetime(KOR_NOW.year, KOR_NOW.month, KOR_NOW.day - 1) +else: + KOR_DATE = datetime(KOR_NOW.year, KOR_NOW.month, KOR_NOW.day) + + class Reports(Base): __tablename__ = 'reports' id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column(Date, nullable=False) + date = Column(Date, default=KOR_DATE, nullable=False) achievement = Column(Integer(), nullable=True) concentration = Column(Integer(), nullable=True) total_time = Column(Integer(), nullable=True) @@ -22,4 +31,4 @@ class Reports(Base): user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) user = relation('User', back_populates='reports') my_studies = relation('MyStudies', back_populates='report') - total_disturbance = relation('Disturbances', back_populates='report') \ No newline at end of file + total_disturbance = relation('Disturbances', back_populates='report') diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index 77a6f9d..005bee5 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -1,5 +1,6 @@ import enum +from datetime import datetime, timedelta from uuid import uuid4 from sqlalchemy import ( Column, @@ -15,9 +16,12 @@ from sqlalchemy.dialects.postgresql import UUID from app.database import Base -from app.core import time_settings +UTC_NOW = datetime.utcnow() +KST = timedelta(hours=9) +KOR_NOW = UTC_NOW + KST + class Style(str, enum.Enum): STYLE_1 = 'style_1' @@ -35,7 +39,7 @@ class StudyRooms(Base): is_public = Column(Boolean(), nullable=False) password = Column(String(32), nullable=True) current_join_counts = Column(SmallInteger(), nullable=False, default=0) - created_at = Column(DateTime(), default=time_settings.KOR_NOW, nullable=False) + created_at = Column(DateTime(), default=KOR_NOW, nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) owner = relation('User', back_populates='study_rooms') my_study = relation('MyStudies', back_populates='study_room') \ No newline at end of file From 7dd65055d20a9b128c2f49d315ec1cd87f45e66a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 24 May 2021 22:49:50 +0900 Subject: [PATCH 089/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20TimeSettings=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20KCT=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 3 ++- app/core/config.py | 7 ++++++- app/models/my_studies.py | 7 +++---- app/models/reports.py | 7 +++---- app/models/study_rooms.py | 7 +++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/core/__init__.py b/app/core/__init__.py index fd0995b..7178a80 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -3,5 +3,6 @@ develop_settings, study_rooms_settings, user_settings, - socket_settings + socket_settings, + time_settings ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index fe8893f..3f048cc 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,6 +1,6 @@ import secrets -from datetime import datetime, timedelta +from datetime import timedelta from pydantic import BaseSettings @@ -48,9 +48,14 @@ class SocketSettings(BaseSettings): NAMESPACE_URL: str = '/study' +class TimeSettings(BaseSettings): + KST = timedelta(hours=9) + + common_settings = CommonSettings() develop_settings = DevelopSettings() deploy_settings = DeploySettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() socket_settings = SocketSettings() +time_settings = TimeSettings() diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 47db8b5..8294b14 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import datetime from sqlalchemy import ( Column, Integer, @@ -12,11 +12,10 @@ from sqlalchemy.dialects.postgresql import UUID from app.database import Base +from app.core import time_settings -UTC_NOW = datetime.utcnow() -KST = timedelta(hours=9) -KOR_NOW = UTC_NOW + KST +KOR_NOW = datetime.utcnow() + time_settings.KST class MyStudies(Base): diff --git a/app/models/reports.py b/app/models/reports.py index e36f5c4..e423024 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import datetime from sqlalchemy import ( Column, ForeignKey, @@ -8,11 +8,10 @@ from sqlalchemy.orm import relation from app.database import Base +from app.core import time_settings -UTC_NOW = datetime.utcnow() -KST = timedelta(hours=9) -KOR_NOW = UTC_NOW + KST +KOR_NOW = datetime.utcnow() + time_settings.KST if (KOR_NOW.hour >= 00) and (KOR_NOW.hour < 5): KOR_DATE = datetime(KOR_NOW.year, KOR_NOW.month, KOR_NOW.day - 1) diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index 005bee5..a33d01e 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -1,6 +1,6 @@ import enum -from datetime import datetime, timedelta +from datetime import datetime from uuid import uuid4 from sqlalchemy import ( Column, @@ -16,11 +16,10 @@ from sqlalchemy.dialects.postgresql import UUID from app.database import Base +from app.core import time_settings -UTC_NOW = datetime.utcnow() -KST = timedelta(hours=9) -KOR_NOW = UTC_NOW + KST +KOR_NOW = datetime.utcnow() + time_settings.KST class Style(str, enum.Enum): From f47b621fb01b34946505970c852d4344027c9909 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 24 May 2021 22:53:16 +0900 Subject: [PATCH 090/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/my_studies.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 8294b14..bbd9c58 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -3,9 +3,6 @@ Column, Integer, ForeignKey, - Date, - ARRAY, - JSON, TIMESTAMP ) from sqlalchemy.orm import relation From 09337ede7a00fa98e2ef5f030cea0885757f389d Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 24 May 2021 23:06:45 +0900 Subject: [PATCH 091/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20date=20default=20?= =?UTF-8?q?value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/my_studies.py | 5 +---- app/models/reports.py | 11 +---------- app/models/study_rooms.py | 5 +---- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/app/models/my_studies.py b/app/models/my_studies.py index bbd9c58..380e37a 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -12,13 +12,10 @@ from app.core import time_settings -KOR_NOW = datetime.utcnow() + time_settings.KST - - class MyStudies(Base): __tablename__ = 'my_studies' id = Column(Integer(), primary_key=True, autoincrement=True) - started_at = Column(TIMESTAMP, default=KOR_NOW, nullable=False) + started_at = Column(TIMESTAMP, default=datetime.utcnow() + time_settings.KST, nullable=False) ended_at = Column(TIMESTAMP, nullable=True) total_time = Column(Integer(), nullable=True) star_count = Column(Integer(), nullable=True) diff --git a/app/models/reports.py b/app/models/reports.py index e423024..46c6d96 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -8,21 +8,12 @@ from sqlalchemy.orm import relation from app.database import Base -from app.core import time_settings - - -KOR_NOW = datetime.utcnow() + time_settings.KST - -if (KOR_NOW.hour >= 00) and (KOR_NOW.hour < 5): - KOR_DATE = datetime(KOR_NOW.year, KOR_NOW.month, KOR_NOW.day - 1) -else: - KOR_DATE = datetime(KOR_NOW.year, KOR_NOW.month, KOR_NOW.day) class Reports(Base): __tablename__ = 'reports' id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column(Date, default=KOR_DATE, nullable=False) + date = Column(Date, nullable=False) achievement = Column(Integer(), nullable=True) concentration = Column(Integer(), nullable=True) total_time = Column(Integer(), nullable=True) diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index a33d01e..76ca505 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -19,9 +19,6 @@ from app.core import time_settings -KOR_NOW = datetime.utcnow() + time_settings.KST - - class Style(str, enum.Enum): STYLE_1 = 'style_1' STYLE_2 = 'style_2' @@ -38,7 +35,7 @@ class StudyRooms(Base): is_public = Column(Boolean(), nullable=False) password = Column(String(32), nullable=True) current_join_counts = Column(SmallInteger(), nullable=False, default=0) - created_at = Column(DateTime(), default=KOR_NOW, nullable=False) + created_at = Column(DateTime(), default=datetime.utcnow() + time_settings.KST, nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) owner = relation('User', back_populates='study_rooms') my_study = relation('MyStudies', back_populates='study_room') \ No newline at end of file From 420b99d16358e6eed44a1fbb14cc0a54e6e9a0b6 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 19:25:25 +0900 Subject: [PATCH 092/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 4cf16a0..b71444f 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -19,6 +19,7 @@ GetStudyRoomResponse, GetStudyRoomsResponse, NotFoundStudyRoomHandling, + NotFoundUserHandling, PasswordNeedyStudyRoomHandling, BodyNeedyStudyRoomHandling, QueryNeedyStudyRoomHandling, @@ -164,7 +165,7 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): }, 404: { "model": NotFoundStudyRoomHandling, - "description": "조회한 스터디룸이 존재하지 않는 경우" + "description": "조회할 스터디룸이 존재하지 않는 경우" }, 422: { "model": QueryNeedyStudyRoomHandling, @@ -183,7 +184,7 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session except NoSuchElementException as element_err: message = element_err.message - detail = get_detail(param='database', field='user', message=message, err='database') + detail = get_detail(param='database', field='study room', message=message, err='database') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) except Exception as error: @@ -199,7 +200,7 @@ def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session "description": "스터디룸 생성 성공" }, 404: { - "model": NotFoundStudyRoomHandling, + "model": NotFoundUserHandling, "description": "방을 만드려는 사용자가 존재하지 않는 경우 (Postman 등을 통한 악용 방지)" }, 422: { @@ -245,7 +246,7 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) }, 404: { "model": NotFoundStudyRoomHandling, - "description": "존재하지 않으려는 방에 접근하려는 경우" + "description": "존재하지 않는 방에 접근하려는 경우" }, 409: { "model": NoEmptyRoomHandling, From 1867bc31ef926fa6ac2e2c5b9feccc8d4206c8d3 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 20:59:22 +0900 Subject: [PATCH 093/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=EC=97=90=EC=84=9C=20=EC=B2=98=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8D=98=20default=20date=20=EA=B0=92=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 3 +++ app/models/my_studies.py | 3 +-- app/models/study_rooms.py | 3 +-- app/schemas/study_rooms/crud.py | 2 ++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 0f273bc..f551cba 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,5 +1,6 @@ from uuid import UUID from typing import Union +from datetime import datetime from fastapi.encoders import jsonable_encoder from sqlalchemy.orm import Session from sqlalchemy.exc import IntegrityError @@ -18,6 +19,7 @@ RequestConflictException, ForbiddenException ) +from app.core import time_settings MAX_CAPACITY = study_rooms_settings.MAX_CAPACITY @@ -78,6 +80,7 @@ def create(self, db: Session, room_info: StudyRoomsCreate): raise InvalidArgumentException(message='field required') room_info.current_join_counts += 1 + room_info.created_at = datetime.utcnow() + time_settings.KST data = self.model(**jsonable_encoder(room_info)) db.add(data) db.commit() diff --git a/app/models/my_studies.py b/app/models/my_studies.py index 380e37a..fd56a8d 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -9,13 +9,12 @@ from sqlalchemy.dialects.postgresql import UUID from app.database import Base -from app.core import time_settings class MyStudies(Base): __tablename__ = 'my_studies' id = Column(Integer(), primary_key=True, autoincrement=True) - started_at = Column(TIMESTAMP, default=datetime.utcnow() + time_settings.KST, nullable=False) + started_at = Column(TIMESTAMP, nullable=False) ended_at = Column(TIMESTAMP, nullable=True) total_time = Column(Integer(), nullable=True) star_count = Column(Integer(), nullable=True) diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index 76ca505..6a47ba0 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -16,7 +16,6 @@ from sqlalchemy.dialects.postgresql import UUID from app.database import Base -from app.core import time_settings class Style(str, enum.Enum): @@ -35,7 +34,7 @@ class StudyRooms(Base): is_public = Column(Boolean(), nullable=False) password = Column(String(32), nullable=True) current_join_counts = Column(SmallInteger(), nullable=False, default=0) - created_at = Column(DateTime(), default=datetime.utcnow() + time_settings.KST, nullable=False) + created_at = Column(DateTime(), nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) owner = relation('User', back_populates='study_rooms') my_study = relation('MyStudies', back_populates='study_room') \ No newline at end of file diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index b7aefc5..a97618d 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -1,5 +1,6 @@ from typing import Optional from pydantic import BaseModel +from datetime import datetime from app.models import Style @@ -14,6 +15,7 @@ class StudyRoomsCreate(StudyRoomsBase): style: Style is_public: bool current_join_counts: int = 0 + created_at: Optional[datetime] owner_id: int class Config: From f2966a370a23e060d62a3528e3997a3df8f917b4 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 21:29:36 +0900 Subject: [PATCH 094/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=BB=AC=EB=9F=BC=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/__init__.py | 2 +- app/models/disturbances.py | 14 +++++++------- app/models/my_studies.py | 15 +++++++-------- app/models/reports.py | 13 ++++++------- app/models/study_rooms.py | 16 ++++++++-------- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/app/models/__init__.py b/app/models/__init__.py index f8c351f..b53006b 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -2,4 +2,4 @@ from app.models.study_rooms import StudyRooms, Style from app.models.my_studies import MyStudies from app.models.reports import Reports -from app.models.disturbances import Disturbances, Type +from app.models.disturbances import Disturbances, DisturbanceType diff --git a/app/models/disturbances.py b/app/models/disturbances.py index 898dd9c..3b832ca 100644 --- a/app/models/disturbances.py +++ b/app/models/disturbances.py @@ -11,7 +11,7 @@ from app.database import Base -class Type(str, enum.Enum): +class DisturbanceType(str, enum.Enum): SMARTPHONE = 'smartphone' AWAIT = 'await' SLEEP = 'sleep' @@ -19,11 +19,11 @@ class Type(str, enum.Enum): class Disturbances(Base): __tablename__ = 'disturbances' - id = Column(Integer(), primary_key=True, autoincrement=True) - type = Column(Enum(Type), nullable=False) - count = Column(Integer(), nullable=False) - time = Column(Integer(), nullable=False) - my_study_id = Column(Integer(), ForeignKey('my_studies.id', ondelete=True)) - report_id = Column(Integer(), ForeignKey('reports.id', ondelete=True)) + id = Column('disturbance_id', Integer(), primary_key=True, autoincrement=True) + type = Column('disturbance_type', Enum(DisturbanceType), nullable=False) + count = Column('disturbance_count', Integer(), nullable=False) + time = Column('disturbance_time', Integer(), nullable=False) + my_study_id = Column(Integer(), ForeignKey('my_studies.my_study_id', ondelete=True)) + report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete=True)) my_study = relation('MyStudies', back_populates='disturbance') report = relation('Reports', back_populates='total_disturbance') \ No newline at end of file diff --git a/app/models/my_studies.py b/app/models/my_studies.py index fd56a8d..b1ff351 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -1,4 +1,3 @@ -from datetime import datetime from sqlalchemy import ( Column, Integer, @@ -13,13 +12,13 @@ class MyStudies(Base): __tablename__ = 'my_studies' - id = Column(Integer(), primary_key=True, autoincrement=True) - started_at = Column(TIMESTAMP, nullable=False) - ended_at = Column(TIMESTAMP, nullable=True) - total_time = Column(Integer(), nullable=True) - star_count = Column(Integer(), nullable=True) - report_id = Column(Integer(), ForeignKey('reports.id', ondelete='CASCADE')) - study_room_id = Column(UUID(), ForeignKey('study_rooms.id', ondelete='CASCADE')) + id = Column('my_study_id', Integer(), primary_key=True, autoincrement=True) + started_at = Column('my_study_started_at', TIMESTAMP, nullable=False) + ended_at = Column('my_study_ended_at', TIMESTAMP, nullable=True) + total_time = Column('my_study_total_time', Integer(), nullable=True) + star_count = Column('my_study_star_count', Integer(), nullable=True) + report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete='CASCADE')) + study_room_id = Column(UUID(), ForeignKey('study_rooms.study_room_id', ondelete='CASCADE')) report = relation('Reports', back_populates='my_studies') study_room = relation('StudyRooms', back_populates='my_study') disturbance = relation('Disturbances', back_populates='my_study') diff --git a/app/models/reports.py b/app/models/reports.py index 46c6d96..f69b263 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -1,4 +1,3 @@ -from datetime import datetime from sqlalchemy import ( Column, ForeignKey, @@ -12,12 +11,12 @@ class Reports(Base): __tablename__ = 'reports' - id = Column(Integer(), primary_key=True, autoincrement=True) - date = Column(Date, nullable=False) - achievement = Column(Integer(), nullable=True) - concentration = Column(Integer(), nullable=True) - total_time = Column(Integer(), nullable=True) - total_star_count = Column(Integer(), nullable=True) + id = Column('report_id', Integer(), primary_key=True, autoincrement=True) + date = Column('report_date', Date, nullable=False) + achievement = Column('report_achievement', Integer(), nullable=True) + concentration = Column('report_concentration', Integer(), nullable=True) + total_time = Column('report_total_time', Integer(), nullable=True) + total_star_count = Column('report_total_star_count', Integer(), nullable=True) user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) user = relation('User', back_populates='reports') my_studies = relation('MyStudies', back_populates='report') diff --git a/app/models/study_rooms.py b/app/models/study_rooms.py index 6a47ba0..37cb34d 100644 --- a/app/models/study_rooms.py +++ b/app/models/study_rooms.py @@ -27,14 +27,14 @@ class Style(str, enum.Enum): class StudyRooms(Base): __tablename__ = 'study_rooms' - id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4) - title = Column(String(64), nullable=False) - style = Column(Enum(Style), nullable=False) - description = Column(String(256), nullable=True) - is_public = Column(Boolean(), nullable=False) - password = Column(String(32), nullable=True) - current_join_counts = Column(SmallInteger(), nullable=False, default=0) - created_at = Column(DateTime(), nullable=False) + id = Column('study_room_id', UUID(as_uuid=True), primary_key=True, default=uuid4) + title = Column('study_room_title', String(64), nullable=False) + style = Column('study_room_style', Enum(Style), nullable=False) + description = Column('study_room_description', String(256), nullable=True) + is_public = Column('study_room_is_public', Boolean(), nullable=False) + password = Column('study_room_password', String(32), nullable=True) + current_join_counts = Column('study_room_current_join_counts', SmallInteger(), nullable=False, default=0) + created_at = Column('study_room_created_at', DateTime(), nullable=False) owner_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) owner = relation('User', back_populates='study_rooms') my_study = relation('MyStudies', back_populates='study_room') \ No newline at end of file From 10fae07f74846f2045b36da01decfcae0d72444f Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 22:23:15 +0900 Subject: [PATCH 095/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index f551cba..0b5b015 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -66,7 +66,7 @@ def get_multi(self, db: Session, skip: int, limit: int, option: str): self.model.current_join_counts, self.model.created_at, self.model.owner_id - ).order_by(f'{option}').offset(skip).limit(limit).all() + ).order_by(f'study_room_{option}').offset(skip).limit(limit).all() if data: return jsonable_encoder(data) From 452e08e67ee80ded04ced439dfee5661547ce667 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 22:31:52 +0900 Subject: [PATCH 096/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20ondelete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/disturbances.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/disturbances.py b/app/models/disturbances.py index 3b832ca..08cf3df 100644 --- a/app/models/disturbances.py +++ b/app/models/disturbances.py @@ -23,7 +23,7 @@ class Disturbances(Base): type = Column('disturbance_type', Enum(DisturbanceType), nullable=False) count = Column('disturbance_count', Integer(), nullable=False) time = Column('disturbance_time', Integer(), nullable=False) - my_study_id = Column(Integer(), ForeignKey('my_studies.my_study_id', ondelete=True)) - report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete=True)) + my_study_id = Column(Integer(), ForeignKey('my_studies.my_study_id', ondelete='CASCADE')) + report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete='CASCADE')) my_study = relation('MyStudies', back_populates='disturbance') report = relation('Reports', back_populates='total_disturbance') \ No newline at end of file From 34b55631860ae10a6c5518b055af77e6f26851c3 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 22:33:58 +0900 Subject: [PATCH 097/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20as=5Fuuid=3DTrue?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/my_studies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/my_studies.py b/app/models/my_studies.py index b1ff351..b5869ab 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -18,7 +18,7 @@ class MyStudies(Base): total_time = Column('my_study_total_time', Integer(), nullable=True) star_count = Column('my_study_star_count', Integer(), nullable=True) report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete='CASCADE')) - study_room_id = Column(UUID(), ForeignKey('study_rooms.study_room_id', ondelete='CASCADE')) + study_room_id = Column(UUID(as_uuid=True), ForeignKey('study_rooms.study_room_id', ondelete='CASCADE')) report = relation('Reports', back_populates='my_studies') study_room = relation('StudyRooms', back_populates='my_study') disturbance = relation('Disturbances', back_populates='my_study') From 7b93fe4a9f47b620f4acb9c976cd15472134e100 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 26 May 2021 01:28:38 +0900 Subject: [PATCH 098/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EB=B3=B8?= =?UTF-8?q?=EC=9D=B8=EC=9D=B4=20=EB=A7=8C=EB=93=A0=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=EB=A3=B8=20=EC=A1=B0=ED=9A=8C=20=EA=B0=80=EB=8A=A5?= =?UTF-8?q?=ED=95=98=EA=B2=8C=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 11 +++++++++-- app/crud/study_rooms.py | 13 +++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index b71444f..8dbc324 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -1,5 +1,6 @@ import traceback +from typing import Optional from fastapi import ( APIRouter, Depends, @@ -177,9 +178,15 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): } } ) -def get_study_rooms(skip: int, limit: int, option: str='created_at', db: Session = Depends(get_db)): +def get_study_rooms( + skip: int, + limit: int, + owner_id: Optional[int] = None, + option: str = 'created_at', + db: Session = Depends(get_db) +): try: - data = study_rooms.get_multi(db, skip, limit, option) + data = study_rooms.get_multi(db, skip, limit, owner_id, option) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) except NoSuchElementException as element_err: diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 0b5b015..0bea803 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,7 +1,8 @@ from uuid import UUID -from typing import Union +from typing import Union, Optional from datetime import datetime from fastapi.encoders import jsonable_encoder +from sqlalchemy import and_ from sqlalchemy.orm import Session from sqlalchemy.exc import IntegrityError @@ -54,10 +55,14 @@ def get(self, db: Session, room_id: UUID): raise NoSuchElementException(message='not found') - def get_multi(self, db: Session, skip: int, limit: int, option: str): - data = db.query(self.model).filter( + def get_multi(self, db: Session, skip: int, limit: int, owner_id: Optional[int], option: str): + query = db.query(self.model) + if owner_id: + query = query.filter(self.model.owner_id == owner_id) + + data = query.filter(( self.model.current_join_counts < MAX_CAPACITY - ).with_entities( + )).with_entities( self.model.id, self.model.title, self.model.style, From b2d4322c72dec55ac54508130f8348ad00c07349 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 26 May 2021 19:32:19 +0900 Subject: [PATCH 099/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=A1=B0=ED=9A=8C=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/study_rooms.py | 6 +++--- app/crud/study_rooms.py | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 8dbc324..a4cf085 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -179,10 +179,10 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): } ) def get_study_rooms( - skip: int, - limit: int, + skip: Optional[int] = None, + limit: Optional[int] = None, owner_id: Optional[int] = None, - option: str = 'created_at', + option: Optional[str] = 'created_at', db: Session = Depends(get_db) ): try: diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 0bea803..3e2f1a8 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -55,7 +55,14 @@ def get(self, db: Session, room_id: UUID): raise NoSuchElementException(message='not found') - def get_multi(self, db: Session, skip: int, limit: int, owner_id: Optional[int], option: str): + def get_multi( + self, + db: Session, + skip: Optional[int], + limit: Optional[int], + owner_id: Optional[int], + option: Optional[str] + ): query = db.query(self.model) if owner_id: query = query.filter(self.model.owner_id == owner_id) From 131f7df3dc0f6098da06bb09e0081aa97884a135 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 26 May 2021 19:33:05 +0900 Subject: [PATCH 100/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 3e2f1a8..e2b43d2 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -67,9 +67,9 @@ def get_multi( if owner_id: query = query.filter(self.model.owner_id == owner_id) - data = query.filter(( + data = query.filter( self.model.current_join_counts < MAX_CAPACITY - )).with_entities( + ).with_entities( self.model.id, self.model.title, self.model.style, From dafaf7242cc497918f678b0afa038636594a3a3e Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 27 May 2021 22:05:28 +0900 Subject: [PATCH 101/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20CORS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 1 + app/core/config.py | 6 ++++-- app/main.py | 17 +++++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/core/__init__.py b/app/core/__init__.py index 7178a80..6b39a05 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -1,6 +1,7 @@ from app.core.config import ( common_settings, develop_settings, + deploy_settings, study_rooms_settings, user_settings, socket_settings, diff --git a/app/core/config.py b/app/core/config.py index 3f048cc..f4dbd4b 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -16,19 +16,21 @@ class Config: class DevelopSettings(BaseSettings): ALLOW_ORIGIN: list = ['*'] - ALLOW_CREDENTIAL: bool = True + ALLOW_CREDENTIAL: bool = False ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] ALLOW_HOST: list = ['*'] + ALLOW_EXPOSE_HEADERS: list = ['*'] class DeploySettings(BaseSettings): # TODO: 차후 배포 전 상세 설정 필요 - ALLOW_ORIGIN: list = ['*'] + ALLOW_ORIGIN: list = ['https://studeep.com'] ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] ALLOW_HOST: list = ['*'] + ALLOW_EXPOSE_HEADERS: list = ['*'] class UserSettings(BaseSettings): diff --git a/app/main.py b/app/main.py index 86ea377..7eca375 100644 --- a/app/main.py +++ b/app/main.py @@ -6,7 +6,11 @@ from fastapi.middleware.trustedhost import TrustedHostMiddleware from app.api import api_router -from app.core import common_settings, develop_settings +from app.core import ( + common_settings, + develop_settings, + deploy_settings + ) from app.service import sio @@ -15,14 +19,15 @@ server.add_middleware( CORSMiddleware, - allow_origins = develop_settings.ALLOW_ORIGIN, - allow_credentials = develop_settings.ALLOW_CREDENTIAL, - allow_methods = develop_settings.ALLOW_METHODS, - allow_headers = develop_settings.ALLOW_HEADERS + allow_origins = deploy_settings.ALLOW_ORIGIN, + allow_credentials = deploy_settings.ALLOW_CREDENTIAL, + allow_methods = deploy_settings.ALLOW_METHODS, + allow_headers = deploy_settings.ALLOW_HEADERS, + expose_headers = deploy_settings.ALLOW_EXPOSE_HEADERS ) server.add_middleware( TrustedHostMiddleware, - allowed_hosts = develop_settings.ALLOW_HOST, + allowed_hosts = deploy_settings.ALLOW_HOST, ) server.add_websocket_route("/socket.io/", sio_app) server.include_router(api_router, prefix=common_settings.COMMON_API) From 1baa47ed6038360fd5fcb4086da7d50ffa07a50a Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 27 May 2021 22:08:48 +0900 Subject: [PATCH 102/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20host,=20expose=5F?= =?UTF-8?q?headers=20=EA=B5=AC=EC=B2=B4=EC=A0=81=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index f4dbd4b..a4b4a29 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -29,8 +29,8 @@ class DeploySettings(BaseSettings): ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] - ALLOW_HOST: list = ['*'] - ALLOW_EXPOSE_HEADERS: list = ['*'] + ALLOW_HOST: list = ['https://studeep.com', 'localhost'] + ALLOW_EXPOSE_HEADERS: list = ['Authorization', 'authorization'] class UserSettings(BaseSettings): From 1d3970147506a4c5a9ef016b5af1b73d860e214c Mon Sep 17 00:00:00 2001 From: limm_jk Date: Thu, 27 May 2021 23:27:16 +0900 Subject: [PATCH 103/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=9D=B8=EC=A6=9D=EC=A0=95=EB=B3=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/core/config.py b/app/core/config.py index a4b4a29..ef629be 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -29,7 +29,7 @@ class DeploySettings(BaseSettings): ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] - ALLOW_HOST: list = ['https://studeep.com', 'localhost'] + ALLOW_HOST: list = ['*.studeep.com', 'localhost'] ALLOW_EXPOSE_HEADERS: list = ['Authorization', 'authorization'] From 9735ccb34c751e235a7d41a6fa5922f6533b8818 Mon Sep 17 00:00:00 2001 From: limm_jk Date: Thu, 27 May 2021 23:46:38 +0900 Subject: [PATCH 104/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20=EC=A0=95=EB=B3=B4=20=EB=B0=8F=20SSL=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 11 ++++++++--- app/main.py | 2 +- app/schemas/users/crud.py | 12 +----------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index ef629be..216f6fb 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -15,8 +15,13 @@ class Config: class DevelopSettings(BaseSettings): - ALLOW_ORIGIN: list = ['*'] - ALLOW_CREDENTIAL: bool = False + ALLOW_ORIGIN: list = ['https://www.studeep.com/', + 'https://api.studeep.com/', + 'https://studeep.com/', + 'http://localhost/', + 'http://localhost:3000/', + 'http://localhost:8000/'] + ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] ALLOW_HOST: list = ['*'] @@ -25,7 +30,7 @@ class DevelopSettings(BaseSettings): class DeploySettings(BaseSettings): # TODO: 차후 배포 전 상세 설정 필요 - ALLOW_ORIGIN: list = ['https://studeep.com'] + ALLOW_ORIGIN: list = ['*'] ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] diff --git a/app/main.py b/app/main.py index 7eca375..c5ded01 100644 --- a/app/main.py +++ b/app/main.py @@ -34,4 +34,4 @@ if __name__ == "__main__": - uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True) + uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True, ssl_keyfile='/etc/letsencrypt/live/api.studeep.com/privkey.pem', ssl_certfile='/etc/letsencrypt/live/api.studeep.com/fullchain.pem') diff --git a/app/schemas/users/crud.py b/app/schemas/users/crud.py index 7d6b539..488c57c 100644 --- a/app/schemas/users/crud.py +++ b/app/schemas/users/crud.py @@ -17,22 +17,12 @@ class UserBase(BaseModel): class UserCreate(UserBase): provider: str nickname: str - goal: dict class Config: schema_extra = { 'example': { 'provider': 'google', - 'nickname': 'Studeep_User', - 'goal': { - 'MON': 2, - 'TUE': 2, - 'WED': 2, - 'THU': 2, - 'FRI': 2, - 'SAT': 2, - 'SUN': 2 - } + 'nickname': 'Studeep_User' } } From 4adeae8d485850ba0f4f1fae0206aadf1bb31b36 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 18:05:03 +0900 Subject: [PATCH 105/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=EB=A0=88=ED=8F=AC=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=8A=A4=ED=82=A4=EB=A7=88=20=EB=B0=8F=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=84=B0=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/__init__.py | 32 ++++++++--- app/api/my_studies.py | 21 ++++++++ app/api/reports.py | 22 ++++++++ app/core/__init__.py | 2 + app/core/config.py | 10 ++++ app/crud/__init__.py | 6 ++- app/crud/disturbances.py | 48 +++++++++++++++++ app/crud/my_studies.py | 76 ++++++++++++++++++++++++++ app/crud/reports.py | 80 ++++++++++++++++++++++++++++ app/crud/study_rooms.py | 3 ++ app/schemas/__init__.py | 66 +++++++++++++---------- app/schemas/disturbances/__init__.py | 1 + app/schemas/disturbances/crud.py | 19 +++++++ app/schemas/disturbances/handling.py | 0 app/schemas/disturbances/success.py | 0 app/schemas/my_studies/__init__.py | 1 + app/schemas/my_studies/crud.py | 24 +++++++++ app/schemas/my_studies/handling.py | 0 app/schemas/my_studies/success.py | 0 app/schemas/reports/__init__.py | 1 + app/schemas/reports/crud.py | 15 ++++++ app/schemas/reports/handling.py | 0 app/schemas/reports/success.py | 0 app/service/__init__.py | 2 +- app/service/sockets.py | 74 ++++++++++++++++++++----- 25 files changed, 453 insertions(+), 50 deletions(-) create mode 100644 app/api/my_studies.py create mode 100644 app/api/reports.py create mode 100644 app/crud/disturbances.py create mode 100644 app/crud/my_studies.py create mode 100644 app/crud/reports.py create mode 100644 app/schemas/disturbances/__init__.py create mode 100644 app/schemas/disturbances/crud.py create mode 100644 app/schemas/disturbances/handling.py create mode 100644 app/schemas/disturbances/success.py create mode 100644 app/schemas/my_studies/__init__.py create mode 100644 app/schemas/my_studies/crud.py create mode 100644 app/schemas/my_studies/handling.py create mode 100644 app/schemas/my_studies/success.py create mode 100644 app/schemas/reports/__init__.py create mode 100644 app/schemas/reports/crud.py create mode 100644 app/schemas/reports/handling.py create mode 100644 app/schemas/reports/success.py diff --git a/app/api/__init__.py b/app/api/__init__.py index 156f7a0..0f85cbc 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -1,7 +1,12 @@ from fastapi import APIRouter, Depends -from app.api import users, study_rooms -from app.core import study_rooms_settings, user_settings +from app.api import users, study_rooms, my_studies, reports +from app.core import ( + study_rooms_settings, + user_settings, + my_studies_settings, + report_settings + ) from app.service import auth_token @@ -11,10 +16,21 @@ prefix=user_settings.API_USER, tags=['users'] ) -# TODO: 의존성 추가 api_router.include_router( - study_rooms.router, - prefix=study_rooms_settings.API_STUDY_ROOM, - # dependencies=[Depends(auth_token),], - tags=['study_rooms'] -) \ No newline at end of file + router = study_rooms.router, + prefix = study_rooms_settings.API_STUDY_ROOM, + # dependencies = [ Depends(auth_token) ], + tags = [ 'study_rooms' ] +) +api_router.include_router( + router = my_studies.router, + prefix = my_studies_settings.API_MY_STUDY, + # dependencies = [ Depends(auth_token) ], + tags = [ 'my_studies' ] +) +api_router.include_router( + router = reports.router, + prefix = report_settings.API_REPORT, + # dependencies = [ Depends(auth_token) ], + tags = [ 'reports' ] +) diff --git a/app/api/my_studies.py b/app/api/my_studies.py new file mode 100644 index 0000000..2240d78 --- /dev/null +++ b/app/api/my_studies.py @@ -0,0 +1,21 @@ +import traceback + +from fastapi import ( + APIRouter, + Depends, + status + ) +from fastapi.responses import JSONResponse +from sqlalchemy.orm.session import Session + +from app.api.deps import get_db +from app.crud import my_studies + + + +router = APIRouter() + + +@router.get() +def get_my_studies(): + pass \ No newline at end of file diff --git a/app/api/reports.py b/app/api/reports.py new file mode 100644 index 0000000..2b3eaf4 --- /dev/null +++ b/app/api/reports.py @@ -0,0 +1,22 @@ +import traceback + +from fastapi import ( + APIRouter, + Depends, + status + ) +from fastapi.responses import JSONResponse +from sqlalchemy.orm.session import Session + +from app.api.deps import get_db +from app.crud import reports + + +router = APIRouter() + + +@router.get( + '' +) +def get_report(): + pass \ No newline at end of file diff --git a/app/core/__init__.py b/app/core/__init__.py index 6b39a05..f813423 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -4,6 +4,8 @@ deploy_settings, study_rooms_settings, user_settings, + my_studies_settings, + report_settings, socket_settings, time_settings ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index 216f6fb..cb7c607 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -51,6 +51,14 @@ class StudyRoomSettings(BaseSettings): MAX_CAPACITY: int = 5 +class MyStudySettings(BaseSettings): + API_MY_STUDY: str = '/my-studies' + + +class ReportSettings(BaseSettings): + API_REPORT: str = '/reports' + + class SocketSettings(BaseSettings): NAMESPACE_URL: str = '/study' @@ -64,5 +72,7 @@ class TimeSettings(BaseSettings): deploy_settings = DeploySettings() user_settings = UserSettings() study_rooms_settings = StudyRoomSettings() +my_studies_settings = MyStudySettings() +report_settings = ReportSettings() socket_settings = SocketSettings() time_settings = TimeSettings() diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 5d95ee9..26917f4 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,3 +1,5 @@ from app.crud.users import users -from app.crud.study_rooms import study_rooms - +from app.crud.study_rooms import study_rooms +from app.crud.reports import reports +from app.crud.my_studies import my_studies +from app.crud.disturbances import disturbances \ No newline at end of file diff --git a/app/crud/disturbances.py b/app/crud/disturbances.py new file mode 100644 index 0000000..0feda09 --- /dev/null +++ b/app/crud/disturbances.py @@ -0,0 +1,48 @@ +from sqlalchemy import and_ +from sqlalchemy.orm import Session +from sqlalchemy.sql.functions import count + +from app.crud.base import CRUDBase +from app.models import Disturbances +from app.schemas import DisturbanceCreate, DisturbanceUpdate + +class CRUDDisturbance(CRUDBase[Disturbances, DisturbanceCreate, DisturbanceUpdate]): + def update_or_create( + self, + db: Session, + type: str, + time: int, + my_study_id: int, + report_id: int + ): + try: + instance = db.query(self.model).filter(and_( + self.model.type == type, + self.model.my_study_id == my_study_id, + self.model.report_id == report_id + )).first() + + if instance: + instance.count += 1 + instance.time += time + + else: + instance = self.model( + type = type, + count = 1, + time = time, + my_study_id = my_study_id, + report_id = report_id + ) + db.add(instance) + + db.commit() + + except: + raise Exception + + finally: + db.close() + + +disturbances = CRUDDisturbance(Disturbances) \ No newline at end of file diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py new file mode 100644 index 0000000..8eb7082 --- /dev/null +++ b/app/crud/my_studies.py @@ -0,0 +1,76 @@ +from uuid import UUID +from datetime import date, datetime +from fastapi.encoders import jsonable_encoder +from sqlalchemy import and_ +from sqlalchemy.orm import Session + +from app.crud.base import CRUDBase +from app.models import MyStudies, Reports, Disturbances +from app.schemas import MyStudiesCreate, MyStudiesUpdate + + +class CRUDMyStudy(CRUDBase[MyStudies, MyStudiesCreate, MyStudiesUpdate]): + def get(self, db: Session, date: date, user_id: int): + try: + data = db.query(self.model).filter(and_( + Reports.date == date, + Reports.user_id == user_id + )).outerjoin( + Reports, + Reports.id == self.model.report_id + ).outerjoin( + Disturbances, + Disturbances.report_id == self.model.id + ).with_entities( + + ) + + if data: + return jsonable_encoder(data) + else: + # Not Found + pass + + except: + pass + + + def create(self, db: Session, room_id: str, started_at: datetime, report_id: int): + try: + instance = self.model( + started_at = started_at, + study_room_id = UUID(room_id), + report_id = report_id + ) + db.add(instance) + db.commit() + db.refresh(instance) + return jsonable_encoder(instance) + + except: + raise Exception + + finally: + db.close() + + + def update(self, db: Session, ended_at: datetime, total_time: int, id: int): + try: + instance = db.query(self.model).filter( + self.model.id == id + ).update({'ended_at': ended_at, 'total_time': total_time}) + + if instance: + db.commit() + else: + # Not Found + pass + + except: + raise Exception + + finally: + db.close() + + +my_studies = CRUDMyStudy(MyStudies) \ No newline at end of file diff --git a/app/crud/reports.py b/app/crud/reports.py new file mode 100644 index 0000000..e29ae7a --- /dev/null +++ b/app/crud/reports.py @@ -0,0 +1,80 @@ +from datetime import date, datetime +from sqlalchemy import and_ +from sqlalchemy.orm import Session +from fastapi.encoders import jsonable_encoder + +from app.models import Reports, Disturbances +from app.schemas import ReportsCreate, ReportsUpdate +from app.crud.base import CRUDBase + + +class CRUDReport(CRUDBase[Reports, ReportsCreate, ReportsUpdate]): + def get(self, db: Session, user_id: str, date: date): + try: + data = db.query(self.model).filter(and_( + self.model.user_id == user_id, + self.model.date == date + )).outerjoin( + Disturbances, + Disturbances.report_id == self.model.id + ).with_entities( + + ).first() + + if data: + return jsonable_encoder(data) + else: + # Not Found + pass + + except: + raise Exception + + + def get_or_create(self, db: Session, today: date, user_id: int): + try: + if (today.hour >= 0) and (today.hour < 5): + date = datetime(today.year, today.month, today.day - 1) + else: + date = date = datetime(today.year, today.month, today.day) + + instance = db.query(self.model).filter(and_( + self.model.user_id == user_id, + self.model.date == date + )).first() + + if instance: + return jsonable_encoder(instance) + else: + instance = self.model(user_id = user_id, date = date) + db.add(instance) + db.commit() + db.refresh(instance) + return jsonable_encoder(instance) + + except: + raise Exception + + finally: + db.close() + + + def update(self, db: Session, id: int, total_time: int): + try: + instance = db.query(self.model).filter( + self.model.id == id + ).update({'total_time': self.model.total_time + total_time}) + if instance: + db.commit() + else: + # Not Found + pass + + except: + raise Exception + + finally: + db.close() + + +reports = CRUDReport(Reports) \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index e2b43d2..78c73b1 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -158,6 +158,9 @@ def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): except ValueError: raise NoSuchElementException(message='not found') + finally: + db.close() + def leave(self, db: Session, room_id: str): try: diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 75cee53..2c5532f 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,27 +1,39 @@ -from app.schemas.responses import ( - SuccessResponseBase, - ErrorResponseBase, - MethodNotAllowedHandling - ) -from app.schemas.users import ( - NotFoundUserHandling, - UnauthorizedHandler, - ForbiddenHandler, - UserDataResponse, - UserBase, - UserCreate, - UserUpdate - ) -from app.schemas.study_rooms import ( - StudyRoomsCreate, - StudyRoomsUpdate, - StudyRoomJoin, - GetStudyRoomResponse, - GetStudyRoomsResponse, - NotFoundStudyRoomHandling, - PasswordNeedyStudyRoomHandling, - BodyNeedyStudyRoomHandling, - QueryNeedyStudyRoomHandling, - NoEmptyRoomHandling, - ForbiddenUserHandling - ) +from app.schemas.responses import ( + SuccessResponseBase, + ErrorResponseBase, + MethodNotAllowedHandling + ) +from app.schemas.users import ( + NotFoundUserHandling, + UnauthorizedHandler, + ForbiddenHandler, + UserDataResponse, + UserBase, + UserCreate, + UserUpdate + ) +from app.schemas.study_rooms import ( + StudyRoomsCreate, + StudyRoomsUpdate, + StudyRoomJoin, + GetStudyRoomResponse, + GetStudyRoomsResponse, + NotFoundStudyRoomHandling, + PasswordNeedyStudyRoomHandling, + BodyNeedyStudyRoomHandling, + QueryNeedyStudyRoomHandling, + NoEmptyRoomHandling, + ForbiddenUserHandling + ) +from app.schemas.reports import ( + ReportsCreate, + ReportsUpdate + ) +from app.schemas.my_studies import ( + MyStudiesCreate, + MyStudiesUpdate + ) +from app.schemas.disturbances import ( + DisturbanceCreate, + DisturbanceUpdate + ) \ No newline at end of file diff --git a/app/schemas/disturbances/__init__.py b/app/schemas/disturbances/__init__.py new file mode 100644 index 0000000..6351d86 --- /dev/null +++ b/app/schemas/disturbances/__init__.py @@ -0,0 +1 @@ +from app.schemas.disturbances.crud import DisturbanceCreate, DisturbanceUpdate \ No newline at end of file diff --git a/app/schemas/disturbances/crud.py b/app/schemas/disturbances/crud.py new file mode 100644 index 0000000..af1540c --- /dev/null +++ b/app/schemas/disturbances/crud.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel + +from app.models import Type + + +class DisturbanceBase(BaseModel): + pass + + +class DisturbanceCreate(DisturbanceBase): + type: Type + count: int + time: int + my_study_id: int + report_id: int + + +class DisturbanceUpdate(DisturbanceBase): + pass \ No newline at end of file diff --git a/app/schemas/disturbances/handling.py b/app/schemas/disturbances/handling.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schemas/disturbances/success.py b/app/schemas/disturbances/success.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schemas/my_studies/__init__.py b/app/schemas/my_studies/__init__.py new file mode 100644 index 0000000..97d244c --- /dev/null +++ b/app/schemas/my_studies/__init__.py @@ -0,0 +1 @@ +from app.schemas.my_studies.crud import MyStudiesCreate, MyStudiesUpdate \ No newline at end of file diff --git a/app/schemas/my_studies/crud.py b/app/schemas/my_studies/crud.py new file mode 100644 index 0000000..17a39be --- /dev/null +++ b/app/schemas/my_studies/crud.py @@ -0,0 +1,24 @@ +from uuid import UUID +from datetime import date, datetime +from typing import Optional +from pydantic import BaseModel + + +class MyStudiesBase(BaseModel): + pass + + +class MyStudiesCreate(MyStudiesBase): + date: date + report_id: int + study_room_id: UUID + + class config: + schema_extra = { + + } + + +class MyStudiesUpdate(MyStudiesBase): + total_time: int + ended_at: datetime \ No newline at end of file diff --git a/app/schemas/my_studies/handling.py b/app/schemas/my_studies/handling.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schemas/my_studies/success.py b/app/schemas/my_studies/success.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schemas/reports/__init__.py b/app/schemas/reports/__init__.py new file mode 100644 index 0000000..d439574 --- /dev/null +++ b/app/schemas/reports/__init__.py @@ -0,0 +1 @@ +from app.schemas.reports.crud import ReportsCreate, ReportsUpdate \ No newline at end of file diff --git a/app/schemas/reports/crud.py b/app/schemas/reports/crud.py new file mode 100644 index 0000000..3294809 --- /dev/null +++ b/app/schemas/reports/crud.py @@ -0,0 +1,15 @@ +from datetime import date +from pydantic import BaseModel + + +class ReportsBase(BaseModel): + date: date + user_id: int + + +class ReportsCreate(ReportsBase): + pass + + +class ReportsUpdate(ReportsBase): + pass \ No newline at end of file diff --git a/app/schemas/reports/handling.py b/app/schemas/reports/handling.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schemas/reports/success.py b/app/schemas/reports/success.py new file mode 100644 index 0000000..e69de29 diff --git a/app/service/__init__.py b/app/service/__init__.py index 62e6530..7075dd1 100644 --- a/app/service/__init__.py +++ b/app/service/__init__.py @@ -1,2 +1,2 @@ from app.service.auth import auth_token -from app.service.sockets import sio +from app.service.sockets import sio \ No newline at end of file diff --git a/app/service/sockets.py b/app/service/sockets.py index e4e6f07..f0755a4 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,10 +1,13 @@ import socketio +import traceback +from datetime import datetime from sqlalchemy.orm.session import Session from app.core import socket_settings -from app.crud import study_rooms +from app.crud import study_rooms, reports, my_studies from app.database import SessionLocal +from app.core import time_settings db = SessionLocal() @@ -13,18 +16,43 @@ clients = dict() - @sio.event(namespace=namespace_url) async def connect(sid, environ, auth): # TODO: Redis 사용자 정보 추가 - clients[sid] = auth['email'] - + try: + today = datetime.utcnow() + time_settings.KST + instance = reports.get_or_create(db=db, today=today, user_id=1) + clients[sid] = { + 'user_id': auth['user_id'], + 'report_id': instance['id'], + 'my_study_id': '' + } + + except Exception as error: + print(traceback.print_exc()) @sio.event(namespace=namespace_url) async def joinRoom(sid, room_id): # TODO: Redis 사용자가 이용중인 스터디룸 정보 추가 - sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) - await sio.emit('response', {'message': 'room joined'}, room=room_id, namespace=namespace_url) + try: + sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) + instance = my_studies.create( + db = db, + room_id = room_id, + started_at = time_settings.KOR_NOW, + report_id = clients[sid]['report_id'] + ) + clients[sid]['my_study_id'] = instance['id'] + await sio.emit( + 'response', + {'message': 'room joined'}, + room = room_id, + namespace = namespace_url + ) + + except Exception as error: + print(traceback.print_exc()) + @sio.event(namespace=namespace_url) @@ -32,16 +60,38 @@ async def leaveRoom(sid, room_id, db: Session = db): try: # TODO: 축적된 학습 데이터 Redis > PostgreSQL 이동 필요 message = study_rooms.leave(db, room_id=room_id) - await sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) + sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) + my_studies.update( + db = db, + ended_at = time_settings.KOR_NOW, + disturbance = '', + id = clients[sid]['my_study_id'] + ) + reports.update() clients.pop(sid) - await sio.emit('response', {'message': message}, room=room_id, namespace=namespace_url) + await sio.emit( + 'response', + {'message': message}, + room = room_id, + namespace = namespace_url + ) except Exception as error: - await sio.emit('response', {'message': error}, room=room_id, namespace=namespace_url) + print(traceback.print_exc()) + await sio.emit( + 'response', + {'message': error}, + room = room_id, + namespace = namespace_url + ) + @sio.event(namespace=namespace_url) -async def status(sid, data): - # TODO: Redis 사용자의 학습 상태 정보 추가 +async def status(sid, disturbance): + # TODO + # - Redis 사용자의 학습 상태 정보 추가 + # - 넘어 온 상태에 따른 emit > 어떤 사용자가 어떤 상태인지 보내줄 것 + # print(conn.lrange(clients[sid], 0, -1).decode()) # await sio.emit('response', {'message': 'success'}, room=room_id, namespace=namespace_url) - pass \ No newline at end of file + pass From a2e60efa06da8a7d2fdce5883bb51240244bfbdb Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 27 May 2021 19:07:35 +0900 Subject: [PATCH 106/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=EB=A0=88=ED=8F=AC=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EB=B0=8F=20?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/my_studies.py | 60 ++++++++++++++-- app/api/reports.py | 58 ++++++++++++++- app/crud/__init__.py | 5 +- app/crud/disturbances.py | 13 +++- app/crud/my_studies.py | 82 +++++++++++++-------- app/crud/reports.py | 63 ++++++++++------ app/crud/study_rooms.py | 4 +- app/models/my_studies.py | 2 +- app/models/reports.py | 4 +- app/schemas/__init__.py | 10 ++- app/schemas/disturbances/crud.py | 4 +- app/schemas/my_studies/__init__.py | 4 +- app/schemas/my_studies/handling.py | 19 +++++ app/schemas/my_studies/success.py | 51 +++++++++++++ app/schemas/reports/__init__.py | 4 +- app/schemas/reports/handling.py | 19 +++++ app/schemas/reports/success.py | 35 +++++++++ app/service/sockets.py | 111 +++++++++++++++++++++-------- 18 files changed, 446 insertions(+), 102 deletions(-) diff --git a/app/api/my_studies.py b/app/api/my_studies.py index 2240d78..45df8ca 100644 --- a/app/api/my_studies.py +++ b/app/api/my_studies.py @@ -10,12 +10,64 @@ from app.api.deps import get_db from app.crud import my_studies - +from app.schemas import ( + ErrorResponseBase, + GetMyStudiesResponse, + NotFoundMyStudiesHandling + ) +from app.errors import ( + get_detail, + NoSuchElementException + ) router = APIRouter() -@router.get() -def get_my_studies(): - pass \ No newline at end of file +@router.get( + '', + responses = { + 200: { + "model": GetMyStudiesResponse, + "description": "마이스터디 조회 성공" + }, + 404: { + "model": NotFoundMyStudiesHandling, + "description": "조회한 마이 스터디가 없는 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def get_my_studies(date: str, user_id: int, db: Session = Depends(get_db)): + try: + data = my_studies.get(db, date, user_id) + return JSONResponse( + status_code = status.HTTP_200_OK, + content = {'data': data} + ) + + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail( + param = 'database', + field = 'my studies', + message = message, + err = 'database' + ) + return JSONResponse( + status_code = status.HTTP_404_NOT_FOUND, + content = {'detail': detail} + ) + + except Exception as error: + print(traceback.print_exc()) + return JSONResponse( + status_code = status.HTTP_500_INTERNAL_SERVER_ERROR, + content = {'detail': f'server error: {error}'} + ) + + finally: + db.close() \ No newline at end of file diff --git a/app/api/reports.py b/app/api/reports.py index 2b3eaf4..947871f 100644 --- a/app/api/reports.py +++ b/app/api/reports.py @@ -10,13 +10,65 @@ from app.api.deps import get_db from app.crud import reports +from app.schemas import ( + ErrorResponseBase, + GetReportReponse, + NotFoundReportHandling + ) +from app.errors import ( + get_detail, + NoSuchElementException + ) router = APIRouter() @router.get( - '' + '', + responses = { + 200: { + "model": GetReportReponse, + "description": "레포트 조회 성공" + }, + 404: { + "model": NotFoundReportHandling, + "description": "조회한 학습 레포트가 없는 경우" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } ) -def get_report(): - pass \ No newline at end of file +def get_report(date: str, user_id: str, db: Session=Depends(get_db)): + try: + data = reports.get(db, user_id, date) + return JSONResponse( + status_code = status.HTTP_200_OK, + content = {'data': data} + ) + + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail( + param = 'database', + field = 'report', + message = message, + err = 'database' + ) + return JSONResponse( + status_code = status.HTTP_404_NOT_FOUND, + content = {'detail': detail} + ) + + except Exception as error: + print(traceback.print_exc()) + return JSONResponse( + status_code = status.HTTP_500_INTERNAL_SERVER_ERROR, + content = {'detail': f'server error: {error}'} + ) + + finally: + db.close() + diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 26917f4..cc39567 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,5 +1,6 @@ from app.crud.users import users from app.crud.study_rooms import study_rooms -from app.crud.reports import reports +from app.crud.disturbances import disturbances from app.crud.my_studies import my_studies -from app.crud.disturbances import disturbances \ No newline at end of file +from app.crud.reports import reports + diff --git a/app/crud/disturbances.py b/app/crud/disturbances.py index 0feda09..e46e6ef 100644 --- a/app/crud/disturbances.py +++ b/app/crud/disturbances.py @@ -1,12 +1,23 @@ from sqlalchemy import and_ from sqlalchemy.orm import Session -from sqlalchemy.sql.functions import count from app.crud.base import CRUDBase from app.models import Disturbances from app.schemas import DisturbanceCreate, DisturbanceUpdate class CRUDDisturbance(CRUDBase[Disturbances, DisturbanceCreate, DisturbanceUpdate]): + def create(self, db: Session, disturbances: list): + try: + db.bulk_insert_mappings(self.model, disturbances) + db.commit() + + except: + raise Exception + + finally: + db.close() + + def update_or_create( self, db: Session, diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index 8eb7082..f784cab 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -1,46 +1,62 @@ from uuid import UUID -from datetime import date, datetime +from datetime import datetime from fastapi.encoders import jsonable_encoder from sqlalchemy import and_ from sqlalchemy.orm import Session from app.crud.base import CRUDBase -from app.models import MyStudies, Reports, Disturbances +from app.models import MyStudies, Reports, Disturbances, StudyRooms from app.schemas import MyStudiesCreate, MyStudiesUpdate +from app.errors import NoSuchElementException +from app.core import time_settings class CRUDMyStudy(CRUDBase[MyStudies, MyStudiesCreate, MyStudiesUpdate]): - def get(self, db: Session, date: date, user_id: int): - try: - data = db.query(self.model).filter(and_( - Reports.date == date, - Reports.user_id == user_id - )).outerjoin( - Reports, - Reports.id == self.model.report_id - ).outerjoin( - Disturbances, - Disturbances.report_id == self.model.id - ).with_entities( - - ) + def get(self, db: Session, date: str, user_id: int): + # TODO: 3차 Dev Camp 이후 구현 사항. 관련 쿼리 수정 필요. + date = datetime.strptime(date, '%Y-%m-%d') + instance = db.query( + self.model + ).filter(and_( + Reports.date == date, + Reports.user_id == user_id + )).outerjoin( + StudyRooms, + StudyRooms.id == self.model.study_room_id + ).with_entities( + self.model.id, + self.model.started_at, + self.model.ended_at, + self.model.total_time, + self.model.star_count, + self.model.study_room_id, + StudyRooms.title, + ).all() - if data: - return jsonable_encoder(data) - else: - # Not Found - pass - - except: - pass + data = jsonable_encoder(instance) + if data: + for my_study in data: + my_study['disturbances'] = jsonable_encoder( + db.query(Disturbances).filter( + Disturbances.my_study_id == my_study['id'] + ).with_entities( + Disturbances.id, + Disturbances.type, + Disturbances.count, + Disturbances.time, + ).all() + ) + return jsonable_encoder(data) + else: + raise NoSuchElementException(message='not found') - def create(self, db: Session, room_id: str, started_at: datetime, report_id: int): + def create(self, db: Session, room_id: str, report_id: int): try: instance = self.model( - started_at = started_at, study_room_id = UUID(room_id), - report_id = report_id + report_id = report_id, + started_at = datetime.utcnow() + time_settings.KST ) db.add(instance) db.commit() @@ -54,14 +70,20 @@ def create(self, db: Session, room_id: str, started_at: datetime, report_id: int db.close() - def update(self, db: Session, ended_at: datetime, total_time: int, id: int): + def update(self, db: Session, id: int): try: instance = db.query(self.model).filter( self.model.id == id - ).update({'ended_at': ended_at, 'total_time': total_time}) - + ).first() + if instance: + instance.ended_at = datetime.utcnow() + time_settings.KST + instance.total_time = ( + instance.ended_at - instance.started_at + ).seconds db.commit() + db.refresh(instance) + return jsonable_encoder(instance) else: # Not Found pass diff --git a/app/crud/reports.py b/app/crud/reports.py index e29ae7a..702a408 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -1,38 +1,55 @@ -from datetime import date, datetime -from sqlalchemy import and_ +from datetime import datetime +from sqlalchemy import and_, func from sqlalchemy.orm import Session from fastapi.encoders import jsonable_encoder from app.models import Reports, Disturbances from app.schemas import ReportsCreate, ReportsUpdate from app.crud.base import CRUDBase +from app.errors import NoSuchElementException +from app.core import time_settings class CRUDReport(CRUDBase[Reports, ReportsCreate, ReportsUpdate]): - def get(self, db: Session, user_id: str, date: date): - try: - data = db.query(self.model).filter(and_( - self.model.user_id == user_id, - self.model.date == date - )).outerjoin( - Disturbances, - Disturbances.report_id == self.model.id + def get(self, db: Session, user_id: str, date: str): + date = datetime.strptime(date, '%Y-%m-%d') + instance = db.query( + self.model, + ).filter(and_( + self.model.user_id == user_id, + self.model.date == date + )).outerjoin( + Disturbances, + Disturbances.report_id == self.model.id + ).with_entities( + self.model.id, + self.model.date, + self.model.achievement, + self.model.concentration, + self.model.total_time, + self.model.total_star_count, + func.count(Disturbances.count).label('total_disturbance_counts') + ).group_by(self.model.id).first() + + if instance: + report = jsonable_encoder(instance) + disturbances = db.query(Disturbances).filter( + Disturbances.report_id == report['id'] ).with_entities( + Disturbances.type, + func.count(Disturbances.count).label('total_count'), + func.sum(Disturbances.time).label('total_time') + ).group_by(Disturbances.type).all() - ).first() + report['disturbances'] = jsonable_encoder(disturbances) + return report + else: + raise NoSuchElementException(message='not found') - if data: - return jsonable_encoder(data) - else: - # Not Found - pass - except: - raise Exception - - - def get_or_create(self, db: Session, today: date, user_id: int): + def get_or_create(self, db: Session, user_id: int): try: + today = datetime.utcnow() + time_settings.KST if (today.hour >= 0) and (today.hour < 5): date = datetime(today.year, today.month, today.day - 1) else: @@ -63,8 +80,10 @@ def update(self, db: Session, id: int, total_time: int): try: instance = db.query(self.model).filter( self.model.id == id - ).update({'total_time': self.model.total_time + total_time}) + ).first() + if instance: + instance.total_time += total_time db.commit() else: # Not Found diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 78c73b1..92a3f3c 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -1,3 +1,4 @@ +from datetime import datetime from uuid import UUID from typing import Union, Optional from datetime import datetime @@ -168,11 +169,10 @@ def leave(self, db: Session, room_id: str): {'current_join_counts': self.model.current_join_counts - 1} ) db.commit() - return 'room leaved' except Exception as error: # TODO: 더 구체적인 에러 핸들링 필요 ex. Positive Integer(MIN_CAPACITY) - return error + raise Exception finally: db.close() diff --git a/app/models/my_studies.py b/app/models/my_studies.py index b5869ab..d558f66 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -15,7 +15,7 @@ class MyStudies(Base): id = Column('my_study_id', Integer(), primary_key=True, autoincrement=True) started_at = Column('my_study_started_at', TIMESTAMP, nullable=False) ended_at = Column('my_study_ended_at', TIMESTAMP, nullable=True) - total_time = Column('my_study_total_time', Integer(), nullable=True) + total_time = Column('my_study_total_time', Integer(), default=0, nullable=True) star_count = Column('my_study_star_count', Integer(), nullable=True) report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete='CASCADE')) study_room_id = Column(UUID(as_uuid=True), ForeignKey('study_rooms.study_room_id', ondelete='CASCADE')) diff --git a/app/models/reports.py b/app/models/reports.py index f69b263..063be7c 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -15,8 +15,8 @@ class Reports(Base): date = Column('report_date', Date, nullable=False) achievement = Column('report_achievement', Integer(), nullable=True) concentration = Column('report_concentration', Integer(), nullable=True) - total_time = Column('report_total_time', Integer(), nullable=True) - total_star_count = Column('report_total_star_count', Integer(), nullable=True) + total_time = Column('report_total_time', Integer(), default=0, nullable=True) + total_star_count = Column('report_total_star_count', Integer(), default=0, nullable=True) user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) user = relation('User', back_populates='reports') my_studies = relation('MyStudies', back_populates='report') diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 2c5532f..0e53504 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -27,13 +27,17 @@ ) from app.schemas.reports import ( ReportsCreate, - ReportsUpdate + ReportsUpdate, + GetReportReponse, + NotFoundReportHandling ) from app.schemas.my_studies import ( MyStudiesCreate, - MyStudiesUpdate + MyStudiesUpdate, + GetMyStudiesResponse, + NotFoundMyStudiesHandling ) from app.schemas.disturbances import ( DisturbanceCreate, DisturbanceUpdate - ) \ No newline at end of file + ) diff --git a/app/schemas/disturbances/crud.py b/app/schemas/disturbances/crud.py index af1540c..aafa51d 100644 --- a/app/schemas/disturbances/crud.py +++ b/app/schemas/disturbances/crud.py @@ -1,6 +1,6 @@ from pydantic import BaseModel -from app.models import Type +from app.models import DisturbanceType class DisturbanceBase(BaseModel): @@ -8,7 +8,7 @@ class DisturbanceBase(BaseModel): class DisturbanceCreate(DisturbanceBase): - type: Type + type: DisturbanceType count: int time: int my_study_id: int diff --git a/app/schemas/my_studies/__init__.py b/app/schemas/my_studies/__init__.py index 97d244c..da4c115 100644 --- a/app/schemas/my_studies/__init__.py +++ b/app/schemas/my_studies/__init__.py @@ -1 +1,3 @@ -from app.schemas.my_studies.crud import MyStudiesCreate, MyStudiesUpdate \ No newline at end of file +from app.schemas.my_studies.crud import MyStudiesCreate, MyStudiesUpdate +from app.schemas.my_studies.success import GetMyStudiesResponse +from app.schemas.my_studies.handling import NotFoundMyStudiesHandling \ No newline at end of file diff --git a/app/schemas/my_studies/handling.py b/app/schemas/my_studies/handling.py index e69de29..bc2f2da 100644 --- a/app/schemas/my_studies/handling.py +++ b/app/schemas/my_studies/handling.py @@ -0,0 +1,19 @@ +from app.schemas.responses import ErrorResponseBase + + +class NotFoundMyStudiesHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "my studies" + ], + "msg": "not found", + "type": "database.missing" + } + ] + } + } diff --git a/app/schemas/my_studies/success.py b/app/schemas/my_studies/success.py index e69de29..80f3c26 100644 --- a/app/schemas/my_studies/success.py +++ b/app/schemas/my_studies/success.py @@ -0,0 +1,51 @@ +from app.schemas.responses import SuccessResponseBase + + +class GetMyStudiesResponse(SuccessResponseBase): + class Config: + schema_extra = { + "example": { + "data": [ + { + "id": 5, + "started_at": "2021-05-25T22:55:16.874569", + "ended_at": "2021-05-25T22:59:16.555907", + "total_time": 239, + "star_count": None, + "study_room_id": "7ce741ef-5f97-46ec-9cf6-6eb6b6a4ee9a", + "title": "스터디룸 생성 테스트", + "disturbances": [ + { + "id": 5, + "type": "smartphone", + "count": 1, + "time": 8 + }, + { + "id": 9, + "type": "sleep", + "count": 1, + "time": 5 + } + ] + }, + { + "id": 6, + "started_at": "2021-05-25T23:00:10.040419", + "ended_at": "2021-05-25T23:02:49.544101", + "total_time": 159, + "star_count": None, + "study_room_id": "7ce741ef-5f97-46ec-9cf6-6eb6b6a4ee9a", + "title": "스터디룸 생성 테스트", + "disturbances": [ + { + "id": 6, + "type": "await", + "count": 1, + "time": 20 + } + ] + } + ] + } + } \ No newline at end of file diff --git a/app/schemas/reports/__init__.py b/app/schemas/reports/__init__.py index d439574..59b6c99 100644 --- a/app/schemas/reports/__init__.py +++ b/app/schemas/reports/__init__.py @@ -1 +1,3 @@ -from app.schemas.reports.crud import ReportsCreate, ReportsUpdate \ No newline at end of file +from app.schemas.reports.crud import ReportsCreate, ReportsUpdate +from app.schemas.reports.success import GetReportReponse +from app.schemas.reports.handling import NotFoundReportHandling diff --git a/app/schemas/reports/handling.py b/app/schemas/reports/handling.py index e69de29..bba11ba 100644 --- a/app/schemas/reports/handling.py +++ b/app/schemas/reports/handling.py @@ -0,0 +1,19 @@ +from app.schemas.responses import ErrorResponseBase + + +class NotFoundReportHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "report" + ], + "msg": "not found", + "type": "database.missing" + } + ] + } + } diff --git a/app/schemas/reports/success.py b/app/schemas/reports/success.py index e69de29..c7640b8 100644 --- a/app/schemas/reports/success.py +++ b/app/schemas/reports/success.py @@ -0,0 +1,35 @@ +from app.schemas.responses import SuccessResponseBase + + +class GetReportReponse(SuccessResponseBase): + class Config: + schema_extra = { + "example": { + "data": { + "id": 4, + "date": "2021-05-25", + "achievement": None, + "concentration": None, + "total_time": 518, + "total_star_count": 0, + "total_disturbance_counts": 4, + "disturbances": [ + { + "type": "smartphone", + "total_count": 2, + "total_time": 20 + }, + { + "type": "await", + "total_count": 1, + "total_time": 20 + }, + { + "type": "sleep", + "total_count": 1, + "total_time": 5 + } + ] + } + } + } \ No newline at end of file diff --git a/app/service/sockets.py b/app/service/sockets.py index f0755a4..4899d1d 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,77 +1,117 @@ -import socketio import traceback +import socketio -from datetime import datetime from sqlalchemy.orm.session import Session from app.core import socket_settings -from app.crud import study_rooms, reports, my_studies +from app.crud import ( + study_rooms, + reports, + my_studies, + disturbances + ) from app.database import SessionLocal -from app.core import time_settings db = SessionLocal() -sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*', debug=True) +sio = socketio.AsyncServer( + async_mode = 'asgi', + cors_allowed_origins = '*', + debug = True +) namespace_url = socket_settings.NAMESPACE_URL clients = dict() @sio.event(namespace=namespace_url) async def connect(sid, environ, auth): - # TODO: Redis 사용자 정보 추가 try: - today = datetime.utcnow() + time_settings.KST - instance = reports.get_or_create(db=db, today=today, user_id=1) + instance = reports.get_or_create( + db = db, + user_id = auth['user_id'] + ) clients[sid] = { 'user_id': auth['user_id'], 'report_id': instance['id'], 'my_study_id': '' } + await sio.emit( + 'response', + {'message': 'connect success'}, + namespace = namespace_url + ) except Exception as error: print(traceback.print_exc()) + await sio.emit( + 'response', + {'message': f'server error {error}'}, + namespace = namespace_url + ) + @sio.event(namespace=namespace_url) -async def joinRoom(sid, room_id): - # TODO: Redis 사용자가 이용중인 스터디룸 정보 추가 +async def joinRoom(sid, room_id, db: Session = db): try: sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) instance = my_studies.create( db = db, room_id = room_id, - started_at = time_settings.KOR_NOW, report_id = clients[sid]['report_id'] ) clients[sid]['my_study_id'] = instance['id'] await sio.emit( 'response', - {'message': 'room joined'}, + {'message': 'join success'}, room = room_id, namespace = namespace_url ) except Exception as error: print(traceback.print_exc()) - + await sio.emit( + 'response', + {'message': f'server error {error}'}, + room = room_id, + namespace = namespace_url + ) @sio.event(namespace=namespace_url) async def leaveRoom(sid, room_id, db: Session = db): try: - # TODO: 축적된 학습 데이터 Redis > PostgreSQL 이동 필요 - message = study_rooms.leave(db, room_id=room_id) + """ + Todo + - Disturbance 테이블 생성 필요 + - Redis 넘겨 받는 데이터의 형태에 따라 구현 메서드 변경 + - bulk_insert_mappings 사용시 속도는 훨씬 빠르다. + 하지만 배열 형태의 데이터가 들어가야 하며 각 리스트에는 객체로 disturbance 데이터가 들어가야 한다. + 또한 객체 내에 report_id 와 my_study_id 에 대한 정보도 포함되어 있어야 한다. + ex. [ {type: smartphone, time: 124, count: 2, report_id: 1, my_study_id: 2}, ... ] + - update_or_create 사용시 속도는 훨씬 느리다. (개별적인 데이터에 for loop을 돌려야 하기 때문) + 이때 장점은 type과 time만 Redis에서 get 하면 된다는 점이다. + - report_id, my_study_id는 이미 글로벌하게 clients 객체에 저장되어 있다. + """ + + # disturbances.create(db, disturbances) > disturbances 부분이 Redis에서 get 한 Array[JSON] + + study_rooms.leave(db, room_id=room_id) sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) - my_studies.update( + + instance = my_studies.update( db = db, - ended_at = time_settings.KOR_NOW, - disturbance = '', id = clients[sid]['my_study_id'] ) - reports.update() + reports.update( + db = db, + id = clients[sid]['report_id'], + total_time = instance['total_time'] + ) + clients.pop(sid) await sio.emit( 'response', - {'message': message}, + {'message': 'leave success'}, room = room_id, namespace = namespace_url ) @@ -80,18 +120,33 @@ async def leaveRoom(sid, room_id, db: Session = db): print(traceback.print_exc()) await sio.emit( 'response', - {'message': error}, + {'message': f'server error {error}'}, room = room_id, namespace = namespace_url ) - @sio.event(namespace=namespace_url) async def status(sid, disturbance): - # TODO - # - Redis 사용자의 학습 상태 정보 추가 - # - 넘어 온 상태에 따른 emit > 어떤 사용자가 어떤 상태인지 보내줄 것 - # print(conn.lrange(clients[sid], 0, -1).decode()) - # await sio.emit('response', {'message': 'success'}, room=room_id, namespace=namespace_url) - pass + try: + """ + TODO: + - Client에서 disturbance 데이터에 room_id 포함하여 줘야 한다. + - response 이벤트로 message에 disturbance 상태를 보내줘야 한다. + """ + + await sio.emit( + 'response', + {'message': ''}, + room = disturbance['room_id'], + namespace = namespace_url + ) + + except Exception as error: + print(traceback.print_exc()) + await sio.emit( + 'response', + {'message': f'server error {error}'}, + room = disturbance['room_id'], + namespace = namespace_url + ) \ No newline at end of file From 9b7d82178d8e6c5ab0c0e8a8b8804a5e70d34133 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 27 May 2021 22:55:03 +0900 Subject: [PATCH 107/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20rebase=20&=20my?= =?UTF-8?q?=5Fstudies=20update=20query?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/my_studies.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index f784cab..92e1c02 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -84,9 +84,6 @@ def update(self, db: Session, id: int): db.commit() db.refresh(instance) return jsonable_encoder(instance) - else: - # Not Found - pass except: raise Exception From db282b1fd3e7cfb92fa1d6fc9d9becc4bf92688f Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Tue, 25 May 2021 18:05:03 +0900 Subject: [PATCH 108/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=EB=A0=88=ED=8F=AC=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=8A=A4=ED=82=A4=EB=A7=88=20=EB=B0=8F=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=84=B0=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/my_studies.py | 2 +- app/core/config.py | 16 ++++++++++++---- app/schemas/my_studies/__init__.py | 2 +- app/service/sockets.py | 5 ++++- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/api/my_studies.py b/app/api/my_studies.py index 45df8ca..12a1bba 100644 --- a/app/api/my_studies.py +++ b/app/api/my_studies.py @@ -70,4 +70,4 @@ def get_my_studies(date: str, user_id: int, db: Session = Depends(get_db)): ) finally: - db.close() \ No newline at end of file + db.close() diff --git a/app/core/config.py b/app/core/config.py index cb7c607..7065c8f 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -15,12 +15,14 @@ class Config: class DevelopSettings(BaseSettings): - ALLOW_ORIGIN: list = ['https://www.studeep.com/', + ALLOW_ORIGIN: list = [ + 'https://www.studeep.com/', 'https://api.studeep.com/', 'https://studeep.com/', 'http://localhost/', 'http://localhost:3000/', - 'http://localhost:8000/'] + 'http://localhost:8000/' + ] ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] @@ -29,8 +31,14 @@ class DevelopSettings(BaseSettings): class DeploySettings(BaseSettings): - # TODO: 차후 배포 전 상세 설정 필요 - ALLOW_ORIGIN: list = ['*'] + ALLOW_ORIGIN: list = [ + 'https://www.studeep.com/', + 'https://api.studeep.com/', + 'https://studeep.com/', + 'http://localhost/', + 'http://localhost:3000/', + 'http://localhost:8000/' + ] ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] ALLOW_HEADERS: list = ['*'] diff --git a/app/schemas/my_studies/__init__.py b/app/schemas/my_studies/__init__.py index da4c115..6824ab1 100644 --- a/app/schemas/my_studies/__init__.py +++ b/app/schemas/my_studies/__init__.py @@ -1,3 +1,3 @@ from app.schemas.my_studies.crud import MyStudiesCreate, MyStudiesUpdate from app.schemas.my_studies.success import GetMyStudiesResponse -from app.schemas.my_studies.handling import NotFoundMyStudiesHandling \ No newline at end of file +from app.schemas.my_studies.handling import NotFoundMyStudiesHandling diff --git a/app/service/sockets.py b/app/service/sockets.py index 4899d1d..3c2a716 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,6 +1,8 @@ import traceback import socketio +import traceback +from datetime import datetime from sqlalchemy.orm.session import Session from app.core import socket_settings @@ -11,6 +13,7 @@ disturbances ) from app.database import SessionLocal +from app.core import time_settings db = SessionLocal() @@ -149,4 +152,4 @@ async def status(sid, disturbance): {'message': f'server error {error}'}, room = disturbance['room_id'], namespace = namespace_url - ) \ No newline at end of file + ) From 1b7e45e17e1e93f3f10212099fac8a6e3df8b4dc Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 27 May 2021 19:07:35 +0900 Subject: [PATCH 109/147] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=EB=A0=88=ED=8F=AC=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EB=B0=8F=20?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/sockets.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/service/sockets.py b/app/service/sockets.py index 3c2a716..823fd08 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,8 +1,6 @@ import traceback import socketio -import traceback -from datetime import datetime from sqlalchemy.orm.session import Session from app.core import socket_settings @@ -13,7 +11,6 @@ disturbances ) from app.database import SessionLocal -from app.core import time_settings db = SessionLocal() From be685229daed7a8e9f5d2f0f28432358a44f8f09 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 28 May 2021 18:03:43 +0900 Subject: [PATCH 110/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20CORS=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 13 +++++++------ app/main.py | 9 ++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 7065c8f..d12b548 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -32,12 +32,13 @@ class DevelopSettings(BaseSettings): class DeploySettings(BaseSettings): ALLOW_ORIGIN: list = [ - 'https://www.studeep.com/', - 'https://api.studeep.com/', - 'https://studeep.com/', - 'http://localhost/', - 'http://localhost:3000/', - 'http://localhost:8000/' + # 'https://www.studeep.com/', + # 'https://api.studeep.com/', + # 'https://studeep.com/', + # 'http://localhost/', + # 'http://localhost:3000/', + # 'http://localhost:8000/' + '*' ] ALLOW_CREDENTIAL: bool = True ALLOW_METHODS: list = ['*'] diff --git a/app/main.py b/app/main.py index c5ded01..c6a309d 100644 --- a/app/main.py +++ b/app/main.py @@ -34,4 +34,11 @@ if __name__ == "__main__": - uvicorn.run('app.main:server', host="0.0.0.0", port=8000, reload=True, ssl_keyfile='/etc/letsencrypt/live/api.studeep.com/privkey.pem', ssl_certfile='/etc/letsencrypt/live/api.studeep.com/fullchain.pem') + uvicorn.run( + 'app.main:server', + host = "0.0.0.0", + port = 8000, + reload = True, + ssl_keyfile = '/etc/letsencrypt/live/api.studeep.com/privkey.pem', + ssl_certfile =' /etc/letsencrypt/live/api.studeep.com/fullchain.pem' + ) From 6d5384e561bf84a50b962359cd5285bebcd5ecf9 Mon Sep 17 00:00:00 2001 From: "weekwith.me" <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 30 May 2021 01:38:16 +0900 Subject: [PATCH 111/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20404=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20200=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(#42)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/my_studies.py | 17 +++-------------- app/api/reports.py | 17 +++-------------- app/api/study_rooms.py | 20 ++++---------------- 3 files changed, 10 insertions(+), 44 deletions(-) diff --git a/app/api/my_studies.py b/app/api/my_studies.py index 12a1bba..a82823e 100644 --- a/app/api/my_studies.py +++ b/app/api/my_studies.py @@ -31,10 +31,6 @@ "model": GetMyStudiesResponse, "description": "마이스터디 조회 성공" }, - 404: { - "model": NotFoundMyStudiesHandling, - "description": "조회한 마이 스터디가 없는 경우" - }, 500: { "model": ErrorResponseBase, "description": "서버에서 잡지 못한 에러" @@ -49,17 +45,10 @@ def get_my_studies(date: str, user_id: int, db: Session = Depends(get_db)): content = {'data': data} ) - except NoSuchElementException as element_err: - message = element_err.message - detail = get_detail( - param = 'database', - field = 'my studies', - message = message, - err = 'database' - ) + except NoSuchElementException: return JSONResponse( - status_code = status.HTTP_404_NOT_FOUND, - content = {'detail': detail} + status_code = status.HTTP_200_OK, + content = {'data': ''} ) except Exception as error: diff --git a/app/api/reports.py b/app/api/reports.py index 947871f..929a2d0 100644 --- a/app/api/reports.py +++ b/app/api/reports.py @@ -31,10 +31,6 @@ "model": GetReportReponse, "description": "레포트 조회 성공" }, - 404: { - "model": NotFoundReportHandling, - "description": "조회한 학습 레포트가 없는 경우" - }, 500: { "model": ErrorResponseBase, "description": "서버에서 잡지 못한 에러" @@ -49,17 +45,10 @@ def get_report(date: str, user_id: str, db: Session=Depends(get_db)): content = {'data': data} ) - except NoSuchElementException as element_err: - message = element_err.message - detail = get_detail( - param = 'database', - field = 'report', - message = message, - err = 'database' - ) + except NoSuchElementException: return JSONResponse( - status_code = status.HTTP_404_NOT_FOUND, - content = {'detail': detail} + status_code = status.HTTP_200_OK, + content = {'data': ''} ) except Exception as error: diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index a4cf085..11acfa6 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -47,10 +47,6 @@ "model": GetStudyRoomResponse, "description": "스터디룸 조회 성공" }, - 404: { - "model": NotFoundStudyRoomHandling, - "description": "조회한 스터디룸이 존재하지 않는 경우" - }, 500: { "model": ErrorResponseBase, "description": "서버에서 잡지 못한 에러" @@ -62,10 +58,8 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): data = study_rooms.get(db, room_id) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) - except NoSuchElementException as element_err: - message = element_err.message - detail = get_detail(param='database', field='study room', message=message, err='database') - return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + except NoSuchElementException: + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) except Exception as error: print(traceback.print_exc()) @@ -164,10 +158,6 @@ def delete_study_room(room_id: str, db: Session = Depends(get_db)): "model": GetStudyRoomsResponse, "description": "스터디룸 조희 성공" }, - 404: { - "model": NotFoundStudyRoomHandling, - "description": "조회할 스터디룸이 존재하지 않는 경우" - }, 422: { "model": QueryNeedyStudyRoomHandling, "description": "쿼리 파라미터를 제대로 전달하지 않은 경우" @@ -189,10 +179,8 @@ def get_study_rooms( data = study_rooms.get_multi(db, skip, limit, owner_id, option) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) - except NoSuchElementException as element_err: - message = element_err.message - detail = get_detail(param='database', field='study room', message=message, err='database') - return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={'detail': detail}) + except NoSuchElementException: + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) except Exception as error: print(traceback.print_exc()) From 4fb1675182f8458153df7faaaf9fa8c8b03c0fa0 Mon Sep 17 00:00:00 2001 From: "weekwith.me" <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 30 May 2021 02:50:19 +0900 Subject: [PATCH 112/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20GET=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B8=EB=93=A4=EB=A7=81=20=EB=B0=8F=20disturbances=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EB=AA=A8=EB=8D=B8=20(#43)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/my_studies.py | 2 +- app/api/reports.py | 8 +- app/api/study_rooms.py | 4 +- app/crud/__init__.py | 10 +-- app/crud/my_studies.py | 16 ++-- app/crud/reports.py | 27 +++--- app/crud/{disturbances.py => statuses.py} | 12 +-- app/crud/study_rooms.py | 2 +- app/main.py | 4 +- app/models/__init__.py | 10 +-- app/models/disturbances.py | 29 ------- app/models/my_studies.py | 2 +- app/models/reports.py | 2 +- app/models/statuses.py | 30 +++++++ app/models/users.py | 2 +- app/schemas/__init__.py | 84 +++++++++---------- app/schemas/disturbances/__init__.py | 1 - app/schemas/disturbances/crud.py | 19 ----- app/schemas/statuses/__init__.py | 1 + app/schemas/statuses/crud.py | 19 +++++ .../{disturbances => statuses}/handling.py | 0 .../{disturbances => statuses}/success.py | 0 app/service/sockets.py | 4 +- 23 files changed, 144 insertions(+), 144 deletions(-) rename app/crud/{disturbances.py => statuses.py} (77%) delete mode 100644 app/models/disturbances.py create mode 100644 app/models/statuses.py delete mode 100644 app/schemas/disturbances/__init__.py delete mode 100644 app/schemas/disturbances/crud.py create mode 100644 app/schemas/statuses/__init__.py create mode 100644 app/schemas/statuses/crud.py rename app/schemas/{disturbances => statuses}/handling.py (100%) rename app/schemas/{disturbances => statuses}/success.py (100%) diff --git a/app/api/my_studies.py b/app/api/my_studies.py index a82823e..6879c2c 100644 --- a/app/api/my_studies.py +++ b/app/api/my_studies.py @@ -48,7 +48,7 @@ def get_my_studies(date: str, user_id: int, db: Session = Depends(get_db)): except NoSuchElementException: return JSONResponse( status_code = status.HTTP_200_OK, - content = {'data': ''} + content = {'data': []} ) except Exception as error: diff --git a/app/api/reports.py b/app/api/reports.py index 929a2d0..17486bf 100644 --- a/app/api/reports.py +++ b/app/api/reports.py @@ -45,10 +45,12 @@ def get_report(date: str, user_id: str, db: Session=Depends(get_db)): content = {'data': data} ) - except NoSuchElementException: + except NoSuchElementException as element_err: + message = element_err.message + detail = get_detail(param='database', field='report', message=message, err='database') return JSONResponse( - status_code = status.HTTP_200_OK, - content = {'data': ''} + status_code = status.HTTP_404_NOT_FOUND, + content = {'detail': detail} ) except Exception as error: diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 11acfa6..909067a 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -59,7 +59,7 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) except NoSuchElementException: - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': []}) except Exception as error: print(traceback.print_exc()) @@ -180,7 +180,7 @@ def get_study_rooms( return JSONResponse(status_code=status.HTTP_200_OK, content={'data': data}) except NoSuchElementException: - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + return JSONResponse(status_code=status.HTTP_200_OK, content={'data': []}) except Exception as error: print(traceback.print_exc()) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index cc39567..81a965c 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,6 +1,6 @@ -from app.crud.users import users -from app.crud.study_rooms import study_rooms -from app.crud.disturbances import disturbances -from app.crud.my_studies import my_studies -from app.crud.reports import reports +from app.crud.users import users +from app.crud.study_rooms import study_rooms +from app.crud.statuses import statuses +from app.crud.my_studies import my_studies +from app.crud.reports import reports diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index 92e1c02..5a16702 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -5,7 +5,7 @@ from sqlalchemy.orm import Session from app.crud.base import CRUDBase -from app.models import MyStudies, Reports, Disturbances, StudyRooms +from app.models import MyStudies, Reports, Statuses, StudyRooms from app.schemas import MyStudiesCreate, MyStudiesUpdate from app.errors import NoSuchElementException from app.core import time_settings @@ -37,14 +37,14 @@ def get(self, db: Session, date: str, user_id: int): if data: for my_study in data: - my_study['disturbances'] = jsonable_encoder( - db.query(Disturbances).filter( - Disturbances.my_study_id == my_study['id'] + my_study['statuses'] = jsonable_encoder( + db.query(Statuses).filter( + Statuses.my_study_id == my_study['id'] ).with_entities( - Disturbances.id, - Disturbances.type, - Disturbances.count, - Disturbances.time, + Statuses.id, + Statuses.type, + Statuses.count, + Statuses.time, ).all() ) return jsonable_encoder(data) diff --git a/app/crud/reports.py b/app/crud/reports.py index 702a408..90fe61e 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -3,7 +3,7 @@ from sqlalchemy.orm import Session from fastapi.encoders import jsonable_encoder -from app.models import Reports, Disturbances +from app.models import Reports, Statuses from app.schemas import ReportsCreate, ReportsUpdate from app.crud.base import CRUDBase from app.errors import NoSuchElementException @@ -19,8 +19,8 @@ def get(self, db: Session, user_id: str, date: str): self.model.user_id == user_id, self.model.date == date )).outerjoin( - Disturbances, - Disturbances.report_id == self.model.id + Statuses, + Statuses.report_id == self.model.id ).with_entities( self.model.id, self.model.date, @@ -28,20 +28,20 @@ def get(self, db: Session, user_id: str, date: str): self.model.concentration, self.model.total_time, self.model.total_star_count, - func.count(Disturbances.count).label('total_disturbance_counts') + func.count(Statuses.count).label('total_status_counts') ).group_by(self.model.id).first() if instance: - report = jsonable_encoder(instance) - disturbances = db.query(Disturbances).filter( - Disturbances.report_id == report['id'] + report = jsonable_encoder(instance) + statuses = db.query(Statuses).filter( + Statuses.report_id == report['id'] ).with_entities( - Disturbances.type, - func.count(Disturbances.count).label('total_count'), - func.sum(Disturbances.time).label('total_time') - ).group_by(Disturbances.type).all() + Statuses.type, + func.count(Statuses.count).label('total_count'), + func.sum(Statuses.time).label('total_time') + ).group_by(Statuses.type).all() - report['disturbances'] = jsonable_encoder(disturbances) + report['statuses'] = jsonable_encoder(statuses) return report else: raise NoSuchElementException(message='not found') @@ -85,9 +85,6 @@ def update(self, db: Session, id: int, total_time: int): if instance: instance.total_time += total_time db.commit() - else: - # Not Found - pass except: raise Exception diff --git a/app/crud/disturbances.py b/app/crud/statuses.py similarity index 77% rename from app/crud/disturbances.py rename to app/crud/statuses.py index e46e6ef..0ed544a 100644 --- a/app/crud/disturbances.py +++ b/app/crud/statuses.py @@ -2,13 +2,13 @@ from sqlalchemy.orm import Session from app.crud.base import CRUDBase -from app.models import Disturbances -from app.schemas import DisturbanceCreate, DisturbanceUpdate +from app.models import Statuses +from app.schemas import StatusCreate, StatusUpdate -class CRUDDisturbance(CRUDBase[Disturbances, DisturbanceCreate, DisturbanceUpdate]): - def create(self, db: Session, disturbances: list): +class CRUDStatus(CRUDBase[Statuses, StatusCreate, StatusUpdate]): + def create(self, db: Session, statuses: list): try: - db.bulk_insert_mappings(self.model, disturbances) + db.bulk_insert_mappings(self.model, statuses) db.commit() except: @@ -56,4 +56,4 @@ def update_or_create( db.close() -disturbances = CRUDDisturbance(Disturbances) \ No newline at end of file +statuses = CRUDStatus(Statuses) \ No newline at end of file diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 92a3f3c..2a79c99 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -48,7 +48,7 @@ def get(self, db: Session, room_id: UUID): ).first() if data: - return jsonable_encoder(data) + return [jsonable_encoder(data)] else: raise NoSuchElementException(message='not found') diff --git a/app/main.py b/app/main.py index c6a309d..d90bfac 100644 --- a/app/main.py +++ b/app/main.py @@ -39,6 +39,6 @@ host = "0.0.0.0", port = 8000, reload = True, - ssl_keyfile = '/etc/letsencrypt/live/api.studeep.com/privkey.pem', - ssl_certfile =' /etc/letsencrypt/live/api.studeep.com/fullchain.pem' + # ssl_keyfile = '/etc/letsencrypt/live/api.studeep.com/privkey.pem', + # ssl_certfile =' /etc/letsencrypt/live/api.studeep.com/fullchain.pem' ) diff --git a/app/models/__init__.py b/app/models/__init__.py index b53006b..4dd1202 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,5 +1,5 @@ -from app.models.users import User -from app.models.study_rooms import StudyRooms, Style -from app.models.my_studies import MyStudies -from app.models.reports import Reports -from app.models.disturbances import Disturbances, DisturbanceType +from app.models.users import User +from app.models.study_rooms import StudyRooms, Style +from app.models.my_studies import MyStudies +from app.models.reports import Reports +from app.models.statuses import Statuses, StatusType diff --git a/app/models/disturbances.py b/app/models/disturbances.py deleted file mode 100644 index 08cf3df..0000000 --- a/app/models/disturbances.py +++ /dev/null @@ -1,29 +0,0 @@ -import enum - -from sqlalchemy import ( - Column, - Enum, - Integer, - ForeignKey - ) -from sqlalchemy.orm import relation - -from app.database import Base - - -class DisturbanceType(str, enum.Enum): - SMARTPHONE = 'smartphone' - AWAIT = 'await' - SLEEP = 'sleep' - - -class Disturbances(Base): - __tablename__ = 'disturbances' - id = Column('disturbance_id', Integer(), primary_key=True, autoincrement=True) - type = Column('disturbance_type', Enum(DisturbanceType), nullable=False) - count = Column('disturbance_count', Integer(), nullable=False) - time = Column('disturbance_time', Integer(), nullable=False) - my_study_id = Column(Integer(), ForeignKey('my_studies.my_study_id', ondelete='CASCADE')) - report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete='CASCADE')) - my_study = relation('MyStudies', back_populates='disturbance') - report = relation('Reports', back_populates='total_disturbance') \ No newline at end of file diff --git a/app/models/my_studies.py b/app/models/my_studies.py index d558f66..de84252 100644 --- a/app/models/my_studies.py +++ b/app/models/my_studies.py @@ -21,4 +21,4 @@ class MyStudies(Base): study_room_id = Column(UUID(as_uuid=True), ForeignKey('study_rooms.study_room_id', ondelete='CASCADE')) report = relation('Reports', back_populates='my_studies') study_room = relation('StudyRooms', back_populates='my_study') - disturbance = relation('Disturbances', back_populates='my_study') + status = relation('Statuses', back_populates='my_study') diff --git a/app/models/reports.py b/app/models/reports.py index 063be7c..3f7673d 100644 --- a/app/models/reports.py +++ b/app/models/reports.py @@ -20,4 +20,4 @@ class Reports(Base): user_id = Column(Integer(), ForeignKey('users.user_id', ondelete='CASCADE')) user = relation('User', back_populates='reports') my_studies = relation('MyStudies', back_populates='report') - total_disturbance = relation('Disturbances', back_populates='report') + total_status = relation('Statuses', back_populates='report') diff --git a/app/models/statuses.py b/app/models/statuses.py new file mode 100644 index 0000000..3ea43bc --- /dev/null +++ b/app/models/statuses.py @@ -0,0 +1,30 @@ +import enum + +from sqlalchemy import ( + Column, + Enum, + Integer, + ForeignKey + ) +from sqlalchemy.orm import relation + +from app.database import Base + + +class StatusType(str, enum.Enum): + SMARTPHONE = 'smartphone' + AWAIT = 'await' + SLEEP = 'sleep' + REST = 'rest' + + +class Statuses(Base): + __tablename__ = 'statuses' + id = Column('status_id', Integer(), primary_key=True, autoincrement=True) + type = Column('status_type', Enum(StatusType), nullable=False) + count = Column('status_count', Integer(), nullable=False) + time = Column('status_time', Integer(), nullable=False) + my_study_id = Column(Integer(), ForeignKey('my_studies.my_study_id', ondelete='CASCADE')) + report_id = Column(Integer(), ForeignKey('reports.report_id', ondelete='CASCADE')) + my_study = relation('MyStudies', back_populates='status') + report = relation('Reports', back_populates='total_status') \ No newline at end of file diff --git a/app/models/users.py b/app/models/users.py index 9c85fdd..f451d8d 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -1,6 +1,6 @@ import enum -from sqlalchemy import Column, Integer, Enum, String +from sqlalchemy import Column, Integer, Enum, String, JSON from sqlalchemy.orm import relation from sqlalchemy.dialects.postgresql import JSON diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 0e53504..bc0f214 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,43 +1,43 @@ -from app.schemas.responses import ( - SuccessResponseBase, - ErrorResponseBase, - MethodNotAllowedHandling - ) -from app.schemas.users import ( - NotFoundUserHandling, - UnauthorizedHandler, - ForbiddenHandler, - UserDataResponse, - UserBase, - UserCreate, - UserUpdate - ) -from app.schemas.study_rooms import ( - StudyRoomsCreate, - StudyRoomsUpdate, - StudyRoomJoin, - GetStudyRoomResponse, - GetStudyRoomsResponse, - NotFoundStudyRoomHandling, - PasswordNeedyStudyRoomHandling, - BodyNeedyStudyRoomHandling, - QueryNeedyStudyRoomHandling, - NoEmptyRoomHandling, - ForbiddenUserHandling - ) -from app.schemas.reports import ( - ReportsCreate, - ReportsUpdate, - GetReportReponse, - NotFoundReportHandling - ) -from app.schemas.my_studies import ( - MyStudiesCreate, - MyStudiesUpdate, - GetMyStudiesResponse, - NotFoundMyStudiesHandling - ) -from app.schemas.disturbances import ( - DisturbanceCreate, - DisturbanceUpdate +from app.schemas.responses import ( + SuccessResponseBase, + ErrorResponseBase, + MethodNotAllowedHandling + ) +from app.schemas.users import ( + NotFoundUserHandling, + UnauthorizedHandler, + ForbiddenHandler, + UserDataResponse, + UserBase, + UserCreate, + UserUpdate + ) +from app.schemas.study_rooms import ( + StudyRoomsCreate, + StudyRoomsUpdate, + StudyRoomJoin, + GetStudyRoomResponse, + GetStudyRoomsResponse, + NotFoundStudyRoomHandling, + PasswordNeedyStudyRoomHandling, + BodyNeedyStudyRoomHandling, + QueryNeedyStudyRoomHandling, + NoEmptyRoomHandling, + ForbiddenUserHandling + ) +from app.schemas.reports import ( + ReportsCreate, + ReportsUpdate, + GetReportReponse, + NotFoundReportHandling + ) +from app.schemas.my_studies import ( + MyStudiesCreate, + MyStudiesUpdate, + GetMyStudiesResponse, + NotFoundMyStudiesHandling + ) +from app.schemas.statuses import ( + StatusCreate, + StatusUpdate ) diff --git a/app/schemas/disturbances/__init__.py b/app/schemas/disturbances/__init__.py deleted file mode 100644 index 6351d86..0000000 --- a/app/schemas/disturbances/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from app.schemas.disturbances.crud import DisturbanceCreate, DisturbanceUpdate \ No newline at end of file diff --git a/app/schemas/disturbances/crud.py b/app/schemas/disturbances/crud.py deleted file mode 100644 index aafa51d..0000000 --- a/app/schemas/disturbances/crud.py +++ /dev/null @@ -1,19 +0,0 @@ -from pydantic import BaseModel - -from app.models import DisturbanceType - - -class DisturbanceBase(BaseModel): - pass - - -class DisturbanceCreate(DisturbanceBase): - type: DisturbanceType - count: int - time: int - my_study_id: int - report_id: int - - -class DisturbanceUpdate(DisturbanceBase): - pass \ No newline at end of file diff --git a/app/schemas/statuses/__init__.py b/app/schemas/statuses/__init__.py new file mode 100644 index 0000000..a1f02e6 --- /dev/null +++ b/app/schemas/statuses/__init__.py @@ -0,0 +1 @@ +from app.schemas.statuses.crud import StatusCreate, StatusUpdate \ No newline at end of file diff --git a/app/schemas/statuses/crud.py b/app/schemas/statuses/crud.py new file mode 100644 index 0000000..ba50033 --- /dev/null +++ b/app/schemas/statuses/crud.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel + +from app.models import StatusType + + +class StatusBase(BaseModel): + pass + + +class StatusCreate(StatusBase): + type: StatusType + count: int + time: int + my_study_id: int + report_id: int + + +class StatusUpdate(StatusBase): + pass \ No newline at end of file diff --git a/app/schemas/disturbances/handling.py b/app/schemas/statuses/handling.py similarity index 100% rename from app/schemas/disturbances/handling.py rename to app/schemas/statuses/handling.py diff --git a/app/schemas/disturbances/success.py b/app/schemas/statuses/success.py similarity index 100% rename from app/schemas/disturbances/success.py rename to app/schemas/statuses/success.py diff --git a/app/service/sockets.py b/app/service/sockets.py index 823fd08..b3a5cad 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -8,7 +8,7 @@ study_rooms, reports, my_studies, - disturbances + statuses ) from app.database import SessionLocal @@ -93,7 +93,7 @@ async def leaveRoom(sid, room_id, db: Session = db): - report_id, my_study_id는 이미 글로벌하게 clients 객체에 저장되어 있다. """ - # disturbances.create(db, disturbances) > disturbances 부분이 Redis에서 get 한 Array[JSON] + # statuses.create(db, disturbances) > disturbances 부분이 Redis에서 get 한 Array[JSON] study_rooms.leave(db, room_id=room_id) sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) From 977da2c7e6c8b00d9b4f8287ebbd93453c549062 Mon Sep 17 00:00:00 2001 From: "weekwith.me" <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 30 May 2021 02:56:54 +0900 Subject: [PATCH 113/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20main=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/main.py b/app/main.py index d90bfac..c6a309d 100644 --- a/app/main.py +++ b/app/main.py @@ -39,6 +39,6 @@ host = "0.0.0.0", port = 8000, reload = True, - # ssl_keyfile = '/etc/letsencrypt/live/api.studeep.com/privkey.pem', - # ssl_certfile =' /etc/letsencrypt/live/api.studeep.com/fullchain.pem' + ssl_keyfile = '/etc/letsencrypt/live/api.studeep.com/privkey.pem', + ssl_certfile =' /etc/letsencrypt/live/api.studeep.com/fullchain.pem' ) From 8eac91addd859ebc62cd6abb71c8578c5fd1971e Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 30 May 2021 06:43:42 +0900 Subject: [PATCH 114/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20socket=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20class=ED=99=94=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/my_studies.py | 20 ++- app/crud/reports.py | 14 +- app/crud/statuses.py | 23 +-- app/crud/study_rooms.py | 42 ++++- app/main.py | 9 +- app/service/__init__.py | 2 +- app/service/sockets.py | 334 +++++++++++++++++++++++----------------- 7 files changed, 282 insertions(+), 162 deletions(-) diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index 5a16702..197738a 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -1,14 +1,14 @@ from uuid import UUID from datetime import datetime from fastapi.encoders import jsonable_encoder -from sqlalchemy import and_ +from sqlalchemy import and_, func from sqlalchemy.orm import Session from app.crud.base import CRUDBase from app.models import MyStudies, Reports, Statuses, StudyRooms from app.schemas import MyStudiesCreate, MyStudiesUpdate from app.errors import NoSuchElementException -from app.core import time_settings +from app.core import time_settings, my_studies_settings class CRUDMyStudy(CRUDBase[MyStudies, MyStudiesCreate, MyStudiesUpdate]): @@ -74,13 +74,23 @@ def update(self, db: Session, id: int): try: instance = db.query(self.model).filter( self.model.id == id - ).first() + ).first() + + statuses = db.query(Statuses).filter( + Statuses.my_study_id == instance.id + ).with_entities( + func.sum(Statuses.time).label('total_time') + ).first() + if instance: + + print(jsonable_encoder(instance)) instance.ended_at = datetime.utcnow() + time_settings.KST instance.total_time = ( - instance.ended_at - instance.started_at - ).seconds + instance.ended_at - \ + instance.started_at + ).seconds - jsonable_encoder(statuses)['total_time'] db.commit() db.refresh(instance) return jsonable_encoder(instance) diff --git a/app/crud/reports.py b/app/crud/reports.py index 90fe61e..1b71326 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -1,5 +1,5 @@ from datetime import datetime -from sqlalchemy import and_, func +from sqlalchemy import and_, func, not_ from sqlalchemy.orm import Session from fastapi.encoders import jsonable_encoder @@ -16,8 +16,9 @@ def get(self, db: Session, user_id: str, date: str): instance = db.query( self.model, ).filter(and_( - self.model.user_id == user_id, - self.model.date == date + self.model.user_id == user_id, + self.model.date == date, + self.model.total_time != 0 )).outerjoin( Statuses, Statuses.report_id == self.model.id @@ -28,7 +29,9 @@ def get(self, db: Session, user_id: str, date: str): self.model.concentration, self.model.total_time, self.model.total_star_count, - func.count(Statuses.count).label('total_status_counts') + func.count(Statuses.count).filter(not_( + Statuses.type == 'rest' + )).label('total_status_counts') ).group_by(self.model.id).first() if instance: @@ -69,7 +72,8 @@ def get_or_create(self, db: Session, user_id: int): db.refresh(instance) return jsonable_encoder(instance) - except: + except Exception as error: + print(error) raise Exception finally: diff --git a/app/crud/statuses.py b/app/crud/statuses.py index 0ed544a..6b5d1bc 100644 --- a/app/crud/statuses.py +++ b/app/crud/statuses.py @@ -1,17 +1,19 @@ -from sqlalchemy import and_ -from sqlalchemy.orm import Session +from fastapi.encoders import jsonable_encoder +from sqlalchemy import and_ +from sqlalchemy.orm import Session -from app.crud.base import CRUDBase -from app.models import Statuses -from app.schemas import StatusCreate, StatusUpdate +from app.crud.base import CRUDBase +from app.models import Statuses +from app.schemas import StatusCreate, StatusUpdate class CRUDStatus(CRUDBase[Statuses, StatusCreate, StatusUpdate]): - def create(self, db: Session, statuses: list): - try: - db.bulk_insert_mappings(self.model, statuses) + def create(self, db: Session, statuses: dict): + try: + # instance = db.bulk_insert_mappings(self.model, statuses) db.commit() - except: + except Exception as error: + print(error) raise Exception finally: @@ -48,6 +50,9 @@ def update_or_create( db.add(instance) db.commit() + db.refresh(instance) + + return jsonable_encoder(instance) except: raise Exception diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 2a79c99..fb7d183 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -133,8 +133,8 @@ def remove(self, db: Session, room_id: str): def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): try: - if not room_id: - raise NoSuchElementException(message='not found') + # if not room_id: + # raise NoSuchElementException(message='not found') data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() study_room = jsonable_encoder(data) if study_room: @@ -177,5 +177,43 @@ def leave(self, db: Session, room_id: str): finally: db.close() + + def current_check(self, db: Session, user_id: int): + try: + """ + TODO + - Redis에 접근해서 user_id가 존재하는지 확인한다. + - 만약 있을 경우 공부 중이던 사람이기 때문에 ABNORMAL의 TIMESTAMP를 확인한다. + - 만약 5분이 지난 경우 삭제하고 Redis Initialize를 종료한다. + 이때 해당 사용자가 포함되어 있던 study_room의 current_join_count도 차감한다. + 이를 수행하기 위해 Redis에 room_id 또한 포함되어야 할 것으로 판단된다. + - 5분이 지나지 않은 경우 재접속 할 것인지 묻는다. + - user_id가 존재하지 않는 경우와 5분이 지난 경우 200 status_code로 응답한다. + - 만약 5분이 지나지 않아서 재접속 여부를 물어봐야 할 경우 409 conflict 응답한다. + """ + + pass + + except Exception: + raise Exception + + + def re_join(self, db: Session, user_id: int, is_re_joined: bool): + try: + """ + TODO + - current_check 엔드포인트에 이어서 만약 재접속하겠다고 한 경우 + data에 해당 room_id를 포함해서 보내준다. + 페이지 랜더링을 통해 해당 방으로 가야하기 때문이다. + - 만약 재접속하지 않겠다고 한 경우 data에 빈 문자열을 보내준다. + - 그리고 재접속하지 않겠다고 한 경우 해당 마이스터디 테이블을 삭제한다. + - 재접속과 그렇지 않은 경우 모두 status_code 200으로 응답한다. + """ + + pass + + except Exception: + raise Exception + study_rooms = CRUDStudyRoom(StudyRooms) \ No newline at end of file diff --git a/app/main.py b/app/main.py index c6a309d..fb3d6ba 100644 --- a/app/main.py +++ b/app/main.py @@ -11,10 +11,15 @@ develop_settings, deploy_settings ) -from app.service import sio - +from app.service import StudyNamespace server = FastAPI(title=common_settings.PROJECT_NAME) +sio = socketio.AsyncServer( + async_mode = 'asgi', + cors_allowed_origins = '*', + debug = True +) +sio.register_namespace(StudyNamespace(sio, '/study')) sio_app = socketio.ASGIApp(socketio_server=sio, other_asgi_app=server) server.add_middleware( diff --git a/app/service/__init__.py b/app/service/__init__.py index 7075dd1..0555554 100644 --- a/app/service/__init__.py +++ b/app/service/__init__.py @@ -1,2 +1,2 @@ from app.service.auth import auth_token -from app.service.sockets import sio \ No newline at end of file +from app.service.sockets import StudyNamespace \ No newline at end of file diff --git a/app/service/sockets.py b/app/service/sockets.py index b3a5cad..0696abf 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,9 +1,7 @@ -import traceback import socketio +import traceback -from sqlalchemy.orm.session import Session -from app.core import socket_settings from app.crud import ( study_rooms, reports, @@ -13,140 +11,200 @@ from app.database import SessionLocal -db = SessionLocal() -sio = socketio.AsyncServer( - async_mode = 'asgi', - cors_allowed_origins = '*', - debug = True -) -namespace_url = socket_settings.NAMESPACE_URL -clients = dict() - - -@sio.event(namespace=namespace_url) -async def connect(sid, environ, auth): - try: - instance = reports.get_or_create( - db = db, - user_id = auth['user_id'] - ) - clients[sid] = { - 'user_id': auth['user_id'], - 'report_id': instance['id'], - 'my_study_id': '' - } - await sio.emit( - 'response', - {'message': 'connect success'}, - namespace = namespace_url - ) - - except Exception as error: - print(traceback.print_exc()) - await sio.emit( - 'response', - {'message': f'server error {error}'}, - namespace = namespace_url - ) - - -@sio.event(namespace=namespace_url) -async def joinRoom(sid, room_id, db: Session = db): - try: - sio.enter_room(sid=sid, room=room_id, namespace=namespace_url) - instance = my_studies.create( - db = db, - room_id = room_id, - report_id = clients[sid]['report_id'] - ) - clients[sid]['my_study_id'] = instance['id'] - await sio.emit( - 'response', - {'message': 'join success'}, - room = room_id, - namespace = namespace_url - ) +clients = dict() + + +class StudyNamespace(socketio.AsyncNamespace): + def __init__(self, sio, namespace, *args, **kwargs): + super(socketio.Namespace, self).__init__(namespace) + self.sio = sio + self.db = SessionLocal() + + + async def on_connect(self, sid, environ, auth): + try: + print(sid) + print('connect') + instance = reports.get_or_create( + db = self.db, + user_id = auth['user_id'] + ) + clients[sid] = { + 'user_id': auth['user_id'], + 'room_id': '', + 'report_id': instance['id'], + 'my_study_id': '', + # 're_joined': False + } + + # if not clients: + # """ + # TODO + # - Redis Initialize + # """ + # # print('initial connect') + + # else: + # # print('re-connect') + # """ + # TODO + # - 정상적으로 다시 진입했기 때문에 Redis ABNORMAL 삭제 + # """ + # # self.clients['re_joined'] = False + + + except Exception as error: + print(traceback.print_exc()) + await self.emit( + 'response', + {'message': f'server error {error}'}, + namespace = self.namespace + ) + - except Exception as error: - print(traceback.print_exc()) - await sio.emit( - 'response', - {'message': f'server error {error}'}, - room = room_id, - namespace = namespace_url - ) - - -@sio.event(namespace=namespace_url) -async def leaveRoom(sid, room_id, db: Session = db): - try: - """ - Todo - - Disturbance 테이블 생성 필요 - - Redis 넘겨 받는 데이터의 형태에 따라 구현 메서드 변경 - - bulk_insert_mappings 사용시 속도는 훨씬 빠르다. - 하지만 배열 형태의 데이터가 들어가야 하며 각 리스트에는 객체로 disturbance 데이터가 들어가야 한다. - 또한 객체 내에 report_id 와 my_study_id 에 대한 정보도 포함되어 있어야 한다. - ex. [ {type: smartphone, time: 124, count: 2, report_id: 1, my_study_id: 2}, ... ] - - update_or_create 사용시 속도는 훨씬 느리다. (개별적인 데이터에 for loop을 돌려야 하기 때문) - 이때 장점은 type과 time만 Redis에서 get 하면 된다는 점이다. - - report_id, my_study_id는 이미 글로벌하게 clients 객체에 저장되어 있다. - """ - - # statuses.create(db, disturbances) > disturbances 부분이 Redis에서 get 한 Array[JSON] - - study_rooms.leave(db, room_id=room_id) - sio.leave_room(sid=sid, room=room_id, namespace=namespace_url) - - instance = my_studies.update( - db = db, - id = clients[sid]['my_study_id'] - ) - reports.update( - db = db, - id = clients[sid]['report_id'], - total_time = instance['total_time'] - ) - - clients.pop(sid) - await sio.emit( - 'response', - {'message': 'leave success'}, - room = room_id, - namespace = namespace_url - ) + async def on_joinRoom(self, sid, room_id): + try: + print('join') + print(clients) + + self.enter_room(sid=sid, room=room_id, namespace=self.namespace) + instance = my_studies.create( + db = self.db, + room_id = room_id, + report_id = clients[sid]['report_id'] + ) + clients[sid]['room_id'] = room_id + clients[sid]['my_study_id'] = instance['id'] + await self.emit( + 'response', + {'message': 'join success'}, + room = room_id, + namespace = self.namespace + ) - except Exception as error: - print(traceback.print_exc()) - await sio.emit( - 'response', - {'message': f'server error {error}'}, - room = room_id, - namespace = namespace_url - ) - - -@sio.event(namespace=namespace_url) -async def status(sid, disturbance): - try: - """ - TODO: - - Client에서 disturbance 데이터에 room_id 포함하여 줘야 한다. - - response 이벤트로 message에 disturbance 상태를 보내줘야 한다. - """ - - await sio.emit( - 'response', - {'message': ''}, - room = disturbance['room_id'], - namespace = namespace_url - ) - - except Exception as error: - print(traceback.print_exc()) - await sio.emit( - 'response', - {'message': f'server error {error}'}, - room = disturbance['room_id'], - namespace = namespace_url - ) + except Exception as error: + print(traceback.print_exc()) + await self.emit( + 'response', + {'message': f'server error {error}'}, + room = room_id, + namespace = self.namespace + ) + + async def on_leaveRoom(self, sid, room_id): + try: + """ + Todo + - Disturbance 테이블 생성 필요 + - Redis 넘겨 받는 데이터의 형태에 따라 구현 메서드 변경 + - bulk_insert_mappings 사용시 속도는 훨씬 빠르다. + 하지만 배열 형태의 데이터가 들어가야 하며 각 리스트에는 객체로 disturbance 데이터가 들어가야 한다. + 또한 객체 내에 report_id 와 my_study_id 에 대한 정보도 포함되어 있어야 한다. + ex. [ {type: smartphone, time: 124, count: 2, report_id: 1, my_study_id: 2}, ... ] + - update_or_create 사용시 속도는 훨씬 느리다. (개별적인 데이터에 for loop을 돌려야 하기 때문) + 이때 장점은 type과 time만 Redis에서 get 하면 된다는 점이다. + - report_id, my_study_id는 이미 글로벌하게 clients 객체에 저장되어 있다. + """ + + # disturbances.create(db, disturbances) > disturbances 부분이 Redis에서 get 한 Array[JSON] + + study_rooms.leave(self.db, room_id=room_id) + self.leave_room(sid=sid, room=room_id, namespace=self.namespace) + + instance = my_studies.update( + db = self.db, + id = clients[sid]['my_study_id'] + ) + reports.update( + db = self.db, + id = clients[sid]['report_id'], + total_time = instance['total_time'] + ) + + clients.pop(sid) + + await self.emit( + 'disconnect', + {'message': 'leave success'}, + room = room_id, + namespace = self.namespace + ) + await self.disconnect(sid, namespace=self.namespace) + + except Exception as error: + print(traceback.print_exc()) + await self.emit( + 'response', + {'message': f'server error {error}'}, + room = room_id, + namespace = self.namespace + ) + + + async def on_status(self, sid, status): + try: + """ + TODO: + - Client에서 disturbance 데이터에 room_id 포함하여 줘야 한다. + - response 이벤트로 message에 disturbance 상태를 보내줘야 한다. + - 개별 사용자의 휴식이 다르기 때문에 Redis에 휴식에 대한 것도 저장 할 필요가 있어 보인다. + """ + print('status', status) + statuses.update_or_create( + self.db, + status['type'], + status['time'], + clients[sid]['my_study_id'], + clients[sid]['report_id'] + ) + + await self.emit( + 'response', + {'message': status['type']}, + room = status['room_id'], + namespace = self.namespace + ) + + except Exception as error: + print(traceback.print_exc()) + await self.emit( + 'response', + {'message': f'server error {error}'}, + room = statuses['room_id'], + namespace = self.namespace + ) + + + async def on_disconnect(self, sid): + try: + """ + TODO: + - leaveRoom을 발생시켜도 disconnect event가 발생할 것이다. + 비정상적인 종료와 차이점은 leaveRoom일 때는 clients 객체가 빈 객체다. + - Redis에 이미 해당 사용자의 id가 저장되어 있기 때문에 clients 등을 통해 user_id에 접근하여 + 발생 시점의 timstamp와 함께 ABNORMAL 타입을 저장한다. + """ + # if self.clients: + # Redis 저장 부분 + print('disconnect') + + study_rooms.leave(self.db, room_id=clients[sid]['room_id']) + self.leave_room(sid=sid, room=clients[sid]['room_id'], namespace=self.namespace) + + + my_study = my_studies.update( + db = self.db, + id = clients[sid]['my_study_id'] + ) + reports.update( + db = self.db, + id = clients[sid]['report_id'], + total_time = my_study['total_time'] + ) + + clients.pop(sid) + + print(clients) + + except Exception as error: + print(traceback.print_exc()) \ No newline at end of file From aa6bd37da4e103cf71414510433bfbbdc95fe6d2 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 30 May 2021 06:25:59 +0900 Subject: [PATCH 115/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8?= =?UTF-8?q?=ED=8A=B8=20Forbidden=20=ED=95=B8=EB=93=A4=EB=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/reports.py | 8 +++----- app/api/study_rooms.py | 27 +++++++++++++++++++++++---- app/crud/reports.py | 2 +- app/crud/study_rooms.py | 18 +++++++++++++----- app/schemas/__init__.py | 3 ++- app/schemas/study_rooms/__init__.py | 1 + app/schemas/study_rooms/crud.py | 4 +++- app/schemas/study_rooms/handling.py | 22 ++++++++++++++++++++-- 8 files changed, 66 insertions(+), 19 deletions(-) diff --git a/app/api/reports.py b/app/api/reports.py index 17486bf..6ed1b5b 100644 --- a/app/api/reports.py +++ b/app/api/reports.py @@ -45,12 +45,10 @@ def get_report(date: str, user_id: str, db: Session=Depends(get_db)): content = {'data': data} ) - except NoSuchElementException as element_err: - message = element_err.message - detail = get_detail(param='database', field='report', message=message, err='database') + except NoSuchElementException: return JSONResponse( - status_code = status.HTTP_404_NOT_FOUND, - content = {'detail': detail} + status_code = status.HTTP_200_OK, + content = {'data': []} ) except Exception as error: diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index 909067a..caad65f 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -26,7 +26,8 @@ QueryNeedyStudyRoomHandling, MethodNotAllowedHandling, NoEmptyRoomHandling, - ForbiddenUserHandling + ForbiddenUserHandling, + ForbiddenPasswordHandling ) from app.errors import ( get_detail, @@ -76,6 +77,10 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): "model": SuccessResponseBase, "description": "스터디룸 수정 성공" }, + 403: { + "model": ForbiddenUserHandling, + "description": "본인이 만들지 않은 방을 수정하려는 경우" + }, 404: { "model": NotFoundStudyRoomHandling, "description": "수정을 시도한 스터디룸이 이미 존재하지 않는 경우" @@ -100,6 +105,11 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D study_rooms.update(db, room_id, room_info) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + except ForbiddenException as forbidden_err: + message = forbidden_err.message + detail = get_detail(param='database', field='user', message=message, err='invalid') + return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) + except InvalidArgumentException as argument_err: message = argument_err.message detail = get_detail(param='body', field='password', message=message, err='value_error') @@ -122,6 +132,10 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D "model": SuccessResponseBase, "description": "스터디룸 삭제 성공" }, + 403: { + "model": ForbiddenUserHandling, + "description": "본인이 만들지 않은 방을 삭제하려는 경우" + }, 404: { "model": NotFoundStudyRoomHandling, "description": "삭제를 시도한 스터디룸이 이미 존재하지 않는 경우" @@ -136,11 +150,16 @@ def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = D } } ) -def delete_study_room(room_id: str, db: Session = Depends(get_db)): +def delete_study_room(user_id: int, room_id: str, db: Session = Depends(get_db)): try: - study_rooms.remove(db, room_id) + study_rooms.remove(db, room_id, user_id) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + except ForbiddenException as forbidden_err: + message = forbidden_err.message + detail = get_detail(param='database', field='user', message=message, err='invalid') + return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) + except NoSuchElementException as element_err: message = element_err.message detail = get_detail(param='database', field='study room', message=message, err='database') @@ -236,7 +255,7 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) "description": "스터디룸 생성 성공" }, 403: { - "model": ForbiddenUserHandling, + "model": ForbiddenPasswordHandling, "description": "비공개 방의 비밀번호 오입력 한 경우" }, 404: { diff --git a/app/crud/reports.py b/app/crud/reports.py index 1b71326..a486c08 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -45,7 +45,7 @@ def get(self, db: Session, user_id: str, date: str): ).group_by(Statuses.type).all() report['statuses'] = jsonable_encoder(statuses) - return report + return [report] else: raise NoSuchElementException(message='not found') diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index fb7d183..77038e3 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -108,24 +108,32 @@ def update(self, db: Session, room_id: str, room_info: StudyRoomsUpdate): raise InvalidArgumentException(message='field required') update_data = room_info.dict(exclude_none=True) - data = db.query(self.model).filter(self.model.id == UUID(room_id)).update(update_data) + data = db.query(self.model).filter(and_( + self.model.id == UUID(room_id), + self.model.owner_id == room_info.owner_id + )).update(update_data) + if data: db.commit() else: - raise NoSuchElementException(message='not found') + raise ForbiddenException(message='forbidden') except ValueError: raise NoSuchElementException(message='not found') - def remove(self, db: Session, room_id: str): + def remove(self, db: Session, room_id: str, user_id: int): try: - data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() + data = db.query(self.model).filter(and_( + self.model.id == UUID(room_id), + self.model.owner_id == user_id + )).first() + if data: db.delete(data) db.commit() else: - raise NoSuchElementException(message='not found') + raise ForbiddenException(message='forbidden') except ValueError: raise NoSuchElementException(message='not found') diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index bc0f214..78561a4 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -23,7 +23,8 @@ BodyNeedyStudyRoomHandling, QueryNeedyStudyRoomHandling, NoEmptyRoomHandling, - ForbiddenUserHandling + ForbiddenUserHandling, + ForbiddenPasswordHandling ) from app.schemas.reports import ( ReportsCreate, diff --git a/app/schemas/study_rooms/__init__.py b/app/schemas/study_rooms/__init__.py index c09610d..52da0d2 100644 --- a/app/schemas/study_rooms/__init__.py +++ b/app/schemas/study_rooms/__init__.py @@ -13,5 +13,6 @@ BodyNeedyStudyRoomHandling, QueryNeedyStudyRoomHandling, NoEmptyRoomHandling, + ForbiddenPasswordHandling, ForbiddenUserHandling ) \ No newline at end of file diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index a97618d..ad37e71 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -34,13 +34,15 @@ class Config: class StudyRoomsUpdate(StudyRoomsBase): title: Optional[str] is_public: Optional[bool] + owner_id: int class Config: schema_extra = { 'example': { 'description': '매일 매일 캠 스터디 가능하신 분들만!', 'is_public': False, - 'password': 'TestPassword!234' + 'password': 'TestPassword!234', + 'owner_id': 1 } } diff --git a/app/schemas/study_rooms/handling.py b/app/schemas/study_rooms/handling.py index 1b82d32..cb2335a 100644 --- a/app/schemas/study_rooms/handling.py +++ b/app/schemas/study_rooms/handling.py @@ -107,7 +107,7 @@ class Config: } -class ForbiddenUserHandling(ErrorResponseBase): +class ForbiddenPasswordHandling(ErrorResponseBase): class Config: schema_extra = { 'example': { @@ -122,4 +122,22 @@ class Config: } ] } - } \ No newline at end of file + } + + +class ForbiddenUserHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "user" + ], + "msg": "forbidden", + "type": "invalid" + } + ] + } + } \ No newline at end of file From 8952a6269e7a6f1c6c4fcf4706315e2d5841d184 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 30 May 2021 06:45:51 +0900 Subject: [PATCH 116/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20access=20token?= =?UTF-8?q?=20=EC=9C=A0=EC=A7=80=20=EC=8B=9C=EA=B0=84=20500=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=EC=9C=BC=EB=A1=9C=20=EC=9E=84=EC=8B=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/core/config.py b/app/core/config.py index d12b548..1fc68d0 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -51,7 +51,7 @@ class UserSettings(BaseSettings): API_USER: str = '/user' SECRET_KEY: str = secrets.token_urlsafe(32) ALGORITHM = "HS256" - ACCESS_TOKEN_EXPIRE_MINUTES = 30 + ACCESS_TOKEN_EXPIRE_MINUTES = 30000 class StudyRoomSettings(BaseSettings): From a0702bcf9eaf0fef3f472c3accd3dd8df6b7f860 Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 30 May 2021 06:47:31 +0900 Subject: [PATCH 117/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20sign=5Fin=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EB=A1=9C=EC=A7=81=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/api/users.py b/app/api/users.py index 5b31a9a..408cff7 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -98,7 +98,6 @@ def sign_up(*, db: Session = Depends(get_db), } ) def sign_in(*, db: Session = Depends(get_db), - response: Response, authorization: Optional[str] = Header(None) ): try: @@ -116,9 +115,9 @@ def sign_in(*, db: Session = Depends(get_db), headers={"Authorization": 'bearer ' + token} ) - response.headers["Authorization"] = 'bearer ' + token - - return JSONResponse(status_code=status.HTTP_200_OK, content={'data': jsonable_encoder(user)}) + return JSONResponse(status_code=status.HTTP_200_OK, + content={'data': jsonable_encoder(user)}, + headers={"Authorization": 'bearer ' + token}) except JWTError: message = traceback.format_exc() detail = get_detail(param='token', field='authorize', message=message, err='invalid Google token') From b9e88b2a3624ce2cf556c1c5e5cecb4ec6574f5d Mon Sep 17 00:00:00 2001 From: "junkyu.lim" Date: Sun, 30 May 2021 06:47:40 +0900 Subject: [PATCH 118/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20get=5Fuser=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/users.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/api/users.py b/app/api/users.py index 408cff7..900bbeb 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -178,6 +178,11 @@ def get_user( detail = get_detail(param='token', field='forbidden', message=message, err='This token is not access token') return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) + except KeyError: + message = traceback.format_exc() + detail = get_detail(param='token', field='forbidden', message=message, + err='This token is not access token') + return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content={'detail': detail}) except Exception as error: logging.error(traceback.format_exc()) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, From a62e76b9f1aa361362adb4f55b5356fba9aa65cb Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Sun, 30 May 2021 08:21:56 +0900 Subject: [PATCH 119/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=B0=8F=20=EB=A7=88=EC=9D=B4=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/my_studies.py | 18 +++++++++++------ app/crud/study_rooms.py | 36 +++++++++++++++++---------------- app/schemas/study_rooms/crud.py | 4 ++-- app/service/sockets.py | 6 ++++++ 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index 197738a..2cf58c3 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -3,6 +3,7 @@ from fastapi.encoders import jsonable_encoder from sqlalchemy import and_, func from sqlalchemy.orm import Session +from sqlalchemy.sql.base import Executable from app.crud.base import CRUDBase from app.models import MyStudies, Reports, Statuses, StudyRooms @@ -84,18 +85,23 @@ def update(self, db: Session, id: int): if instance: - - print(jsonable_encoder(instance)) + print('statuses', jsonable_encoder(statuses)) + print('before ended_at', jsonable_encoder(instance)) instance.ended_at = datetime.utcnow() + time_settings.KST + print('after ended_at: ', jsonable_encoder(instance)) instance.total_time = ( - instance.ended_at - \ - instance.started_at - ).seconds - jsonable_encoder(statuses)['total_time'] + instance.ended_at - instance.started_at + ).seconds + + if jsonable_encoder(statuses)['total_time']: + instance.total_time -= jsonable_encoder(statuses)['total_time'] + db.commit() db.refresh(instance) return jsonable_encoder(instance) - except: + except Exception as error: + print(error) raise Exception finally: diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 77038e3..28e97c4 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -144,25 +144,27 @@ def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): # if not room_id: # raise NoSuchElementException(message='not found') data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() - study_room = jsonable_encoder(data) - if study_room: - if study_room['current_join_counts'] >= MAX_CAPACITY: - raise RequestConflictException(message='no empty') - - if study_room['is_public']: - if room_info.password: - raise InvalidArgumentException(message='field not required') - else: - if not room_info.password: - raise InvalidArgumentException(message='field required') - elif room_info.password != study_room['password']: - raise ForbiddenException(message='forbidden') - data.current_join_counts += 1 - db.commit() + if not data.owner_id == room_info.owner_id: + study_room = jsonable_encoder(data) + if study_room: + if study_room['current_join_counts'] >= MAX_CAPACITY: + raise RequestConflictException(message='no empty') + + if study_room['is_public']: + if room_info.password: + raise InvalidArgumentException(message='field not required') + else: + if not room_info.password: + raise InvalidArgumentException(message='field required') + elif room_info.password != study_room['password']: + raise ForbiddenException(message='forbidden') + + data.current_join_counts += 1 + db.commit() - else: - raise NoSuchElementException(message='not found') + else: + raise NoSuchElementException(message='not found') except ValueError: raise NoSuchElementException(message='not found') diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index ad37e71..641eb0e 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -8,6 +8,7 @@ class StudyRoomsBase(BaseModel): description: Optional[str] password: Optional[str] + owner_id: int class StudyRoomsCreate(StudyRoomsBase): @@ -16,7 +17,6 @@ class StudyRoomsCreate(StudyRoomsBase): is_public: bool current_join_counts: int = 0 created_at: Optional[datetime] - owner_id: int class Config: schema_extra = { @@ -34,7 +34,6 @@ class Config: class StudyRoomsUpdate(StudyRoomsBase): title: Optional[str] is_public: Optional[bool] - owner_id: int class Config: schema_extra = { @@ -52,6 +51,7 @@ class StudyRoomJoin(StudyRoomsBase): class Config: schema_extra = { 'example': { + 'owner_id': '1', 'password': 'TestPassword!234' } } \ No newline at end of file diff --git a/app/service/sockets.py b/app/service/sockets.py index 0696abf..7d3e099 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -51,6 +51,12 @@ async def on_connect(self, sid, environ, auth): # - 정상적으로 다시 진입했기 때문에 Redis ABNORMAL 삭제 # """ # # self.clients['re_joined'] = False + + await self.emit( + 'response', + {'message': 'connection'}, + namespace = self.namespace + ) except Exception as error: From 2a55900ae416672cf6a7cccc76df30274d2168d8 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Mon, 21 Jun 2021 23:13:31 +0900 Subject: [PATCH 120/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A3=B8=20=EC=9E=85=EC=9E=A5=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=B6=88=ED=94=BC=EC=9A=94=ED=95=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=20=EC=95=84=EC=9D=B4=EB=94=94=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 45 ++++++++++++++++----------------- app/schemas/study_rooms/crud.py | 7 ++--- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 28e97c4..edb12e7 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -141,30 +141,29 @@ def remove(self, db: Session, room_id: str, user_id: int): def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): try: - # if not room_id: - # raise NoSuchElementException(message='not found') - data = db.query(self.model).filter(self.model.id == UUID(room_id)).first() - - if not data.owner_id == room_info.owner_id: - study_room = jsonable_encoder(data) - if study_room: - if study_room['current_join_counts'] >= MAX_CAPACITY: - raise RequestConflictException(message='no empty') - - if study_room['is_public']: - if room_info.password: - raise InvalidArgumentException(message='field not required') - else: - if not room_info.password: - raise InvalidArgumentException(message='field required') - elif room_info.password != study_room['password']: - raise ForbiddenException(message='forbidden') - - data.current_join_counts += 1 - db.commit() - + data = db.query(self.model).filter( + self.model.id == UUID(room_id) + ).first() + study_room = jsonable_encoder(data) + + if study_room: + if study_room['current_join_counts'] >= MAX_CAPACITY: + raise RequestConflictException(message='no empty') + + if study_room['is_public']: + if room_info.password: + raise InvalidArgumentException(message='field not required') else: - raise NoSuchElementException(message='not found') + if not room_info.password: + raise InvalidArgumentException(message='field required') + elif room_info.password != study_room['password']: + raise ForbiddenException(message='forbidden') + + data.current_join_counts += 1 + db.commit() + + else: + raise NoSuchElementException(message='not found') except ValueError: raise NoSuchElementException(message='not found') diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index 641eb0e..7707859 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -6,17 +6,17 @@ class StudyRoomsBase(BaseModel): - description: Optional[str] password: Optional[str] - owner_id: int class StudyRoomsCreate(StudyRoomsBase): title: str + description: Optional[str] style: Style is_public: bool current_join_counts: int = 0 created_at: Optional[datetime] + owner_id: int class Config: schema_extra = { @@ -33,7 +33,9 @@ class Config: class StudyRoomsUpdate(StudyRoomsBase): title: Optional[str] + description: Optional[str] is_public: Optional[bool] + owner_id: int class Config: schema_extra = { @@ -51,7 +53,6 @@ class StudyRoomJoin(StudyRoomsBase): class Config: schema_extra = { 'example': { - 'owner_id': '1', 'password': 'TestPassword!234' } } \ No newline at end of file From 5a23cbeb75c880a982bc2266958f407a10c1b876 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Mon, 21 Jun 2021 23:13:44 +0900 Subject: [PATCH 121/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20parsing=5Ftoke?= =?UTF-8?q?n=5Fdecorator=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/service/auth.py b/app/service/auth.py index 24fddcf..bad2417 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -16,7 +16,10 @@ def parsing_token_decorator(func): def wrapper(token: str, **kwargs): - return func(token.split(" ")[1], **kwargs) + try: + return func(token.split(" ")[1], **kwargs) + except: + raise JWTError() return wrapper From 112f20d243931e8507e04fed34dc968abffdfb33 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Mon, 21 Jun 2021 23:14:38 +0900 Subject: [PATCH 122/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20user=5Fid=20?= =?UTF-8?q?=EC=9E=90=EB=A3=8C=ED=98=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/reports.py | 2 +- app/crud/reports.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/api/reports.py b/app/api/reports.py index 6ed1b5b..06a0f05 100644 --- a/app/api/reports.py +++ b/app/api/reports.py @@ -37,7 +37,7 @@ } } ) -def get_report(date: str, user_id: str, db: Session=Depends(get_db)): +def get_report(date: str, user_id: int, db: Session=Depends(get_db)): try: data = reports.get(db, user_id, date) return JSONResponse( diff --git a/app/crud/reports.py b/app/crud/reports.py index a486c08..6a60968 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -11,7 +11,7 @@ class CRUDReport(CRUDBase[Reports, ReportsCreate, ReportsUpdate]): - def get(self, db: Session, user_id: str, date: str): + def get(self, db: Session, user_id: int, date: str): date = datetime.strptime(date, '%Y-%m-%d') instance = db.query( self.model, @@ -56,7 +56,7 @@ def get_or_create(self, db: Session, user_id: int): if (today.hour >= 0) and (today.hour < 5): date = datetime(today.year, today.month, today.day - 1) else: - date = date = datetime(today.year, today.month, today.day) + date = datetime(today.year, today.month, today.day) instance = db.query(self.model).filter(and_( self.model.user_id == user_id, From 047b6ed12be0da1a6ca0a86edd4ccf374b597505 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Mon, 21 Jun 2021 23:16:51 +0900 Subject: [PATCH 123/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20=EC=95=A1?= =?UTF-8?q?=EC=84=B8=EC=8A=A4=ED=86=A0=ED=81=B0=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EA=B8=B0=EA=B0=84=20=EC=A6=9D=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/core/config.py b/app/core/config.py index 1fc68d0..198eac3 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -51,7 +51,7 @@ class UserSettings(BaseSettings): API_USER: str = '/user' SECRET_KEY: str = secrets.token_urlsafe(32) ALGORITHM = "HS256" - ACCESS_TOKEN_EXPIRE_MINUTES = 30000 + ACCESS_TOKEN_EXPIRE_MINUTES = 300000 class StudyRoomSettings(BaseSettings): From b5f389e273c4d56873579caf6154bc28586e67eb Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 25 Jun 2021 00:27:29 +0900 Subject: [PATCH 124/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20status=20respo?= =?UTF-8?q?nse=20key=EA=B0=92=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/reports.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/crud/reports.py b/app/crud/reports.py index 6a60968..9bb56ad 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -39,8 +39,8 @@ def get(self, db: Session, user_id: int, date: str): statuses = db.query(Statuses).filter( Statuses.report_id == report['id'] ).with_entities( - Statuses.type, - func.count(Statuses.count).label('total_count'), + Statuses.type.label('name'), + func.count(Statuses.count).label('value'), func.sum(Statuses.time).label('total_time') ).group_by(Statuses.type).all() From 4bd904673a41777bb05dbec4c2b4116c132d6714 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 25 Jun 2021 00:33:30 +0900 Subject: [PATCH 125/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20key=EC=9D=98?= =?UTF-8?q?=20path=EB=A5=BC=20=EC=A7=80=EC=A0=95=ED=95=B4=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index fb3d6ba..6fc7211 100644 --- a/app/main.py +++ b/app/main.py @@ -45,5 +45,5 @@ port = 8000, reload = True, ssl_keyfile = '/etc/letsencrypt/live/api.studeep.com/privkey.pem', - ssl_certfile =' /etc/letsencrypt/live/api.studeep.com/fullchain.pem' + ssl_certfile = '/etc/letsencrypt/live/api.studeep.com/fullchain.pem' ) From 9515491d31319cc89ffb354aec3272530dba759a Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 25 Jun 2021 00:25:03 +0900 Subject: [PATCH 126/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20redis=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/redis.py | 125 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 app/crud/redis.py diff --git a/app/crud/redis.py b/app/crud/redis.py new file mode 100644 index 0000000..f9f705b --- /dev/null +++ b/app/crud/redis.py @@ -0,0 +1,125 @@ +from datetime import time + +import redis +from datetime import timedelta +from collections.abc import MutableMapping + +from app.core import user_settings + + +def __setflat_skeys__( + r: redis.Redis, + obj: dict, + prefix: str, + delim: str = ":", + *, + _autopfix="" +) -> None: + allowed_vtypes = (str, bytes, float, int) + for key, value in obj.items(): + key = _autopfix + key + if isinstance(value, allowed_vtypes): + r.set(f"{prefix}{delim}{key}", value) + elif isinstance(value, MutableMapping): + __setflat_skeys__( + r, value, prefix, delim, _autopfix=f"{key}{delim}" + ) + else: + raise TypeError(f"Unsupported value type: {type(value)}") + + +def study_room_starting(study_room_id): + return { + "status": "study", + "study_rooms": study_room_id, + "last_access": 1, + "sleep": { + "count": 0, + "sec": 0 + }, + "phone": { + "count": 0, + "sec": 0 + }, + "await": { + "count": 0, + "sec": 0 + }, + "rest": { + "count": 0, + "sec": 0 + } + } + + +def __generate_value_string__(user_id, user_monitoring, disturb_info=None): + if disturb_info is None: + return f"{user_id}:{user_monitoring}" + return f"{user_id}:{user_monitoring}:{disturb_info}" + + +class redis_function: + redis = redis.Redis(port=6000, host='localhost') + + def __del__(self): + self.redis.close() + + def logout(self, token: str, user_email: str): + self.redis.setex(token, timedelta(minutes=user_settings.ACCESS_TOKEN_EXPIRE_MINUTES), user_email) + + def check_black_list(self, token: str): + self.redis.exists(token) + + def start_study_init(self, user_id: str, study_room_id: str): + __setflat_skeys__(self.redis, study_room_starting(study_room_id), user_id) + + def get_user_study_info(self, user_id, user_monitoring, disturb_info=None): + return self.redis.get( + __generate_value_string__(user_id, user_monitoring, disturb_info) + ) + + def add_current_log(self, user_id, disturb_type, disturb_time): + # status를 업데이트 해야함 + # 이 때, 이전 상태를 저장해야 함. + status_key = __generate_value_string__(user_id, "status") + last_status = self.redis.get(status_key) + self.redis.set(status_key, disturb_type) + + # 이전 상태가 study가 아닐 경우 last_access와 비교하여 시간을 알아내야 함. + last_access_key = __generate_value_string__(user_id, "last_access") + last_access = self.redis.get(last_access_key) + + self.redis.set(last_access_key, disturb_time) + + if last_status != "study": + status_time = disturb_time - last_access + + self.redis.incr(__generate_value_string__(user_id, last_status, 'count'), 1) + self.redis.incr(__generate_value_string__(user_id, last_status, 'sec'), status_time) + + def delete_user_study_info(self, user_id: str): + target_key = self.redis.keys(user_id + ':*') + self.redis.delete(target_key) + + def end_study(self, user_id: str): + study_room_id = self.redis.get(__generate_value_string__(user_id, "study_rooms")) + sleep_values = self.get_status_value(user_id, "sleep") + phone_values = self.get_status_value(user_id, "phone") + await_values = self.get_status_value(user_id, "await") + rest_values = self.get_status_value(user_id, "rest") + + self.delete_user_study_info(user_id) + + return { + "study_room_id": study_room_id, + "sleep": sleep_values, + "phone": phone_values, + "await": await_values, + "rest": rest_values + } + + def get_status_value(self, user_id: str, status: str): + return { + "count": self.redis.get(__generate_value_string__(user_id, status, 'count')), + "sec": self.redis.get(__generate_value_string__(user_id, status, 'sec')) + } From 5bf5a65f692215be9f4d6de3223e9298b91a8494 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 25 Jun 2021 00:48:17 +0900 Subject: [PATCH 127/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20redis=5Fsettin?= =?UTF-8?q?gs=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 3 ++- app/core/config.py | 5 +++++ app/crud/redis.py | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/core/__init__.py b/app/core/__init__.py index f813423..f2223c5 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -7,5 +7,6 @@ my_studies_settings, report_settings, socket_settings, - time_settings + time_settings, + redis_settings ) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index 198eac3..f668a32 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -75,6 +75,10 @@ class SocketSettings(BaseSettings): class TimeSettings(BaseSettings): KST = timedelta(hours=9) +class RedisSettings(BaseSettings): + HOST = "https://api.studeep.com" + PORT = 6000 + common_settings = CommonSettings() develop_settings = DevelopSettings() @@ -85,3 +89,4 @@ class TimeSettings(BaseSettings): report_settings = ReportSettings() socket_settings = SocketSettings() time_settings = TimeSettings() +redis_settings = RedisSettings() diff --git a/app/crud/redis.py b/app/crud/redis.py index f9f705b..0fc4c24 100644 --- a/app/crud/redis.py +++ b/app/crud/redis.py @@ -4,7 +4,7 @@ from datetime import timedelta from collections.abc import MutableMapping -from app.core import user_settings +from app.core import redis_settings,user_settings def __setflat_skeys__( @@ -59,7 +59,7 @@ def __generate_value_string__(user_id, user_monitoring, disturb_info=None): class redis_function: - redis = redis.Redis(port=6000, host='localhost') + redis = redis.Redis(port=redis_settings.PORT, host=redis_settings.HOST) def __del__(self): self.redis.close() From 147e99c10394e6aa63b518fc1bb894085853e530 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Wed, 30 Jun 2021 22:25:24 +0900 Subject: [PATCH 128/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20redis=20requir?= =?UTF-8?q?ements=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 6246f71..58ca7d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,6 +35,7 @@ python-engineio==4.2.0 python-jose==3.2.0 python-socketio==5.3.0 PyYAML==5.4.1 +redis==3.5.3 requests==2.25.1 rsa==4.7.2 six==1.16.0 From 82c3752e48f60c33132efdc2c529804f52eba9b1 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 1 Jul 2021 10:34:37 +0900 Subject: [PATCH 129/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EC=97=90=EB=9F=AC=20=ED=95=B8=EB=93=A4=EB=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=97=90=EB=B0=8B=20=EC=96=91?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/my_studies.py | 15 +++- app/crud/study_rooms.py | 18 +++- app/errors/__init__.py | 1 + app/errors/customs.py | 9 ++ app/service/sockets.py | 182 +++++++++++++++++++++++----------------- 5 files changed, 143 insertions(+), 82 deletions(-) diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index 2cf58c3..eee6bed 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -3,7 +3,7 @@ from fastapi.encoders import jsonable_encoder from sqlalchemy import and_, func from sqlalchemy.orm import Session -from sqlalchemy.sql.base import Executable +from sqlalchemy.exc import IntegrityError from app.crud.base import CRUDBase from app.models import MyStudies, Reports, Statuses, StudyRooms @@ -54,6 +54,9 @@ def get(self, db: Session, date: str, user_id: int): def create(self, db: Session, room_id: str, report_id: int): try: + if not room_id: + raise NoSuchElementException(message='not found') + instance = self.model( study_room_id = UUID(room_id), report_id = report_id, @@ -64,8 +67,14 @@ def create(self, db: Session, room_id: str, report_id: int): db.refresh(instance) return jsonable_encoder(instance) - except: - raise Exception + except AttributeError: + raise NoSuchElementException(message='not found') + + except ValueError: + raise NoSuchElementException(message='not found') + + except IntegrityError: + raise NoSuchElementException(message='not found') finally: db.close() diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index edb12e7..0bc10a7 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -19,6 +19,7 @@ NoSuchElementException, InvalidArgumentException, RequestConflictException, + RequestInvalidException, ForbiddenException ) from app.core import time_settings @@ -174,14 +175,25 @@ def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): def leave(self, db: Session, room_id: str): try: + if not room_id: + raise NoSuchElementException(message='not found') + + if self.model.current_join_counts < 1: + raise RequestInvalidException(message='invalid request') + db.query(self.model).filter(self.model.id == UUID(room_id)).update( {'current_join_counts': self.model.current_join_counts - 1} ) db.commit() - except Exception as error: - # TODO: 더 구체적인 에러 핸들링 필요 ex. Positive Integer(MIN_CAPACITY) - raise Exception + except AttributeError: + raise NoSuchElementException(message='not found') + + except ValueError: + raise NoSuchElementException(message='not found') + + except IntegrityError: + raise NoSuchElementException(message='not found') finally: db.close() diff --git a/app/errors/__init__.py b/app/errors/__init__.py index 2e9c254..380471a 100644 --- a/app/errors/__init__.py +++ b/app/errors/__init__.py @@ -4,5 +4,6 @@ NoSuchElementException, InvalidArgumentException, RequestConflictException, + RequestInvalidException, ForbiddenException ) \ No newline at end of file diff --git a/app/errors/customs.py b/app/errors/customs.py index 0e46682..dc42f9f 100644 --- a/app/errors/customs.py +++ b/app/errors/customs.py @@ -53,5 +53,14 @@ def __init__(self, message: str): self.message = message + def __str__(self): + return self.message + + +class RequestInvalidException(Exception): + def __init__(self, message: str): + self.message = message + + def __str__(self): return self.message \ No newline at end of file diff --git a/app/service/sockets.py b/app/service/sockets.py index 7d3e099..a061f66 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,14 +1,14 @@ import socketio import traceback - -from app.crud import ( - study_rooms, - reports, - my_studies, - statuses - ) -from app.database import SessionLocal +from app.crud import ( + study_rooms, + reports, + my_studies, + statuses + ) +from app.database import SessionLocal +from app.errors import NoSuchElementException, RequestInvalidException clients = dict() @@ -23,8 +23,6 @@ def __init__(self, sio, namespace, *args, **kwargs): async def on_connect(self, sid, environ, auth): try: - print(sid) - print('connect') instance = reports.get_or_create( db = self.db, user_id = auth['user_id'] @@ -34,27 +32,16 @@ async def on_connect(self, sid, environ, auth): 'room_id': '', 'report_id': instance['id'], 'my_study_id': '', - # 're_joined': False } - # if not clients: - # """ - # TODO - # - Redis Initialize - # """ - # # print('initial connect') - - # else: - # # print('re-connect') - # """ - # TODO - # - 정상적으로 다시 진입했기 때문에 Redis ABNORMAL 삭제 - # """ - # # self.clients['re_joined'] = False - await self.emit( 'response', - {'message': 'connection'}, + { + 'statusCode': 200, + 'message': 'SUCCESS', + 'eventName': 'connect', + 'data': {} + }, namespace = self.namespace ) @@ -63,16 +50,18 @@ async def on_connect(self, sid, environ, auth): print(traceback.print_exc()) await self.emit( 'response', - {'message': f'server error {error}'}, + { + 'statusCode': 500, + 'message': f'SERVER_ERROR_{error}', + 'eventName': 'connect', + 'data': {} + }, namespace = self.namespace ) async def on_joinRoom(self, sid, room_id): - try: - print('join') - print(clients) - + try: self.enter_room(sid=sid, room=room_id, namespace=self.namespace) instance = my_studies.create( db = self.db, @@ -83,17 +72,38 @@ async def on_joinRoom(self, sid, room_id): clients[sid]['my_study_id'] = instance['id'] await self.emit( 'response', - {'message': 'join success'}, + { + 'statusCode': 200, + 'message': 'SUCCESS', + 'eventName': 'joinRoom', + 'dat': {} + }, room = room_id, namespace = self.namespace ) - + + except NoSuchElementException: + await self.emit( + 'response', + { + 'statusCode': 404, + 'message': 'NOT_FOUND', + 'eventName': 'joinRoom', + 'data': {} + }, + namespace = self.namespace + ) + except Exception as error: print(traceback.print_exc()) await self.emit( 'response', - {'message': f'server error {error}'}, - room = room_id, + { + 'statusCode': 500, + 'message': f'SERVER_ERROR_{error}', + 'eventName': 'joinRoom', + 'data': {} + }, namespace = self.namespace ) @@ -111,38 +121,53 @@ async def on_leaveRoom(self, sid, room_id): 이때 장점은 type과 time만 Redis에서 get 하면 된다는 점이다. - report_id, my_study_id는 이미 글로벌하게 clients 객체에 저장되어 있다. """ - - # disturbances.create(db, disturbances) > disturbances 부분이 Redis에서 get 한 Array[JSON] - - study_rooms.leave(self.db, room_id=room_id) - self.leave_room(sid=sid, room=room_id, namespace=self.namespace) - - instance = my_studies.update( - db = self.db, - id = clients[sid]['my_study_id'] - ) - reports.update( - db = self.db, - id = clients[sid]['report_id'], - total_time = instance['total_time'] - ) - clients.pop(sid) - await self.emit( 'disconnect', - {'message': 'leave success'}, + { + 'statusCode': 200, + 'message': 'SUCCESS', + 'eventName': 'leaveRoom', + 'data': {} + }, room = room_id, namespace = self.namespace ) await self.disconnect(sid, namespace=self.namespace) - + + except RequestInvalidException: + await self.emit( + 'response', + { + 'statusCode': 400, + 'message': 'INVALID_REQUEST', + 'eventName': 'leaveRoom', + 'data': {} + } + ) + + except NoSuchElementException: + await self.emit( + 'response', + { + 'statusCode': 404, + 'messgae': 'NOT_FOUND', + 'eventName': 'leaveRoom', + 'data': {} + }, + namespace = self.namespace + ) + except Exception as error: print(traceback.print_exc()) await self.emit( 'response', - {'message': f'server error {error}'}, - room = room_id, + { + 'statusCode': 500, + 'message': f'SERVER_ERROR_{error}', + 'eventName': 'leaveRoom', + 'data': {} + }, namespace = self.namespace ) @@ -156,18 +181,16 @@ async def on_status(self, sid, status): - 개별 사용자의 휴식이 다르기 때문에 Redis에 휴식에 대한 것도 저장 할 필요가 있어 보인다. """ print('status', status) - statuses.update_or_create( - self.db, - status['type'], - status['time'], - clients[sid]['my_study_id'], - clients[sid]['report_id'] - ) await self.emit( 'response', - {'message': status['type']}, - room = status['room_id'], + { + 'statusCode': 200, + 'message': 'SUCCESS', + 'eventName': 'status', + 'data': status + }, + room = clients[sid]['room_id'], namespace = self.namespace ) @@ -175,8 +198,12 @@ async def on_status(self, sid, status): print(traceback.print_exc()) await self.emit( 'response', - {'message': f'server error {error}'}, - room = statuses['room_id'], + { + 'statusCode': 500, + 'message': f'SERVER_ERROR_{error}', + 'eventName': 'status', + 'data': {} + }, namespace = self.namespace ) @@ -190,14 +217,9 @@ async def on_disconnect(self, sid): - Redis에 이미 해당 사용자의 id가 저장되어 있기 때문에 clients 등을 통해 user_id에 접근하여 발생 시점의 timstamp와 함께 ABNORMAL 타입을 저장한다. """ - # if self.clients: - # Redis 저장 부분 - print('disconnect') - study_rooms.leave(self.db, room_id=clients[sid]['room_id']) self.leave_room(sid=sid, room=clients[sid]['room_id'], namespace=self.namespace) - my_study = my_studies.update( db = self.db, id = clients[sid]['my_study_id'] @@ -210,7 +232,15 @@ async def on_disconnect(self, sid): clients.pop(sid) - print(clients) - except Exception as error: - print(traceback.print_exc()) \ No newline at end of file + print(traceback.print_exc()) + await self.emit( + 'response', + { + 'statusCode': 500, + 'message': f'SERVER_ERROR_{error}', + 'eventName': 'disconnect', + 'data' : {} + }, + namespace = self.namespace + ) \ No newline at end of file From 627c4fc0c2d58e32fe5ba2745daf8ef5268de260 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 1 Jul 2021 22:56:43 +0900 Subject: [PATCH 130/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EC=97=90=EB=9F=AC=20=ED=95=B8=EB=93=A4=EB=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80(=EB=B0=B0=ED=8F=AC=20=EC=A7=81=EC=A0=84=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=98=88=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/study_rooms.py | 4 ++-- app/service/sockets.py | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 0bc10a7..54afb4a 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -177,12 +177,12 @@ def leave(self, db: Session, room_id: str): try: if not room_id: raise NoSuchElementException(message='not found') - + if self.model.current_join_counts < 1: raise RequestInvalidException(message='invalid request') db.query(self.model).filter(self.model.id == UUID(room_id)).update( - {'current_join_counts': self.model.current_join_counts - 1} + {'current_join_counts': self.model.current_join_counts - 1} ) db.commit() diff --git a/app/service/sockets.py b/app/service/sockets.py index a061f66..31746d4 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -23,6 +23,7 @@ def __init__(self, sio, namespace, *args, **kwargs): async def on_connect(self, sid, environ, auth): try: + print('connect') instance = reports.get_or_create( db = self.db, user_id = auth['user_id'] @@ -43,7 +44,9 @@ async def on_connect(self, sid, environ, auth): 'data': {} }, namespace = self.namespace - ) + ) + + print('connect success') except Exception as error: @@ -62,6 +65,7 @@ async def on_connect(self, sid, environ, auth): async def on_joinRoom(self, sid, room_id): try: + print('join room') self.enter_room(sid=sid, room=room_id, namespace=self.namespace) instance = my_studies.create( db = self.db, @@ -82,7 +86,10 @@ async def on_joinRoom(self, sid, room_id): namespace = self.namespace ) + print('join room success') + except NoSuchElementException: + print('not found') await self.emit( 'response', { @@ -121,6 +128,7 @@ async def on_leaveRoom(self, sid, room_id): 이때 장점은 type과 time만 Redis에서 get 하면 된다는 점이다. - report_id, my_study_id는 이미 글로벌하게 clients 객체에 저장되어 있다. """ + print('leave room') await self.emit( 'disconnect', @@ -135,7 +143,10 @@ async def on_leaveRoom(self, sid, room_id): ) await self.disconnect(sid, namespace=self.namespace) + print('leave room success') + except RequestInvalidException: + print('invalid request') await self.emit( 'response', { @@ -147,6 +158,7 @@ async def on_leaveRoom(self, sid, room_id): ) except NoSuchElementException: + print('not found') await self.emit( 'response', { @@ -217,6 +229,9 @@ async def on_disconnect(self, sid): - Redis에 이미 해당 사용자의 id가 저장되어 있기 때문에 clients 등을 통해 user_id에 접근하여 발생 시점의 timstamp와 함께 ABNORMAL 타입을 저장한다. """ + if sid in clients: + clients.pop(sid) + print('disconnect') study_rooms.leave(self.db, room_id=clients[sid]['room_id']) self.leave_room(sid=sid, room=clients[sid]['room_id'], namespace=self.namespace) @@ -230,7 +245,21 @@ async def on_disconnect(self, sid): total_time = my_study['total_time'] ) - clients.pop(sid) + + print('disconnect success') + + except NoSuchElementException: + print('not found') + await self.emit( + 'response', + { + 'statusCode': 404, + 'messgae': 'NOT_FOUND', + 'eventName': 'leaveRoom', + 'data': {} + }, + namespace = self.namespace + ) except Exception as error: print(traceback.print_exc()) From f17d2933acbc51ba2ee46d366a557d683a27d91c Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Fri, 2 Jul 2021 00:28:47 +0900 Subject: [PATCH 131/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EC=97=B0=EA=B2=B0=20=ED=95=B4=EC=A0=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/sockets.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/service/sockets.py b/app/service/sockets.py index 31746d4..b8f2801 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -229,8 +229,6 @@ async def on_disconnect(self, sid): - Redis에 이미 해당 사용자의 id가 저장되어 있기 때문에 clients 등을 통해 user_id에 접근하여 발생 시점의 timstamp와 함께 ABNORMAL 타입을 저장한다. """ - if sid in clients: - clients.pop(sid) print('disconnect') study_rooms.leave(self.db, room_id=clients[sid]['room_id']) self.leave_room(sid=sid, room=clients[sid]['room_id'], namespace=self.namespace) @@ -245,7 +243,8 @@ async def on_disconnect(self, sid): total_time = my_study['total_time'] ) - + clients.pop(sid) + print(f'sid: {sid}, clients: {clients}') print('disconnect success') except NoSuchElementException: From 2e96faaf3e2a2a3d778ea625af9fa6de5f94fef7 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 2 Jul 2021 13:20:50 +0900 Subject: [PATCH 132/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20socket?= =?UTF-8?q?=EC=97=90=20redis=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/__init__.py | 1 + app/crud/redis.py | 2 +- app/crud/statuses.py | 5 +++-- app/service/sockets.py | 44 +++++++++++++++++++++++++++++++++--------- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 81a965c..5cfb940 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -3,4 +3,5 @@ from app.crud.statuses import statuses from app.crud.my_studies import my_studies from app.crud.reports import reports +from app.crud.redis import redis_function diff --git a/app/crud/redis.py b/app/crud/redis.py index 0fc4c24..fff5712 100644 --- a/app/crud/redis.py +++ b/app/crud/redis.py @@ -113,7 +113,7 @@ def end_study(self, user_id: str): return { "study_room_id": study_room_id, "sleep": sleep_values, - "phone": phone_values, + "smartphone": phone_values, "await": await_values, "rest": rest_values } diff --git a/app/crud/statuses.py b/app/crud/statuses.py index 6b5d1bc..da54e5f 100644 --- a/app/crud/statuses.py +++ b/app/crud/statuses.py @@ -24,6 +24,7 @@ def update_or_create( self, db: Session, type: str, + cnt: int, time: int, my_study_id: int, report_id: int @@ -36,13 +37,13 @@ def update_or_create( )).first() if instance: - instance.count += 1 + instance.count += cnt instance.time += time else: instance = self.model( type = type, - count = 1, + count = cnt, time = time, my_study_id = my_study_id, report_id = report_id diff --git a/app/service/sockets.py b/app/service/sockets.py index b8f2801..ab623fa 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,15 +1,19 @@ import socketio import traceback -from app.crud import ( - study_rooms, - reports, - my_studies, - statuses - ) -from app.database import SessionLocal -from app.errors import NoSuchElementException, RequestInvalidException +import time + + +from app.crud import ( + study_rooms, + reports, + my_studies, + statuses, + redis_function + ) +from app.database import SessionLocal +from app.errors import NoSuchElementException, RequestInvalidException clients = dict() @@ -19,6 +23,7 @@ def __init__(self, sio, namespace, *args, **kwargs): super(socketio.Namespace, self).__init__(namespace) self.sio = sio self.db = SessionLocal() + self.redis = redis_function() async def on_connect(self, sid, environ, auth): @@ -74,6 +79,9 @@ async def on_joinRoom(self, sid, room_id): ) clients[sid]['room_id'] = room_id clients[sid]['my_study_id'] = instance['id'] + # redis table init + self.redis.start_study_init(user_id = clients['user_id'], study_room_id=room_id) + await self.emit( 'response', { @@ -194,6 +202,9 @@ async def on_status(self, sid, status): """ print('status', status) + self.redis.add_current_log(clients['user_id'], status, time.time()) + + await self.emit( 'response', { @@ -233,6 +244,11 @@ async def on_disconnect(self, sid): study_rooms.leave(self.db, room_id=clients[sid]['room_id']) self.leave_room(sid=sid, room=clients[sid]['room_id'], namespace=self.namespace) + result = self.redis.end_study(clients['user_id']) + + for status in ['sleep', 'smartphone', 'await', 'rest']: + self.__create_status__(sid, status, result[status]) + my_study = my_studies.update( db = self.db, id = clients[sid]['my_study_id'] @@ -271,4 +287,14 @@ async def on_disconnect(self, sid): 'data' : {} }, namespace = self.namespace - ) \ No newline at end of file + ) + + async def __create_status__(self, sid, type, study_result: dict): + statuses.update_or_create( + db = self.db, + type = type, + cnt = study_result['count'], + time = study_result['sec'], + my_study_id = clients[sid]['my_study_id'], + report_id = clients[sid]['report_id'] + ) From bc9450690ba21020ffe302679cdbec23b893dbb2 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 2 Jul 2021 13:22:30 +0900 Subject: [PATCH 133/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20reports?= =?UTF-8?q?=EC=9D=98=20success=EC=98=88=EC=8B=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/schemas/reports/success.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/schemas/reports/success.py b/app/schemas/reports/success.py index c7640b8..b0227d5 100644 --- a/app/schemas/reports/success.py +++ b/app/schemas/reports/success.py @@ -13,22 +13,25 @@ class Config: "total_time": 518, "total_star_count": 0, "total_disturbance_counts": 4, - "disturbances": [ + "statuses": [ { - "type": "smartphone", - "total_count": 2, + "name": "smartphone", + "value": 2, "total_time": 20 }, { - "type": "await", - "total_count": 1, + "name": "await", + "value": 1, "total_time": 20 }, { - "type": "sleep", - "total_count": 1, + "name": "sleep", + "value": 1, "total_time": 5 } + ], + "max_status": [ + "smartphone" ] } } From c1ad81996031b70f82ca0289b59e35f0d73de80e Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 2 Jul 2021 13:22:58 +0900 Subject: [PATCH 134/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20reports=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EC=97=90=20max=20status=20=EC=BB=AC=EB=9F=BC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/crud/reports.py b/app/crud/reports.py index 9bb56ad..a23bb3d 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -43,8 +43,8 @@ def get(self, db: Session, user_id: int, date: str): func.count(Statuses.count).label('value'), func.sum(Statuses.time).label('total_time') ).group_by(Statuses.type).all() - report['statuses'] = jsonable_encoder(statuses) + report['max_status'] = [status['name'] for status in report['statuses'] if status['value'] == max(report['statuses'], key=lambda x: x['value'])['value']] return [report] else: raise NoSuchElementException(message='not found') From 75ad5f7ce34816cd39c4691cd90432b9d5bd81c0 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 2 Jul 2021 17:33:23 +0900 Subject: [PATCH 135/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20redis=20?= =?UTF-8?q?=EC=9D=B8=EC=BD=94=EB=94=A9=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20=EB=B0=8F=20=EB=8F=99=EC=9E=91=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/__init__.py | 2 +- app/crud/{redis.py => redis_function.py} | 52 +++++++++++++++++------- 2 files changed, 39 insertions(+), 15 deletions(-) rename app/crud/{redis.py => redis_function.py} (80%) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 5cfb940..438869a 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -3,5 +3,5 @@ from app.crud.statuses import statuses from app.crud.my_studies import my_studies from app.crud.reports import reports -from app.crud.redis import redis_function +from app.crud.redis_function import redis_function diff --git a/app/crud/redis.py b/app/crud/redis_function.py similarity index 80% rename from app/crud/redis.py rename to app/crud/redis_function.py index fff5712..dbc031b 100644 --- a/app/crud/redis.py +++ b/app/crud/redis_function.py @@ -1,4 +1,4 @@ -from datetime import time +import time import redis from datetime import timedelta @@ -59,7 +59,8 @@ def __generate_value_string__(user_id, user_monitoring, disturb_info=None): class redis_function: - redis = redis.Redis(port=redis_settings.PORT, host=redis_settings.HOST) + redis = redis.Redis(port=redis_settings.PORT, host=redis_settings.HOST, charset="utf-8", decode_responses=True) + # redis = redis.Redis(port=6000, host='localhost', charset="utf-8", decode_responses=True) def __del__(self): self.redis.close() @@ -92,24 +93,37 @@ def add_current_log(self, user_id, disturb_type, disturb_time): self.redis.set(last_access_key, disturb_time) if last_status != "study": - status_time = disturb_time - last_access - + status_time = disturb_time - float(last_access) + print(status_time) + print(last_status) self.redis.incr(__generate_value_string__(user_id, last_status, 'count'), 1) - self.redis.incr(__generate_value_string__(user_id, last_status, 'sec'), status_time) + self.redis.incr(__generate_value_string__(user_id, last_status, 'sec'), int(status_time)) def delete_user_study_info(self, user_id: str): - target_key = self.redis.keys(user_id + ':*') - self.redis.delete(target_key) + target_key = self.redis.keys(f"{user_id}:*") + for key in target_key: + self.redis.delete(key) def end_study(self, user_id: str): + self.add_current_log(user_id, "study", time.time()) + result = self.get_user_all_info(user_id) + self.delete_user_study_info(user_id) + + return result + + def get_status_value(self, user_id: str, status: str): + return { + "count": self.redis.get(__generate_value_string__(user_id, status, 'count')), + "sec": self.redis.get(__generate_value_string__(user_id, status, 'sec')) + } + + def get_user_all_info(self, user_id: str): study_room_id = self.redis.get(__generate_value_string__(user_id, "study_rooms")) sleep_values = self.get_status_value(user_id, "sleep") phone_values = self.get_status_value(user_id, "phone") await_values = self.get_status_value(user_id, "await") rest_values = self.get_status_value(user_id, "rest") - self.delete_user_study_info(user_id) - return { "study_room_id": study_room_id, "sleep": sleep_values, @@ -118,8 +132,18 @@ def end_study(self, user_id: str): "rest": rest_values } - def get_status_value(self, user_id: str, status: str): - return { - "count": self.redis.get(__generate_value_string__(user_id, status, 'count')), - "sec": self.redis.get(__generate_value_string__(user_id, status, 'sec')) - } + +if __name__ == "__main__": + r = redis_function() + + r.start_study_init(1, "test") + + time.sleep(3) + r.add_current_log(1, "phone", time.time()) + time.sleep(4) + r.add_current_log(1, "sleep", time.time()) + time.sleep(3) + r.add_current_log(1, "study", time.time()) + r.add_current_log(1, "rest", time.time()) + + print(r.end_study(1)) From c192cf5fc1b5c4725ac16111c55d6b0b208463b2 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Fri, 2 Jul 2021 17:42:50 +0900 Subject: [PATCH 136/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20auth=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B4=80=EB=A0=A8=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/service/auth.py b/app/service/auth.py index bad2417..68c7dd7 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -18,7 +18,7 @@ def parsing_token_decorator(func): def wrapper(token: str, **kwargs): try: return func(token.split(" ")[1], **kwargs) - except: + except IndexError: raise JWTError() return wrapper From edf1d579b30b44e643ba290cedcdfbbc7bd0c06a Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 01:29:11 +0900 Subject: [PATCH 137/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20=EB=A6=AC?= =?UTF-8?q?=EB=93=9C=EB=AF=B8=20=EC=9E=91=EC=84=B1=20=EB=B0=8F=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++++++++++++++-- images/studeep_architecture.png | Bin 0 -> 272507 bytes images/studeep_modeling.png | Bin 0 -> 228566 bytes images/studeep_product.png | Bin 0 -> 705227 bytes 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 images/studeep_architecture.png create mode 100644 images/studeep_modeling.png create mode 100644 images/studeep_product.png diff --git a/README.md b/README.md index d2358d4..3e7aa7e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ -# ML-Team-Backend -ML Team Backend \ No newline at end of file +# Studeep API Server✨ +[Studeep](https://www.studeep.com) + +## Production +![](./images/studeep_product.png) + +## Architecture +![](./images/studeep_architecture.png) + +## Modeling +![](./images/studeep_modeling.png) + +## API Docs +[Swagger](https://www.studeep.com/docs) \ No newline at end of file diff --git a/images/studeep_architecture.png b/images/studeep_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..7a8d14c9d75d6e9b10bd41806ed0b7f66ca7922f GIT binary patch literal 272507 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 aypgcxJ6N$3T3eo_g(~j11T+I$I+8 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 r#b%h*O%GhMqQKpjN4M^pda$=F5|O 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 W#6XMqLox6ZN*C3B%eY|j;Qs){7lF0_ literal 0 HcmV?d00001 diff --git a/images/studeep_modeling.png b/images/studeep_modeling.png new file mode 100644 index 0000000000000000000000000000000000000000..1facaa9406c306dd06deb5578ea7bdb008e9b929 GIT binary patch literal 228566 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

@i@v?v9DlO`$CKrg8kp+^ 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≶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 literal 0 HcmV?d00001 diff --git a/images/studeep_product.png b/images/studeep_product.png new file mode 100644 index 0000000000000000000000000000000000000000..e7b39da339537bc5451fb25b8cb17f5b782f3fa2 GIT binary patch literal 705227 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

v0{lUx~=&{ICG4vHx z2YYo`lYmVY@{{dDp1PI+W)yvbcDpR(l?JJfw+1d1r&wdbJf){O=8E%1oGNZX!F~FO z0z#JFPYm(rtv9zmYk9E)6eIUMu2}^mPGSB66O!9V##GMek;_o7{$I}{vQFdHoa=M0 zk}lK6L*uiHkF6063a=M~9)J{t4o5BdFhP5t{uJf`#VNG|Nn z0+v#=)}cdU0|Y(KapU;q8^5zz(EQm}%W`_*_u2qq`GxlmWG_ufR-gH{WD3j>Y4@hs zEDh8-|DJzd8svacIvut=ule#qzx9ifHJ>(=-p}?N8?pcrE2-twL)StNV)4$Oz>-C{ z2vBoOW4ow`7C`5Iqs6PjcI5QAH@gfi6jL>2ddK9rnLZ21nB{%;qXq>U#WaGIFqH&* zBdzI@a_04mi5Y+O4l!M-&j#akkRazD^m-dgn-zn-}F?PsSkI1VYh=JDBZI|?lT08K#GFM%5 z=o#+_};3ziLuERd>3Oa1&C?%Wy!(Q^(d?b1rm{^Y|x$c zQ|LT4u~M>8oGt>>hW_UQ6oJ>UJ8h9Y)wV%MKLmE^WD1uwkrk?k#@z5EJH~wn04i$qQxw}hh0*F%RQo}`DHYt3TT-U`xfaib>2c>`VW&S8Wp1KO-U?v z=rNUfmUgIOm7Gw6w74|Jw3u6XPE{~W{^(|nb?AZ1H~UfJ8-p5fVYeVybn9rwZ?cHi z`h`^}P>jW8D7d)P1^2OqpW0nXOWn+>tDk4x&)-{1u$Fa2Yu`%5H@Y;y9t%&Q>CLKG z#hJ%s<64K(M&HmWy?$ebBy|5~JLj`>*FpTO$KYYjt-U(xui&Xfr`)^c@Y3c=hm&Bv zPr<4!KJZ`KRJ?q#<;%{_-Z5V2)P^`EkWc2M_#X3xy2lW$KBbbwdc;7e(V0-U9U8gh zi2Cev?{?9&cj`2G?R4VrKL-A#t(7DI*5d+0n2l_V6HUg&L2-V9Tra*XimWUG6w5j>Q zVQQq3bv4y*n}%N6v$0WE$#N*<)@RzObbm)tvQPVrA7K7N1R~unFl?D7Xx`Fz#W2 z>K&N(Y=NMQM^J5%f>p6GSL5(}14X=%)hMq0C6rdQ*!&rg{?9nu;#RoKg6Yj|H+ zWRv?V^MkTPyd@3HAyK)p&(|agfe<1*WjKrw{)zIQinl8@Uy{yghS5(K(VJWglol8C zn;;$;&9VOhHnTs&DAelN6A@>mbre z&1BYCa!h5hC~`8zfW5YIz8^bv3E_&FLgLvvmV8Uft)g?=V9_g2+5F}0vEQbx&tIqf zrssPTkK>T|%M?3Q0rdG-{WI3)h6+|!s>jiR16R%HK_9^m&N`+s#GJgY=DmoVhya8VMP2)rap-i$ zU`dp?E}0d1^QKb$q0}FT9kRCietW7_xC{^G3OGSA$a^sL`k%M&Y@S)*9N3|prRf%w?f8JWeJeptS&c>)|&OyAS0#k zhyyZw-odN~7rhVEJ68d&QfR;(_X>+6?%&c%J}DvV#YMFwpT}e_DS=z2C@HZL)!Bpu zlIRZR%yk`b%2&}(co)3}-SK&uMLz3lKQFmsGT#&=7%dIX3Mu#~m@6w4veb2q#^e7$ z+0*(ggkk{+0;&)(M6cvz3tf%6y5}puR$59gOEi;Bd1m@?aJd9#mgy?19HKX+mIWUM z4Wg$CQch~+)XXXO3>p>nX8xaZ$}=I9z7!Q|ldFW-iP8F?fe0edRCeayggE`{z0#EE zIThnXFadlQA8_(Jgb3A!;UERlS|T)uS_bZHB5< zZM~#z>f{cKNrRcE`zxk`O2&s#O~tP+UgF5g5=4HMtD(?gj6hFIp~};iG?h_OhGZL4 zz4aoAofpDWW=-P12Z!0YUtT?!J>1x~(m(?2mP+0^C5q%K(^<5J0gNF3PKOTka7 z&vldcIk5xRWcOjiOSH9PF(XAxzbj3Rrx0i#a#%j~y>Hf|oPM1gW>PChaAVI8N!9~z z@-<(crbKR|bAC%a7>CtM_RTBSnfpjAJ^SUa*EA;$CPLVeVeI%d2j zEaVK>oF%UQJdNRZp=wO1=)QgF*D}HxNNp%5yk;z18w5OxOcT?I>@X(Rx;_g;L$R%~ zIlnZG0sIG=eF+$mhT{X@3K7sYR|Z8F{6?Ut$ko0hwYC2HuFX1N@DQj1iNVdE-`*H$ zO`)3ENIt>yHmeR_AG@95ak{P$!ph(;j%+f?!wlS)?8Y6JtGx|zFAQrR6F8B*;2R1~ zd`&Q*Z_qa1Lfm3;Yq3uhcYD}Kp@UzD99cG<7xBRn+r$$;L*h-4qQ6-hGUWXE9vMPD z^kN|;Eb9|IAe72L4sa~$ELbHeENVffg3QL|qq^J(W7{*CFG$7| zwElOgY=RAy3VsPs-I$c)Lf_bXW)({N2FKOstt%*0E0}7LxI)d=ov>fIA;c(T!1jW| zUo7sabTBqV%XD6Kvtmz1i@eLP7D<<47y^GRuntbcXmjuhsh)Z9p@Kmwjc96RZpNQv zmlm7E!R3W?LI`gT;n)Dl;|pd{^jT^qm)a~cESO_KNb7>z(5zm+@Pns<13TC444;F( z62fOzYM_IPZBK$bYVPCgfKm-9IJcY?<0}MgRjint@*K3y!uB4XXrTL{TV9LTQ;4vr zxE{sGAnRXNx8d$8Tf!c^fep2dtVz@Tprrlp0`ynLpJRIu?!(-kJxOXyM2oH?d|9k) z*UL}>S?4V&{o+yz z=Tr7Pj0yT6`n0zegy&d^e5kXd*(z>p8!{9u@6_}axTs5Wr&P*AC?@xe^>LIV`{Z)j z5dpkinMmN#V+2S1dtUjPm)w!}V34O0Nj}tr{~0sDzO2x~fMS@U2(yMqk*<%I-Eh{3ajs5M+9g=WW8tuy5oZ6sshV>P5_==S@13p`a z_3uuso~buzFd+)pDk#T^DOckpWalil_d~u2K89_if8?@uEM^<%%uKg)buhrb%i>&d z0ID_0taAPK&R_**V{8q35^t^RZ?V`Eh7%moe^SN$1=5hSTP;+s(sVt!571tV;^Cf;7V|T zq!!~fJXQ0Dn{-1=(zgJ8A4A|-@?}2H`h!HuUf%9elKg%ONT*{gX4#hOVRpOL)->mB zv!@t^v37`WaJu-U&b2jnD?QX0zgByG zp~fM0Wa&Z9^M9jn`@Tp8N}6R0In(8E8`fY2-tU@OSX#F83JPxQZr{cf*45SBHAZi2 z`$Eg|5BWsXTEvuhSSv4$j(@h^JEATRy}wPVR4V&O1~oR`Vg(6gpvG7#yMXw3f;*Z- zc;1P<%n1~Uk;WX_jrVveAppz$&F-8mh=8Z{|a_c9l;rh zD|n&&xnZ7a$P^B<$UuA3F9WNz?P5(*?dK+ZS5ah?1Pi^<|Ny zMfA#B!I;t+#*1v*k%7j~+!F}7Hnc83E~mG+%T9GJ&pczO#TEyxa>>2wRJSUOu;_Q; z(|_#Rd>yrNsuV6-yhw|_{nXxhEe|Sf*0p2jMkkM?#U0(2RaNYuvs>5zv~V|K@P20uWTE ztlijZGyABG`l>4P=@dWIt)LD(vu4MGl0)`|B@tiC?NMzNRCta>moYbQtnrJgoPd;z zM!SVy?^)T|+ZUUCuYb934l!_X;fE8_ca^=a25PsD!;-gnzkmNmR8_SBu{93~;np$x-I= z1;OW@sIX-_QT#htuVZ2LF1fm;W$!Yh`VJr8_>FDqHazIh1#nF)<^DD90vY@#&{m!) zb6)>Fh-dz{Pc9!E86H~24ntQ^B{9CdYZYI-KODdH4n63&nK+H8^u`rDXz=zpz?t^_ zV;MP0{&^+^IaEvQB>iNX$cN^!1ueq&2Ai|li=Fw|JVpoGIIqtM|FdU9$o#+c^jyDt zd(^SQqr-$`CKZ_2{5c#tN)xmv<1bAcqrT2nue`CwQ0(t?se$3Vt4?+KY21d9#>#Mp z;7bD}GUG4YVbN^+Jm55bINj?-z{N2TLt%V)F68$$4$1f$P6`uGO(iKMgQXz*=J zfh-OlRVYKTB&f==En7%v+BqMsIGJXW@>6@rkI-ZV!)q9|GOTK<4NlR^wf%txWaJIHKnondu^$r zC=Xk7|;N1>QG5~*M&4twIEOFSTNZXB7P+BBFF-pvI z<*Dc&BPvBh($^wU=^o9Do&hnLj7dKNqo&7$|YyHd) zu0^(eH-V5ySK+ioFoahwbzg|h&qXAMlnXbv;=a4QT%B)m%A(stMw)O5&zlSmwJkPw z8Sj-rz9?Gqq~7E4X%e-%hI%vX?d@s8U=eS+<8t%!LyF3jU;=`Ic@-4|>gwu#M$*!c z`s=ma&U|j1BBh({k`k?jvknW<;`%m1S=O;XCjm0l~>-$FE={x45(> zg2ZzuRxLKC5B7?x4mTqEvvnLx4gwi`P2~e8hH2l}38Zn4G9kRNfeK&XN2ummTV9E= zX-PiO_u{)ghuIoi6qd#7*RN;ysfC>W1p4*R=h4#8DD1WRUAygj-Y8}~JR_dlrjkKN zb#=wn)0G=kF!}lUDa=4xUb|cFB%q=K=uC|eP>9cm}7CH$}wDYH!#+8 zWuhHWhb|8ubhu18NsrFiDa>oYX6ZVt$qEzzO1xE>MeIjvNPQV4|d4! z9h^nvg3un(-5Z|g!r!09siZSpVLy5H?3v|B%C>_jelq3w+dE2WY3_(vf^NPy2EtCN zikbmW#a|i`zZQ;IduP@WP2t7BG(o~G*uUJPg3dO`{|h+=<;bwxu%)Gd@e8mJTLqg_ z0Nb*jiN%4oFG(<;nJV<4g|sqZOhw z%iVewW=0|xbt68}Gxo#p4rx9T$kD zK09Qf-QC&gOE&5AZCn5z`S;Z7e-)Ao@}^WHU;aujE@o|sMbRm9R{ezm5FTOKs9YLf zkbpi&h5Knre}3*otM+v{(Mc2wf{ymJ3~L{jvZcg%0o(~qMMtt&CDSlh+;nNSX2B0as^Z1bj--@Dj&X5u zchbh(h}G5AnrV_)UD?Yr;Dn>Aj#AjrEWkjjkN`X)e-l9!>r zdZ~7VMvlL*T{Zb^=`BU~bsKH7c40at;BghalJWU>LPGH$q!mG7uo^}>mBAD9?PX=uc9E9S7^lbkirx5Y!?zY%vK}RmMNOs@KM4z`Gi*Q3 z9g|bRPI|pa)wXV1rSvq((AeSFBh9HHw=VuSY$V`=%S)4pym)l|1~5Xj&ju`R2j&*gDIz83iC&9jQMPh*)zeUBvg_g&5J^ub za{B_*!X8fSS_Kn&UOu8yKZ#(?soPtXy{K0v1aoFd25wpqklvV5$S-*4teeE3Ke3EC zanrUK&(jp5{6_?}`Yso>dM7ErC84k1>#vzlA&N!kb>f+tjT&4;C#P6Pmm=2g)r4EB zu~|F?PT9iC#paEM;~8e&e@2JdLq64|27mBy?VbGGQK9o`Eo9Dh8)e$$y^U_#_~Fy( z$+}Lx=gKo~T6)xWuDWM-`SiGUd$K{Z06(J@--+c^JP{9&GniPM*GeMfyjW(U@wa6( zgkbb>*#2inN=<*$ZU;kNUgiY+&CtRGh!?J zl}u9AUYy%k;6`kT`5w$S%m$dAd10z;-#>q>czQA=n1;+lPXq3(93*I)qoGF|$^lda zY}kOpSQ&95odokEm2pJtmrFw?p-+-%e13DG1FrHQff)ut4g(?ftCHI0+kG4hd@{=X zCBTkb7Ye2OuFTmxH7a#;Hlq6XXq=w<`YX0%)CY#}&;iiMW*YPn>P~|UmcK6>;Y)m(tDz8io3|vut8pp4tzDrsG5qs%}j$1YRW z@xie_C<}ZJv3v4%Sg6Z5{e?Hh!7JVI=YHc}&tC*esecuZ{#jAO^m2?cF5}0mBt3As z69n-G6dkt)RPZ8|G6RM}R$({!!cHXL$C#=F#5{p4E?vxX3&tQlI1!A&X%frj#VEfC zO9>eE_^)1<=uzU0m8P4$!?Y`)25HJfCMaAONyT`?@epE=|e( zSdQYbAJWT}ICk;_98{Z7^@wicbj7yil~5I2*>M3h^PpRyq#ZM)p&fGoneHV8baDU% zkn=Z0KlJTX#F!|6dpdE+IjeF1>VFAo&`tYJ2Af#ULMPWy=(QqN=19^(8)JgyQzZXF#y}K;VU;$gvbm!OiOPF+r0cNF;|= zmoQ_{ZyBaXY3{|G2?f7fE~xgLixMC0x*)36Im+YC9DXP2gA3L79J(S+=3LySJcmkx z^dlFzL}})l@w=abOWv3Le5~l@(793}y60SqT&}a+TTF}Zkf^Qq_Fysfy}(=ay{B?& zx#n98+$C%By_avg-qCCFyT;3w@PAYkF6#2F^iwlMiedgG2ewa@G!v@765n4asXh-R zp{37?N=Q&>1+U(|zRtl~3u@U+-6V-g`==|hucsPYE^vQ=7gp*9aD*bM5|Mci1~@_T z)}g5J>T)YI6)*xE33mpjln24hEMq58_ns=8dgdj?F;D!_qODTAkyDo+)ow{r^m9>U zj>%HrGBYylE_1^f4U0G#bR`FNjf(P4RK9UC6#Qk-3z)<>^L=hL!NY|B1|+bpUvFQ= z)b&C#iMl2yCxPqZ3Ev`Vnq&~95M2HTr1GFC2V`h>L(SMQCd-QUkIcNDwI9XVf`Dbd zM8_8v_67rBTogREqo-3mK=A{0VIj^0G|gVffeO0*0bFxSBkZMR>Cknv5MLMvP0ZAC zi>;1@ur(&LMs{3ea^Y%RFJ}GaVk2?YD26))Pn&}gy`0`iiR^t(>G77cA^nWhI3mSWl=&xjD;Ax!al37K0Qwdk&>lTh>uT7Dxx2 zS#R@w;7{y4&@5fi_h)d@hmzqi407H<^{sI8J-=o4C(#n(8+A#L+2fqUT&?@>KSp#C zBWcN^{*axwGK%Pbjr`hlsKW4+|@#^;Z=l-6(qE_FZjeFA^yZ1q$$$4_S zdG2_%ld0b4Uf%DaP3-DqJo9R&`trDw<#1)3aA`vZ&;gNAveRRpU>!TWrPJKQsg}6=Eqi7=J;jPp1fvIQf&;;*UCC2X+`0;Cw0>M*7?=8H$%SvmLVaB>{iCZ;;QCipo=FY9VRKwbC z%|~s54+IrleiptT!wR)mO>b{=z@||)|H2s*U6q1LDykAM(>MQ`49S}mWssPlz^G~~ zR-J37ZkPh5PXi-FBZ~(kq~QwY*5Tevi%Y~S2a{Nyb*~cg*+S5h*(NI!6DINV8{;m> z@aUNoeVSU_d%`~JXR)PWCmFdZL~$}XUgz`W3TVHLB`lem+)}cRR++gkdsUy#r7iR; zpP&2LV8ihicTpn7X+wS985yKd>6O+OdJW}Ncz&a5lIp}0mAR*-f)rx*ZX;&Nv0rud zm4c(jUh`K{ifG2{DfTyM`TDSn8AOpQn`8UPGwtKYi?UMvlv zzL6<*c4H}=Cu1^d@f>!~Tbonj$?J=1X?z7DOP{3F?94`Wh*4b?2P*nzx-?Z%vfLQC z1dr*7>;3LqAO9k;Z!Gtfa_3Lh+*H`E- z$S&*!*f-RxU>g8zSf>pn6zU_8(W8x1nv>iF=v(Cgk23a1ar<;q#=T5&!Rbkz=KiXY9ffO!z=cJ29(u}yXTMhZJSQX||yL#U0& z#@cLf^DvMSF6H&sdS8+Ea_x-DZW5oUyp}0e{k7$bG|*~T7}-pbOh3D3+Ge7t%;S%j z1Ok=e!yNwHj*gDCbLak_Y$d)X$K?m;gVR#-RIaZJmsn;E?g&PkNB(k;`e6NPxuRvX zX$1T#5hc6PAMA(+?-)gMVxXJ{U?es3`xNxay$1Cc--xjeuW%3Q-Km(>zCHcQ!s|Qw zwjOg&PIdbgAr(x&)Yjb#mm(P#C}P` zSKoNUxMVOJSo6l?GC9Y{tJyfJ7m^;(1}8PVv6{4zQQ@w23e&b>%hi^LesuKURUE@K zAnht!i#-uj85=bNoZ^ES{XPtGp38j9U49&k1|nETQe?awEVE->kG{8zz0UY+`GNu{ zDx*62Po6G0y)7aGin%S$wv|VWPw8h`Q28BhMM0~$Nv^h{;)!0y*(w^9uQYmG8?h99V4i+NghwM+7|;wRc67W=C_dIm)w@lB=~td)PsGCcp(y zee30N?GePwS>n0co)}>Iz*6twAe1d4*)yHLeuCX*x|ns3vvv}>Q14PhxEX)8yfeel zbU$nD_b@tlb&xrHw6qjBc!l}*=D;4<4HQ>5{Te>(yUCeT$3xUpM?1gA_nPj-Daq-! z1pWiv~R};^Ppm z$Y8wFQ<#CC7Kfy2^mBo|#gArQd}0s3bxi-yf}?y24U#A9KaqTO7REsLBUJ+N$1OT7 zjOLsFpY^a%pt=a4lezv_3A}w?r%v=9F_FNd>fiVX*O^ax0nJBv zVxOjeq$7A8rDFEi%1)O^eDkTMz-s>TN`~|2x%|x} z-QF~irr!OD$Vl>0|1?92lT=uAkyjq8{Y$~?+2`}!&yEB1BQ9%Y$||uLC1Qv-971E` z`d3;F?VJv*t4S;L$9h8kIeWQ{aAGtXF5;El&AnLX}KM zCAzM}o(qlTG`9k}F?55ibOE2AF9#g(XFUWs*wyB10VaqUq*ps*Y^)_>t|5;Z-iH>h z@)+)~q%bN@Z=Im<66~YLh_26WrePiF7nryVy07(a_y(@3X)ZPFL$tzao*Hqu6qiT2 zf0S-6lQS#L-RC#!ol%S(pZhKl$zj*S9a;LOc~E$f=e#QKK`$jLiKTRicE|c`MVvyf z(dD@35x0H4n=aFLb&#*?`UFu$)?)a(VVY%Q3HOB4`59U7hk1)8mlf8{&gkx=G58vu zVBq%i>{bL}rMNHYp=oQBhExFcQot$Y!y)0)YGA-!_AzbdU(6-{OR|>h8+X6cPQ|O$ zd@tA2{dCtgxXNCOX9o}t^iRjK`FJLguNv|&J0h{wD0CyKdvI$nyVME@Q6^~iO%jLz zobOHA*Iduk%xyF4?QhMu(}=XuqCelK2#^n$!T+=K1UM_v-}G{uqu^UH61F8KjY6bK=Tf2{XRW7dpwG%4dYo2z=2h?vI-M zmH_)w^$*pqvR5pZEhK_vgArwjQTZfIejY5>acggC`*_;t=ZVrs8 z9@OMCp9Pand%+VT&o}yrqEmng;92v;+}p3zl?1l6dqUx!B3} zIMr58zE=xJ;&QUHOc0x9oTWZn(Ts8G(SfBj&6;-U7(6vnHr88n@x|YKgbkd>;0i-! zLp=+r^PhQ+cqMGN`q_1>V|JSW1yb{w0f#|y z1{U7W_rzCV^0F5Sn%el2D6e+*_dI<+30LR8yqO-=4d0k}?x5oN%Kpd8+133jiAkzK zEkT>{^ zK_IWzMLuCI&!=R?27*y07OTw#pA=|vBlu*RiK*)`0f&HSM_r~Djln6+FQ7X7ym-WO zR^wHF@F1O_gIzyj1ueSJ@^x7wnOhZH)hCuyYC_El=p~Sh6fi8wCDP}ob!?ngw4_9% z1&A}-kU#iNO+~ObZ%Jo?$BKd3$F>c=A=9qxLQBb{=kRadt>61%R+x9e1ps#_V|A`u zklPrOq#L=#84F`W7FF_}*15PsluK#r z>sz0u6P&G$wMiO_@_+0Pf9ks4LnrR*2e=6b9jQ9E*H|Bo^|kVL<{6B|0_B3O$RfY1 zbRVC*1b$W1fBNwO2cKyG=HcjBZ0Xh3#_rWg zbmrAcCeP6tq1j3}eQR61R6zXS%VGLsDXE8#e{VZ3jUDbUFU?lh;ujU=<=Hj{ecS-Q zaH~=A+W*2x`jW9#=%z*Y;M7QZslV@1{YVD{15lu!GHf`2rWqfBd2lE7UI1;^RgJ{! zE3oeWX*$KB34eZ%qa3J#DSU==Pofo`8w*AulfY@Lm$U8gcSix^GlBjm8E)E)dEN?m z9*~}rSuDmYnw~DF()|d^mkFs`D)FpdD7T!SYRz2`#Kj zS_%JHZa|bm?pln2dxVTK(=V~rnifhTZ={qiS_dO(yxW;}Qh>FNK0o@}lz%#`PzvxHT!56s0 zqsq#OktHV)Bjz9oyxQiw#)r|AxP0Fjv(1>Mo>vbobrb;N@k!w%Us4M=>-Q~A`7P}Z%wFpjTyewM{W#yRPk|1Fb~qsZ~4M;Tr4VM(NLUzWmCBQAHAqJQ`(YwbW{gisUd^vqC0*{Fm^C^9rl}L^qNBP0&Iq%5j z>w7V8!qRtfdjP;qu-X?XA#U;hd?G;H>*i6mlsndNjzo<8rhH!1m@crQS5y0ogp&$H zW2Y*zSCXQ}^rmv8;&-Q5P2`P{u@pS3T`I%NUkxgk7pAg128FV_Z-qWxFNRq9=0GarIhXw1wYykkN!SfOFV4mn5~^pnT6(53Xu|tJTLy5@qv2 zY?;;IXLX0lJ|{--eZ)ZD`Z!s#}&jH^SV;a-1Q8rEaQx;7;1f}+|JBxGA0X1=$+kh{Ve58CpGKZD)eq&1ULcx zT)Ca2eJ)OI+Yf!8$EltoomvV>Df+rZhq2pPm=9tE|C8n>-S3OtoY^ zp*DKfcIf)SU_{iL5z}Xb0S7?$Wv-k)yCO$Ll(H#g7pv@GjMOxkH60+bk!u9@JPI25e$76eaWLI+-fLPGpsm{^2DG?om_6U$D{&*cpbsTi4H6*L?;2$Ah@bUZzn)Av8|^96cSkjGAW%X>O{I6nFsXWY##M9eKS7&O1OrZ(l!_;%*?km5@C5|MrspwQ&NFci?>@3Gj#9KLF$u37E&Us;kMbhLh2f z33wm=_MG>-$LnhxdSk08`8LDX{CLO3oB1-YehaH&?^%22g>Ke#9X1PfuuIJ(iK3l} zYuONPcSf+Qo3FU~Pl{DtFD`Y@-)l-n0-rLVJ|stz!E*fTs1sd1Jwsu3osO#-b_ulK zctEo^201(w(APD|TZylY&;W9w6NCKR1sDLy2Tjr}t)Bo`Zky4E)o0uFza7}6SD^#Z z*8WO)Dir?PWmQnT^Hef+lGid0k?-BAAmuE)*6rBLSr8G0O$J+t9L3k11F<*BLVcD( z-`K=3_u;l%CBq%B+_61{(k%_%@TR|R+`)zT=q2`c>iF97h1?h_qp2+BL=^&8Y`C6* zEohGA@mB~?E7X#AeJf{uybsyCTD9`ndcj$VC21yeU;PP^rsRbkB#;-X$&9E0j_6nK z7F^sfg46-3F7~Btvv6x53pWiNvNNAwblKEcq=9f)dn^iyHcZnlkfgs^QgXxFbT;5x zf_F5d<9#optlb>2&sfpwf-Mx0&b>BhP~oDa*?f9J)^yvacX8`ZCe%>;A^UXk+#V!k zy3zD^vef(U{?yS*W94ecrD@_Z-)6p7gu&6aZ{=Dw;Sy>pXAvc2rUcpzcb4pkUkZo| z47kL2IKNN7`m^RmOiLSNjl22gI!lBJ6%BOy1UKd9KLH3(RyMYkkc?uq-ARCJz|Pe+ zj%7vw>#>UiF_8`Q06}B`Q_vaBe)5Pl^cN&F?FSt!sR_hZ*5JP9@xgqXg9%Ur{&myD zXtMar14I!dl>L9czr6sSn$`n?gj$-KN*0qE^pQ?_gJ5n!5a(68dN!)dg}=ghfB9*> z)U&(#u@37`oebHUK0kW&@sYBewC+H?y&&C}?ME+nwdFQUyP-+k2HLXdUP)80Gj zk~L2ktTVVGyih}2WYq3j$c6pRH_FB79qkYy|Jq&!bJpHW)RS_uX+5)#*?kTkX@&U! z?XKo?Y||4dZQ?oMg2NHAAz-C&41k~&t5@cK6fmE^Pc8yxbIOrQ_k(NCsyZ{(n)R7x zyR&86p#)2c%#C#}dth;c<4?yaV`D6>1@E={R8qj&8eDN=MxNE}Zw*vJ>kU6<^ymy% zn7@1J04RruWH!Mv236tRh6KLJM14`q{-FI$^O#r%lZa>xDX(XZ>fpuz{>E0=g`wrv z`N*#Mu8>y82hqgsq|o4T~SzSSlcI=JzLJU159>GPUO(6-ZL`{lJ)K_YL6OxZR`2NR{6E*DY<|P&kFv$NI76Kysh_bG&)$gY$F<{qtnRO^0 zHpj&~w*+Y{w#I2ljvPHuJ1p!v+)zn2lmwOE?sfe9=SQvX4lkwmVYl8qlM1-S22}hv zcSnOP!mg{290p=7T3jB-Y|M)WSzB1NS(EiX%NW~g$%{FPWXT@6J}|0kkMTo|)??TCBKY~=DAay^&KLAHc(L9#6caC(w*!g^(9Bi{K2)8``=}() ztYT3zCz-hQLR5Sr_dN(eW=7)E62Io2&->RWiuZEFB~!{|4ZfdNa*HP312cTE*80JY z`kj=+Gdo3h{8(Lyz)k)H)2jf(_xYQA7QSG}n4tHOV-4ZH%B8f9p#c$P#LXGk7PneA z_r=TSLGtUtXQ#{g`1)4Ie64lCay5Ut@9BRS7`g1OJYvk+glWt1xK-53SX+`6ttfPL+V%MEik3`yt6WvlS&f;(x{(UEs_}~g zJ!iKhcR4$v6(C`YFZB%Y3EoewDLFI60ak4ClZmzOxSJ)sw{4G&CHW#syFVS>DVG%e z7Pz>EOX^oj<|pd?(|Qbsmv7vYYVxx6fIpbK1}>-Po35v^_DSD9oI?DLCOPD!+H}L)1ug*e#9$kk!ubsv(u2}B$Yb>ql40Ss!bUSaiPX?Y- zLJ*QjFEf7>gO5C4v;w^><&NEy{yp+7Q?uiYAmpMv4e(^=jta0f549*|X`j~02rg^A2_P<_4 zpyyG;G&T&_QBU=ZfxaCqABcvz7Ks;Cm}Ux5QWMn|Bo#LU4L1`FISdtiO@I>w`2Ykw zjj>dLdr_J7l^#<=9FU3DkpI`1XaKlb*eNG=oI&UA0M5sJK+6U9KFSTZ5ROz}dD6%4y3ba;9+FE#iILa zPpGlvfg&d`&kkc@)(}J$D36<)zo67%S-@Dsi2ugGi}_wpR*6$A{%&8^`+QzK#ltLE zSrdoOWE=1RN00iqWSlPbXvF_AF9zIW4$+H5;Wiq%xW2>YK2KeB(2yM3H$O{TzN=ub zD<|K4n&A>~DVQ}^i~sH>vjHVKX%a2FpZd(Q($(Dl@y++s5xoo`SEbixC{_^&tf|um za!a8)+DeQZXpqRv1PZc(vm#>%ahl1LgHpoi|iORqZCTLSdWjl`IDgyb&gu3p#$^ zNS5e!HKsg9QcdszXw8xw`1q#^_AN{W#gFBu3a6kTcK2i<4ein57>rSAR>o;R3#;ci zjA#kNb?cuhEgSgFhAWBX}TAYWez+c%^ONw2R@A=@=X4R?Y__-?gS5IB|w<5;WbTZF$xQpDE zZ%q!G*yqD}AUUeu1TcB5gA!VFMO9-7R>&aanO*s^bx4y3A|La%amUq0@k!i;V@IS( zxv;=Qi2Lo0%gPZqkPNUI)rUR|&BtuU_Njc%p4{fDC}ktAzi4gT&Z>gP+Ec%lwCnBqyNr z8UU_>x33@*;~vf=#$HgRS0jN%CXa=PZ?P`jOFE}?WK?Zc$a%Xw)1;zNW$<}$;%;|` zH##|F^1r;BGv%@>xwM2QQU-5y`#Sz2 zk+<{6xqh=nWG~y_d|xxNXP&}*Eh!3PkFfb$3W*D$NE9;kC01X3=yFUc*6?&Z0MOwu z<=4J=cPnA{Cloum$R$YNw>hX#JuB!sej&VYFo2b7`<2$IkM8?}_VafiG#A~8IVQW_ z6n*pyzm2he1k ztd1m5N0-lx8e66^hkbkDDe;48@?;cC`K|S*YetUw_@e4!R07z*RQFL%(fb-__0Lj# zGX9B_tI;*)JYe(&hJddet7s;|RlpGWNf)**23}@#GN#2q{JD6SRhbyD-i-pGmD9;; z601;*iB!9pFCk3^p;`VtSMCn;p1;SconAv3&a+ULi#&zA8F!{S|&v3QkZ zZ<~XZXL-!v;@zzM?#j03|N_g@ZnQ7gQa>@fAxPL({ zgHl@*` zZ?qEsElxm*SHK^zD&XZ`57eVHwn>c0)4~kvS&ih7K#ML&&7vhM*{U3DKlp^Ewr!3< zP&2ix`Hpte#p?;drQq6hh2XzFrkCJKg2Ppb3T~Y*%Rtzt?8T{~w;9Kd?KxE}=;{um zN%_alI)|}t^X-nicf11T1h{36Hgrgnbt9taf2_q)pmmnx~d^2+;N z5lG%2N%&oiHpXOL-K||7VZh6tnFZW&Z&qte-)Jm#Q{)6j@U&iGExl;DPa4w&E%}}E zw%jDu`6DkZZf&i|u>oKDMp{QyX_v}Q#iGfZj+31Gh+AHASOl?HWxCTGCNOgHW1x zR~zFGoUnbxql5nNqrtgum-9aSEU6EVhY8MC#)1U1mZqXqe1E<)baB-n;ofs|JU~@t)2`y_m=fdzb}#q<805^Aqetl#L5(v`&wbNNdR9-{7p2YS-As z!*T1)RqWawT4|(FKY%r@L?El@2Iv#*TB%SO#XNR_U}p}E*?};^Ug{(%T^U6;HnDj^ z%G^aI+~Za4NHDRq8yjT$NeOjxO@ZUdBu@1nmed~w=yuWS=kvQJei=)7=;sYO#;bFC zfg|g>>;pKzD~U#umWY+sJSM?lI@saQ9H37NPav{~RK_AZF4*$-dvm8VsxZ`MMyIps zE4MXLBgh3ctOH^l{B`vCGpa2|QYga|E=;u=%*lLniisr!hMfoEEV{Kw-X|$)CF z7e7b0g3pCfiWCm0s+PCezeKBxNH#AIk#O02;Xq3s?wrN=(oKSu+0OhX-J{fZ>L+|{ z)J;Xd<+FbP$<6PMB{g6Y@tISVEBDkq%OOH$sHe`#_oc<+N3u}Eg{Gk4#lXyCZpqta z2|s4J-z-9uhbyNV&a2VG{FYEcz&cDsrRS{fR!UmE0kUGYdEsVmJw;?rNoP$VD?u}(22Q1=%Q1eVa0-Nh?W z>WvKspvjezoE!0}s!D2OSg3=2E|mB-K70;>z@ata^_?VfG5ke?o1KB5e0^#m>iqa! z{+IQLd*Cj_n1ro|K!K1ZSbi@j=n0Tgfvp<}Ke1=*ds>@Mv_l39E&ThNgkLyx0%fuj z2&6<6CN`>?CpIx|44TARtCXZ@#sK$5shcf^U>Lt#Rx_ zkvk>b11yfNmj&DP?yCz_K?1ax$@ECGx8h-ecMDYRX9-GZ0mRsZ_sa~wG8qOY``+v9eVw)DSR;6HY@>eQGhZE8 z+^vSYOF3xOVDzc~L7uzD+A94NUw$Np(GdURKD&u)Hxf7NuE{c%d zwtlFvcakFc?5uxQZy``Y3(1c9DP)v(yeqq~*#@7hG4%Rm4gDr?r9gFX@vW+;#;E7P z{^xzFKWP1_IhaKaZ2GxUy_z)Hwc&=5xkGLXGhWMTwZmI5=`53t83sGcuS+6aKYwi@ zq|0l`QbKlp*@_ijN!dzn>obBPcH0nDblkQMgxTv)1EQ4*Qyte5hzu8nVI>*W%VssD zp+_*<(*QoWgSMvI;8fAHuDsr1K|D%)5Pg2|XB-u^>FYit9ssLijSOGqWB8e`%?)j^7r?X-s{-24FCr^3Z24|4$)+(yxSw@3m zW^z>0c4o`V9hpjgj-k_Xahq#tXUJ%3WB-sw1YP~>(GfFz9in1j=95@NsL|NiG$QAVRP=wR8Iu||Dc=C=MLMLiIOC-`PY_q@* z5#^>Yo%rgSnobSDHa-Rj4%<6FRJ6t^1<5}2JZH?qiY}D`H{Ih%g{sD1ayPw@GSu~( zn4!z5y7gO!UW^$C$YB~4voOcMzvzp$EhsE)-ebH zA%7ZEfy5BVAfpqos29BN`-8A_E$wRuk+GX6^_~Ap0K27w-d{^AHAb>WuxKn@^R|0# z(?f+r=3DM)FiCi*5F?#?=a9>?dPcDkUj*N-B#4?HT@XCEau6!F{4?KV3U>TM9fh_{ zWOfLN&Jxl=?hvYx?ZNRYa%iF2pDtx@_YS6hez=8kJ1}j)BF>T>3DNrB2OGuWMmqaA9vM$Wxq=`=C?Ghr0Thc092 zt-~GJv_pD0)3;<%&0?_%j}4apD2ga1_=`@sXl5P=LVw}(Pr6D4T;ueOZ2&ss)#@5~ z)%ZDmz8XTl{}2+7Z`yP&N7F^bYCSah!XMJig<@|=9m3V%73d{=Fim%{x9NI7aV#M6 zbwGCJAH425sI9->^`EU3hP19Zao65p>S=^s=GGogYG^Raqb;u&k zDt!q)>ub?XFFn|LPA>^9&IDACFM?X~=@$cQ^nQvQx`ig(Y8c)K=Xlxj-tZr*i#RY#i*GjMYOx{@<#N-T+2L_w^~4BYRuYc_bF0zbxYO}2#sk@`1tHdu2=Sa ztFL8#fp?4>dtOg>=lBs?IHMevYJAJoC~tkVEyr- z_T-J@{4GxisLm+`oUr`(Z3fk@VoTA7EH|X~hv*Y$6VU#9B0#jGpo4QOAUBENFnkAK z!XW=h&nX1Z-TL5~JHg;1l0j(wedbV-b0kOtIniZi39;6dH5A90<`GD!lT-DRen;|q zeN3f|b`ogQ9z1>BTSV~<{hp%qpFlb{@oo_UQ+0V-(M*NDe#r7SwonKS=wlP)S{oi2 zl~|W|Qb__Sk%rRUkl6L7x`O<_!|((5>yS<^S8bRNLSwX9{P|xCr3( zlk;Op3rDhM7p#yN00;6Jp5%j)Gtxp!Ju8Hh9~X{omQ=$RW0Jq|!UcQaseD$L<9V$LxrASu&Zz3eQ{phY zPKToCw8j!^F*(WP-$_X)a#bTQpmz00zrHBlFZPy_2!gP#gxWW*g4Oyj^SMkHzmEM5 zU?Egq@HbuNBd&T}!eQIiF~4lpBN4R6CgOU08~6~UGI7(hKeH=wy+2Lf<##vGyo>L8 zpSh;sr4*8?2B?wE+RX74PRl$S==okX1o0x~IV-@xHjtyE;iHPaKm#bYqnWh0GGvKu zRkUEt{OCmYl(8?6NC~V4o`H^xNoi)J5jTaHam~Ds&Y#honTR*-tFUmGQs*`*yx(%Q6K7!-nMV;Nde2EBqlV@R#a|XZ+ibW-H;R7$ zYH3fTg0i<^?n+e?A@HC;NyYT-T(Co7DkQ&+s|_3RRMa?>yG@81gVHD4B$QZWVK~m< z?*%Vob+l0b804o|C~vy=x2n>kQ>Mdn0mdV1{d0k0!2yBM&t9#mM@7gNYu6LdWgRW! z=>sdpdp`nQTu)m?7Gel2ZhJJo1k@{^jrE^U9XDTIy9@ zLtoieHg6;(Mx#3%!`_;g|8bc@-}V_TX5aBk;|4qxp)q3KgUFYW?WeS!o#aow0d3Nf z6eXq#`-)0+U3NyT;^wk;MN{oMg{p-{LU0r0+fR3eY$PJi87^7{c62llX1i)^^Cvc? zhRt1T)cFfGb!|=99I!_XX#pPj7&{m{#}l}$%GXK}dob&5emHkRBIL+X87vsQejzmM z8PNjw-oS*A#p;^Q5@=U_6-Fy#?+M$y6y(TFS{M=)wh79%5dC0-l)-~gDUr;Wrpt{F zmQkG2Be+!R>yQH@R<04i${utD!jlqvw`^z}xwh78dcO_x22jbx8^SeEQRu;4CKx@W zbOYz3Kce#H#-~=JzCU5QzIQQaaiQ;|FLHhF8t)#tW7Un(kaheI!epZ1zeFa4kvxR( zbT>Xc7AHmeXUqPDv5BXDEl&IAgRs0csXi%5637d6d~c@7I1E}B$rGH5+D+Mv@G0XN zLY+8haZ>~MWw0B^%l{E-SxJtPs2@8iNf|x)B8XLN<0Aj6)&r__J}Y$4RW*IyeqO(~ z8^jFgabp)yYonWD#eKI$;Wop9x4l5o8~pdU7ZTrof7dy6pK9pY*kurJ9CX&I0EYK>7MBYhuIY%~Y&=`_^A`2N+mHqk}1Fl4jYLJu@ zjs~-}aA4C-?d#qjyrKs`KcBx7c^jxv8Qc;%}pgkUNy^Jx~2etuWFl{VOgK&jiis)@7E>IY{ogrhBu z`ag@6qBb+^mo1}F|kzAY^<_IM#%OKcGsUs?d@gDe-I^0@*W*t|jLxFjH43Uuwo^~m+9t$HUcg?=LowSfF z$hYcqI@mCVjZA~l2@i}(7Q$$yrK>!0i;l2XTY~n@d<5ipAycVOCsz$Il(J(KsD^eT zrEk$`Y1nD&sjx^pd5P$8Gd+h}b^!+esnxmMC6b7lvy>%L4USfpu~fCNLWzD!g$q_z zLoMrcvYpbVi-}BMR#TlG#I~FORUWY;raFqzoY}Sdk%Ze!e4d%r)`9H9YOqt%h82oM zU@bcoGOc@}$WhqphwoeZzAqS2G7##7PRm>i0fOuKaWC;I+g=FSx7Hb;5gPhCgz>#w zq!RWT?7s8H1Vp<|${gXnn&%Tqlu?cESV;LS0TDRV*j83naa0my+e7jF1JU?!TNz80 zuYBRWfe)U@=%VBB`0V9tR`n_1(;3$DbK%sVB8_4>X%Hy<$x1Q~W7heBGxg4Y!MG=M zqED(PA&-_&CxD#*?D>W%4P46xwfqG5$5I8^w>@4i3Qv@zOgvqCD7488+MjNsUO)Rs z`fy7c^Fp0C^xY&Sm?mL0q>Vj?$9>BglS+)5{Pxj&l*#26`0&eU!;fC~;i>6A+gIFL zBQF+(d`=RQ50_H+1&{vw(_QTCx5v?vU6Q@+|57iGYR17G7nob(oo*sS*z#CiJZ9Uh zn0h`0V|UB%Czr^9yvFBfx1nDxSe~A1>6XvPawse|wkf|{zb9ru{Y^hQjG{<26y>!b zQ#EeKR7Ll(g=WT*k`Aj|zVQNOK+jpe^X4tgjX^!cDv0E5M8{@v3r4q}|E7&Q!rKge zK)s-BRIx96DCM{?#V_0)(`A){E?$J=IN@k3hZ&B#&L0Eyt#jzq7=ibCQ?^_m?hTSH zs^WnPfO=lqe7m0od+3e)W_zXgD`a(&*vl?M0C$?j9n%n8cL`c-CQSWGR>(0vY(jd% z#pR8Z7$TBz(j?8|sf*fUoI*ZYn~q=C&^hBupwlx(_)-pvNq6p(}K-b z+$g`YAC8};6eU8}_gF)%j5;!9{*ud>`B8JcBLaMIo}4|0{#d_kHK9O-G7(qN5k=0Z z+h_g8X5#7#Q0$Ng-k9PeNh;Xc?>lJ~5plIanSahaw+C+l!VxAsENe(61A7^%I(iV~ zlzi0ggHWR{zo{^BRuc3kf%vWgep49cnDj`4ogUtz!5I``ugG;+i9V&yDHCW!NJj23 zJq3>RlR?xgJBsH%JP*Az;0(J}E+HJ@<{D_oF%%zTAGmr#u-x6lM^E~c6e%tfB+XTS z<+0@FY$kabgRZVVl5CPRSuhq33dfCBQdgXPVIWj7o(CS5YM0m6ymx9M5!B>WW-S5g zXs66rGiU;jYJb$oI$j|~l-A43?`jGLJ2e3EY} zWR!vM4rxTMLQ5cL!W$x}AdEM?*=XDJ|%AI42aQ@ZXuxHc=`xCr7{z?-6TzFvBs;ME(*a{pfl91kunv zLF1r>KS+FhK?bOqH0AlcgT1wTg$8$tQw?L0`wOKY)0>mpI5nw!NS{(RuT{cZYmTm{ zVCcC-0ch*lYj%?SRr*PdQ9r_)4%g__oE|{#2$RF3L5sf#39a!Cil?NpX^N4$0By1&CDO*tpcEW8Q(P6 zueu=6)8I|IHb+dXoQDPwgiQJzw@{>_lOcGQ`Yc1inT_Tpz)12AUls6~NA`;Zp>D)E z^U+&uA^^i9il_nYTt9YU5LXo7Rwlp_pt)t9ltYlXGXNe4N2QrtdHXUU;2uliVlzV5 z84A`S?)v3Bl<^c9((k>qB>2;&>`R4yr!FW^uvRwz}#YS zUESMwZiPn!3FD`QUfY1aixn5{^DSg~iKTZYn(-Z_>8;vqj0&#G41*tGPW3@OCEsZJ z)>2}uPk~f~>HJhg_~>H_>_hzZIrMmit(}-w+UYEr3hH{G;_8wl^%1|O67(iKRmXY7 zN)jwVO@TS>)T0`+xy5O%5Bl7dN^+*tGH0E=TRViYGbx%Ha>dO`a3<`{M@qpsjej_) zIh2G&=aPf11;tP*}aySD&?!7rvpTx|&V%<>)~nW=+--o|!cfgB53bY=sYWHMU|O znM*Xl+mTrEy?^rydK|IhbgP^sPiJP*DbcIp-5P?Y4DVk6khG2ZfAvOYY+47X3Nb{d z)$KJB3U{^7CV&-=BUCaXC(5LCOgIgSGT3{e7yB zl5%I-7H;LMJzMrMb%l9_+feuX?)`1oSo38!#^nRS)3fcF|CI6TSV51|^}B?Zh3R0G zP8Ar7ZT^J#JKyR5Br$;=B^rlbGGkotmWay+ju^W^9AzEhntyO;o{^O7BHSF!CQ)tV ziw%$84P{IsYTSS>Vy4AYBL=v82@A3NTNHA(s>LCma=FSZ?AM^sy|WE&H)S0~ey|_` zH8u&vY_@y&%d3j)-Km5gy4hmQYb@28|8{<$|K`5F6~&)6g1#4>C^YY0<89dh?gzyb^ug-UXOwIEU`%zgrBFeI9iXB(pjCf;T$SVj3v854aynh zk|hm{v<*X!TF8%Qc|M5Z$%?m~6^v?G4MEBdi)t1f(FA-@!G@Ux<2+s8^-bQxqZkEJ zSm#EI2s_`Wz@LMgbj7wkB4HrKrLT46RXR`sDYhD6Gr}!P#R;c*Od}jOKAVvss#HD8 zudztQi{{f$dVM>~2%|3{p22L(t5vwiX0bff#InebbdusotQU2y-@e6(E!J*bbcy*q z-1G9~OUN6mQpI4zYJj!kLSb|}JC@tPrJyT&biCp);NKI4375fB<}Y$#OKw23AOW^G zIa|FW*kVeVq&pBSzzJ{J>wM9%_sUnvXb@Try->z5!tx|Y{f9O)XHypzju87 z4b|zw`K5Pcuq+GA+#;FaD3;kSC`mE_P zHcI%ec4j(VkDMi-gf^R=&Kn5fD~s2nbv^MZHFFwJwn17bQT+2k&)2@PyQ#7o+~L}% z$6-*>zcUy5&nBz)o1lZ#O0#=-@`m^k+%&3PXfJaYUhOYSS35DxY&Cy{KxSCf;v{23 zA5Dww`*&D>i#a%FKL_WCB3Arlb9%7y%|=ir3Ay2epJHS@iz?cE#muBN@N-F9$3n zt4(AG2khlG0eH)Pe?)ucPvfGu?yca1z1e0GDJ5e$^@nn^gCGdiGIO_j>`@Z1C>B;x z!8VjYiNVNNs;WqeOp)uWb2*S+)tf>b&BzY5WYn>N-)-m>tsuvIr)$HJ=Ye;2_edtu z5eT7zS9|SU&-?uD4^x$AE&H#@e3Fm$l1!7ri68xo&*ux4vg!hu%eb3*TlLzr8dj;u zgU|-wmkyGgk1pwXFRU?B}jRsKu)i3Kt zQ^_f~&&zgh^D_K?iUD86M+q54u=FEG31!JI|FaAv+~NpgSizwgdZ3}>Or-hs#Dfrz z-TTKhIJI|1mgM7@M^UmW0b5%6Kv6ZT-glW%NNj>TT*jzqalpF<7h8-X6Dm42Xs}P2 z9b3j7KCo*c*uDXEX= z+1vU&YkKZV05UQo3m2>Wk8%X7UF~v$#lngrs+6Ci3XDzV84ElW6%`s>HFS^B$*HMf zsNT+WoU{nQpb3C$^B3y2<~RQINTMXPBNMpNLIO?d#OoQ2&KXRr@wU?5`hN~73_ic> zexvpYt2utltYQJ3$P2Vf2nQPRL%hhaGZPvbr44TSp>6Nsk&V}c?_z0V;UUk)Rqvk^ zBPuuTE`4qEN(eaz&XgU#^7?{68A1X3O^-e_0vrg1qq?{rM?k!M0(wEU81jGShU2Xv zV?i0Mn*k)=YYAJ0dm5Gz<;6VXD5ZBY>JKc~yOWw4U%l~XwjPsW@(OFj@x9VT$}@?e ze&CxMa{&RZ!m?%rLPEw7cFuke4MM6+Exx7e_gc~9R`acfI$@R?SSd>OX!8mz6>Kr8wQ()x?8B*{B~vxneL>1Wa>odg6o zMp<|uj)VP3(_CSKM%eP9y$oSt$~>&1VgtU?=rzBLQ3jPv>j@yl-nO+ZnLm+OWrzy< z@3537Xb#P3Xc-HlRhhY{nSRWIW`NA50hLY$^x%(GycR?aP9A$y{fSZoNzztF7VB_} zmDk%>X)n>^MMt{3>H(-;!`o~owbaLsmokLd3CZ7iy@yo;cromS1Ac^GOQX6q&;Pt9 z2^pO4!6R^WNzsLof#H4C0I@Q?muy`qJW0+>BU#XX$NVb`M?wo{wdH>@+Xd3u6Ib3? zbW>^U1!Z>GU^#Zc+3bdSEd?z()gQr*G|rt5;;w<+%$tuV94D0QXPqzy_48rb`) zW!Izb64Mz!WRdQ8`_ZnwkZvC8;dyNcK~QF?6(xtablpo$fE7K|a~yHg`XqwVz;k*p zc69&W%lG~HZHsHaSBLAvk3O&L*VF}&S`^N~w132Po9`)JBmy|)KI%s>{#i0V3{d{1 ze-OplfynDR;&^@biu@3CkBky;kkH4kv)Q%YHC5_xXYF_AN9}JDglKa!e}BF?OJlNeSu{o95bi~SkbM{IDzSzq{cEl%EN%WD9+oqlPNVsu?j z;iff;;ro?Bvs4_?(V7DE0q91QjqA`I0?kM^?WT+tio~_?N8nu;23iFX&@x2=Edwy$ zS~CM3i{k;z4v;o*i>$ne0qyD_9*~O&V8I%0UBcL!)o=~tsn0#7{wuS>lvABONFb4y z7kM&VkgS{WaqQYd_<(T#J$-IDO_59-l|#I#w*ll)n0Dq5WgV@gLL7Gg?tm~;#i_B{ zaF{>N`HmY?eZ!?j61R*SJh5&DJuOpFLt6tQx&#}~j<`W)!7L}Bl~sC|MXctw{&^E6{Q zIYr2S>|$tJCge@rynfhHAGu`cHfBBk`>Q3(R%v_j8MS)bwOyfzj#s$f znx@1qtPw2sk@%W_Zy-G}9i_9n5qHBrz86;tQdUZP=*)zdmqEv<7V4=XcpBx9#2Ogl zs7QY*9+)sj<)<(Qj)&lT;I`Q?72!W_Eu_Ih8BPb{@v+Kx{qorNRm0 z+Olf|)~9f2xQ=5Lb-ZQq$BmhZOlD~#58YZpWARCYz?ctMCVZocwhS#}N?VPM!*(=T zL-4`TgELGa+VLbZp4|k=|L`DtO27iuch(8T{_mYHtdv0i*)I_lF zXn*9x0YUn4`&D=)J29^D0o2aPXZ>Axyi}PPbPXj0|4KN4(dzp8p))CTLLFuxkaD57 zs4}h7kItVHL80R-3l=FeJWSBCc&cfFz(L-?xset)W?(y|{wt>~k`srN53i!a;2ScL z)j>+E`^42L644~l{DH8f3$4Yj&$pSm&(uHRr|sRbOny;%Xn7TUf~ck9#Zc!Xea?m# zTZF5JzRp-L2yNYG-^7Fnz^7!_geHiwssBx{JqqWPOf}r*>EP~S)|e(Zl^}r&yd$Tv z|4ql_&cnDLq_`S;-TV<-Zj&fUE~{Pt8PWJl)E}X*OTg~>T3$IVrA&OP(O*aaf0kA@ zye8Pi<$QAMrw}eY>tp)h4THu0rN&e46b(5;JQ{w&?~3kqhhBV$iWa+8%i8)A*7M=d z%ZH1g$+!D!+w9keAjXBv{nyFqd+U7^j{6Bx_LfM~^Yi$7_j9DGmp%l3A_I$;JFa^( zH9+^nXHim;XZ)^*fVf(@Uw!)^gXxq0Zl7A^7HfD151BT(jr{u}c>l7<55T#ONL1sP zDW1nYDvA%Zd8*S9!~X6#>$)t7lFqNB_c{f{A2ojI%SX;fHMXA=iB8L<6Xs+~x-0QE@ zvrHgcMVe7cW3)ud>Uw(dY-r4tB{QO`n)9wH70ns=+Kq|dL55wnML@3`&bis<7J<3f1PJO~MFEL*_1IO7$QA1)Ly zF1YDX)_2aUZ3FfC3M(@JLEnm(r0hchPV37ny!SO z$gjS!&*Pl87n+AY4~E?saK-v=J&GasE7m*4*T~2D z*T`RF8+O_fHBvrN0?b&3v-;7HZ4cbWK)k1BRmfyw#rYpW(igE|8q;APNYZYSNg0jj zouw>QPRQ@nt0Ye|G%g3O0l{3xktu^1auj8^F?agBwqt4Q-k_aRM@%^2X_q zfENsgSh6I#3WpSMlLAMLv>`AZtT{lS0ML&5nM%i}`?IJPR?mi;!z#CN<&Gqd-v`h6 z?qp2_o%?_h79T;b-39jgLWlGXi^0{AL z6coH^8yqahjaL7pXv56$A-6G(Fd$PWlU`tsI(0bFj&-$Wh7MZZS;UX0s!p~p*V%~` z0{T~sUNv!9hHzxX3Xut!U)pEaGOygp?^rEXZLHBe zazW1a62F|25k5&a-UXQ4O1>BXYNdU~xx-!}G?N*h0-wd`*=t4pnBba#z0O$MbX1AM z7`~QT@Qr-$vx3^c)|>Yf=0yAuD4KwoCix-X7;*H=KKb>*JEZ&oAuRf#)8Ukx^{npS zC`vz9rd~Z5tJbZeNMkv9U;TBTTDg((U;Oz*nx*{io=Ng?@t8Vtmd5N6y93i92v}pgqz233loYIFZ?kfCPQHjkr&E znwpyDEaTLyK|~5yLUP{{fn1Md^n(V(tTpxuP^oa)j#PM~P9S*1SE!eW5Uvc1L&~;@ zYS~6!aFf-i*ks7qb%U(f(=0E=DVDR~_{(1Th|&y=0eRO|<813GcAX*>xcy~)QmxdO zA^sgS%ad4jA$d_a*U|wBZ?^golPO3;=k|F@28TD?&BbdNnCa*RN#D(IZ{OZvinj)m zt5Hk7|C>5I^6QtZ>Sr$W%UBIVt%w;s-qqnq(h#l@%reS9hRp}RT)u{}L5#a%d5HN-vM52F4{}JyUlGr!zxO&FF|;~nWA8atxUNXz8%s@w z?j?|(|CYp(l$v}$6`~g74!sjWPtG_DFWZ|SjbD67Quw^d zyN`{S>xs&n7f_Ns9Dw)bCOj-e^Zx=`*-ubkf zZrD^iX*9JZaREKDNlIhtpFSaLfLIf#))Ey}^xY6*OR;8Hs+h`q$zC&%iK>GIy(i32 zI4>n58?XLS_5UL6xLDIi71`4ORNWTA87AChD3}5x`^XF}e0D{S7D~`bq-8iQGYAXG!u3TI-RwP^ z{Bqocai-CiO&hQfOk`PW;-i*Z$j_RJE)1D`nf%h}k9&(&*z@DMCH*z`L}B$Q{h+F| zXaxVi>9$_-JZT7HPI!|003UY33#+R)0ERRlxc~Tr%`fWk5DTeS?=#z-Ji#=eIM6?}EnlIpC5PiLw?KZ`{cc<{XIZQmIzV09Xz+`b}xR zZVDe0#1v!KoyVxa!q_DhaG(QL+#gDO$v5lsc{KwulaC7%kcRo;bsHiZnW|7Pl>lC$ zkE$1!g=2ZzRpYEMMOgz%s|H|1Hl<9~AP}-rLA$(^rdSDfVIBb5k{@lyfrE7!kXq?! zNAS_iBo*MMw(gEBl@eZpj6l-NPi|t{=#`W=*L@P={tuXN#|C*FrudwnX49YAM37lV z*yYTE&|=V)HMBTnq7~xm>y^?nb!9keWI^Fb>4fv;6;&Zxn(>E+`b2tzGjB?7$}@yg zg7kZ0ZUqY}n%}0h5B=5Ae+_LCuXm3n*6Zx7sC=y!2~Q#hcQ&S^!=>x;H$Q}baTWUR z)p!I%M4O`x@~!R?SgdYlQ8*WJ!oI3~&YuBpbs%U17X8#HSqQccpuXijP2Zmd%pk{R zIsAKl^8VpvKpxS&!nN0&Ze7IjG0ji9&wUW{x zo{R&fKaqDC0ds=zS@q~v*{X*=xJgiH3D9(P5-C~8Qu&aohZ4h3*swBIk1=RihfCBg-TRJvD8ZM!H?7%3#?|`bb;hY&HCO>fyPsYU1 z6gH47EN*E0#s8HpgE&8ugAI)7@I6>@FjF+YLil@$Hu>5;(8b^h zARtv&ornD*{7h2OiP)bW^!{~H-eRXwFspTgz?!SBzbx1I-t`M!``zgzgHBJaoH?u_ zcmJx^Y=5}{4xF6CaILNPzgi%#`4_#Su3cO;FHJSfM5g*v{5@_8+hkNGSc{QXvgg2F zHtI+IWCG5P*#2T6tSUUz$0b172P_197JwB0U|Nk6+;pmX8~nk`r|tnBGHG6g63osC z`EC3@YtRisekxzyXAB{seqXZ7JMf!AKJA89R{wda`tFLCkMk z%sBe_O5kE8qVArq6B$T-OtI?wqm!J@ip-E24>+l}U>8B4&#g>XE#20N$H=%lGRbaz z)9U=EJu&XuK|xJP&Rhl4yuTkvi5HXAYbyH>nQrFY7oc*6MF851bkyyIJksDI^`>MH zQu}Enz=c}&K|MfZgjeH*z+L4%?$(pA`EwYlo3wOPOoIICnvDWi`M}Mk=xS}%U|0;9 zA$u~7WGx<0j}X8tYpF}e@hR@hcf8j1vB<|J$9pF0-r+H-7c!~d?F|a>aTZE{JickW zFW<5E1Y{-8_xyLun;QSUzW9wm*S9jNT=J{o>8(|52#R||bpK%P42IxP;rKxxit>cR ztrc6xq=K44s=;|~*N=vYNE#Bcy>L6IbGk~R(Lp%x#PcJnG2GDYt`z~z{HhZ7W7Mxo zb3AqdgI|DAJomVH{lPzj zrTf`a@$KljBcA(%YwvrT7CH7H*qKJ`Sc|mj4BCP_fmOcYYIe=3t8Rkq8mA z9Etj?Q2EYm;`oClk7)DwKPzAD5JBHoKI~t4cSGtxq3acwl^m0d1SBHvI(S36(R71T zQj~BMgh3rHlhI9HW0b0z5h_dJ8W~Bap_7cSk~JKD=uPJdhibp|?ncRYZ>lkrp!ZXD zc14wP=fAO5ZYXw{F~|^YSKVyq?P+z6uw2X=CK>zfTYGoq^h5uVnQ`fKYGK&;)ycT0&R z`bG#Y^jnwV*-Q>NWdHhpa+5MOC;x6(M92@8NW=_%iGQJH+fL=y;sx7Dqz#?)@Bi2< zZ12T2!7+-gMXm1p68vK;JK2NRYZMrlUme>d^}F~i^22noP4M;c5>A&SWhkpd(9mB0 zQ1PSGL$UH=&HnO@#FN@07YAOY_axQ5^OB|Q5qa+vE!v7&yV+xq^8LT|&1ozb;m5(P z6ltEu_z^EX z)P0L-ct^jwo+2|ctx5f#Zfa?fb+{N46udd^KJdVeE}vriARPp(uXn#V-^5?-4#as^ zvpSHTR;i$<05Vs>!z)g~B?d;`kNC)$Ya!q%X5&g{(BuF1lhG2Fx1?Cf!21eGD<}HR z%g2x!Xt6be8+e7bRsS=|STjDGj@3C+DJg|r?)N94_!)8E&1cE}T^*`b=bgS6Ii};; z22e*3PfWi#VMt@WUun9(~x!^9x&VMufio?VnAK1;5Rr9iky-&93qSLCOI z5u2i~6x*>VgvMFZ>aPj3!}ymbgI07|f&0}UB#OcfK8pLu$|1ku0es3&huuX3))SS$ z3>hm%?!h}$xwaBjaU5VHUzDq{oB_V59*nNm6?i>jk55&q<0wYj{UR*cOWz>!HK|;z z8j{^L%lZNPj?>JwE_sE8ywI@&-y(IC@FOT2!})yUE{y2^9~ys2>@`O?B4>lPUQ5FX zeXnamZm2Ol#l)aDH?h~A6AHPk0GUtwf$@ht>JRRc{sSHhu{TN2MdUX# zkq4lrJhiJ!cB0ki_qVvjoQnYR<3kq!`6f2NZtl&FK=P41-TQz4d*gt`@1z#{H4ZX) zq7CdGzFj{%qIs%X1l>x8-~FMwewXz^gb`f%`qLBcAXBnsPzbjd{0{=_>`Y;<6U75B zCq%nqjeTj-Wt*_`F*}EzO+ALu-f#4q-9P<_JikAPz$Zu|l~mIFdhu}W36 z?B@rI7EqsAkvOJj_IG+))X$Lx@{@^EmGUN?i+dPxdYyzOY#)anpQS7YS2{i)gw`0f znV(8@+zcF#_M198V`1%${SICr{G^*R^v$UQcv2iLhPKZ04s+0~%QUAEEi~Z=wc}c< z8PJFD>K#?@qEhk2APwV_!&LD3P0Mw#eLAm84BKs$@!R1BX55plF9Z7u48z0p^t4ns z{9N0ca1%24_1ILce|jP;Ke=SxxVV1^!%?)ja>LM+OZ&7~2Xzf;o4=KERv=F1iXB-k zH2O-*-89F1+`=?Je27dX{W3bIBwsA|<$Aj+TtV1}tRzb5$kY_e=p)vZpcJ8_#f-73 zYjVg1^lmo?yQr=RJWR0aR6kL46Q&fKM+ z;gE?7WYkx>Q91P)BQhh8%oC?7bp5t%YFPlE_?=3~%K|CSk|a5i*j}&u9>?#qZ^-b< z+Gw`H4#4J+{dG{9$tX<=Di#3;MnHpb4J;8s}))gl|Y zYg1>kTWRN8-JfJh6XpF@8WM#>naU1HI-0R_TVy2y(N)51^|k^!#v(-?gHaP@$(Fl- zajp-p8GyHHpz~l&^qxr2d7H_bNv7moPkz)}(yvg}VDziTVII|XoV6_SspwX@Q!&c+ z!pzN}6G>kkx|}Iqm;zDY4fQW|(slTVb*)l^p4Z}<V!Z9wKzE>Z@3 zFN4nR3$O|iC)iTz3&w}DjEwNgdaleY#koXYwY&JdL~?ie1sA%Q)pPkVscBW+wseBbhlih4ba@SeqBZBYY6<-A_J z7xlKbHR!oB%7>lrsBO!cW3`$}*%X z5}S-aX|@BQClUQijH&$se3l}OvmzJdwfMoP<5CCulZaZp_efpreHXNU+4r491paqF zPBH}WY_NNtEx|!CPn#(}u*Aqii^=T(qZ1YdAKLIQPUiEb8OH#ALqhqxliq#>dNAqZ zMwAuFFT@(y0wa-50x!>%+HlOtcOI}WK{u5+WVwevRlKy}q0wr`9Z9%I8w)Fuv=$wcg1WIzf9X?n>3C>GMJG!7mVO2bOHGAcI<^83 z9%ZOIFZhYJdbhmhgOyicHi2|uBize$`N+kk1NR?7>_S%xD6hBZGWvV<0G^y1+ALaW zTG@layq0y{i{ISBLQz>+M3^CY={KcrB{t+rbuGh)&Q2L||GapAZ>lZ1AtyuCuFwGp z0mE>qYYH0^vf}h81+QY@QB0K zSu1?uuiey|5PpQzuh70kem%-fTO#w2CW3sxlUI`p=ol(8a3%!jI{=Mk362nLdkY zEld#}f5p5SF&S^8Fv=lg&G@f#c(TrPjVVr>YG^0@kR{zZWS*|p_L^|`Xrb3H^NA9P zh)@Sk8fg}6^n7Fw8T^hD)KBb^$qj|iL+cTgKcmRNL#Xee3qQg-Tk*Ga5YGcj=pMV>+%FQPn^^>x@aq7X zV(if6SeU&UoT3P6x+Ug!6xjtBBpOW3#Sf><58c~u_yxSo(_vBv1B%OXhJCaJRle1{ zO|Ki~HUAY(Q$Dxtd!MojQiKcbMSI}VSnxJ&;Inbg^ZNv*|P}KuY0QeAThFM zNy;dyE-A~V+IFuKx&7$Ghu{!3sl(xcKDVnkm?o{H`2ljLXS01^eh*&fR^!m_8Vqdx z2$cwxG|3Z}g@B@M>%Kt=`R|Ee?F9=VmI+59qb_X;~hH9DF zK)15HR5*ZAm!do4C-j@BPKmKhUN+bew609*?tXc`KaIcI2G4q8)lDWz4ZSZ%lEF)X zZ71OljaKX@u?!#&(=hQMXuLH8++oSIW>X{Nif^85pp$!$+h+fMzt)HU(C5Yz--UKm zg31%yp}6p=V3RQV({0dii>;`5{j%RaN{CX&e#WDgs!V$FFyBXRbewhfr!Xr24tAe<@j6=gk97YiE`66TV5gaVHM;EuPv`SKX?9wH zdLC%%*jwJ6uKjMb!J(j^~5eT~)E#`+mC409} zuLQ_q_WE(89Ls`VU&gDG5+xtX38{mh+}I)c?3TS>-d5`)pP>|v{Oh3m-_8RCr$`WL zd&15J-z7{)@yzKh`TNi7oJ7IAY-O2$mBM>*FD0^dlG)K>pY7*&(a0m`i0+3Q^9N) z0zL;bLni-P0rH=ZW~Rl6Up{*_2HW7Sk5$qHSc_k`+X`f;A3mk;vxFzn#dZI$Jyz2D zGNyqq>7YR(_E9&HTzx-9(1<-@&?|Kkrpf94a}9r9_hnxu=+H-v;nvYTUiV`Sohc*V zUqNwX{%`Vwc}cg+oO*v6NrLM}F}wVN6O7M-A*T`#Me=901)~1!lCRbXl26y<*G~mf z+3`uGz|RNLFVdn2CP5D(*k?;f7Kq7w-YPh>zKY3w~H|K#ey5I~D8PKLS{X*;<8l zA$-Wo&lwLeIa$VFH~m8^2^^EeYwF=B@4RTd;5p72}hY793+^W0h0DBy-{-A-L!15@P~xR{S9n+wAJ^ zxT~962s}<2UmyND)^BlK3U%8aq7@V*bXcqjkB&xzd$WGE#m`ft$|VHD09BbFb2Olw zF>4W&;OXneE+I4g3U=SZv~E2RJbn;XZErG4;C2Rmfy-GxMKW5D)quH*eMRI=^M7P9 zCYcxLHBw$!JtfjLX&wlBYb1Y;INT!bzlR@WZ3A34kROrc-t>54r|mqOfJuGY^l--6 z?7;6{YzaU2Fo`(6!8og>hfH47q6gQ)9?v*nHtWFpGxdAtKS)bgXi^RQfU`>Y`x=1f z@t4YlA-}J!DIoZFR0DhhGU;*#ddGx)MfpDf4ngt0^mHyDIWh*0_Wn4dorq;WgkaWE zD@>ecg7MR}nZO!7@iaz^J&55dyD)6b9*i7!7=wqd!Z*WbVBiq?l&fkGS11F&0fPv`M=VNs5-V@!rbwiIHy)bBy3i|c!hmGIOg@<1PrZ4>g zpMNzRlO`>}vXzH%;@Dn{oIVp@Oq-AIcI)AiOC0pI1-lPuLiZt+lK?&ci`vs8}Y;HHCVM`4dyQY9y8W%#q6yI zv3SpUtU98L@6VcHmxeWd*0#g1m+W!qq7BYoG=}!Yi!jmCfSJyD=&2op*6IDwIJz4b zkNpCjqdTEtEgwGfN64|wXRw%7g1`FR!phmYGD;in@J_4)BQ-BM%wfuDKg0Nb)FI_Zi#Ae zx3n7fOKR|_s2X?6$U6BxKNeM@pi+u*a!u0O-%wNY8B`Db9Wfl^ zn`R)CO(Epv6^+1pQ-MVVjfI5;w6(QaB-Y83Ct+`I&!U)gbaZg;+&LDBMO$lYYw}w$ z2xewx?3fWFMzlGfJYH8|(NZHmK0a`Ec4m=adU|?HVC~<(pF!mnjnJZ^Eg&F(MPX5? zMWx)^5Li@P@d%}rJc0G9;_7t;mZBz>f_I5*5qDwql~7)B>4UPf4>m<#(HdB!9X?E6 z`k+8w$rNyxHw$5F7Gd-#ZdSs#g+gE{VCg7yKqed<2?wD3fJ!*Xl812M_A-QnL?QGq zN7-e5U3OXC_E$xCUF{*f*Ulh(o_{rj_uCP|XZkYay(eLx5aD;`W!pPKcs(5)rMqkN_tXC0Oyu^}?z@h@n-efNf&+fw2Fdrm@`N6;}4(sDl6}o((h%Y;noZ4hAN6FtM`VzR1fSw>!^m(<~EX+1JT z^|&r-z>V@o+$?Xvt+G1CO>#WtR!KeMCfWabVGS}0$>-!rk(ynB#OGy*ep-mw$2mxQ znv2JICCC$tS+rqcemPF7X=1$6NK8>u#uVlMVA@D!Oj8-vB(RiaW*;2QqOhpU8m~00 zjd*z#fyG1R6~9bn5&s_;ixw?vPRFB>Pqf{;cQ1|{If7xshP645JYH8|Q3*w(y|!=P z&e9cWOJy2Occ;-=G=-4v$EQ2;*E4V4ytkG@Naa;$YG4T^7B8ygi7YAwWaZWCiYx^R z-UWOLAw^#Cb_Nw#Lt1KI{in_BgYxQM@hOBtfyG5&$(w;tR$R%hj~n~;QVA6T>u(Gl z9MJ!np@S;nph(^TO4!#P!U3B+WCwi00U)|+D6 z7H7s!KYC-wPeIsD*s;B(-L};kn>X2D;|5c#`(6(#mLJ2irTfWWmg~v&&2IBKLWI}) zGKBXoME1GK4(R{v$lizWo;yPL4BJEaUWDI~sr>h2G5LP1H}5d3~@Am5Mg+3&|uG9cL7^!=E{zI*NccD%~>LwNrkA$+c~(DU*C z%if;!`Loec3ZYP1y-Z+r6oDlaS?xt&@dE3}u_M_1>kjxh+9NSC3^um0ShqI@^S}4N zqP5PLzQhVsW*K1OR1GMNK8PX1w_)t$Lr@-j7~`g#z$c$6W5p&-ELwR2eR}o9Kf3ov zFEZHb|Bqf!`)Lc7jUR{qwvvC75r<$QVg571>@Eo!0cajvF5BBHfsk#!zvj59yYMK zsDYpN=|EfG9butSxSSS<^q2rx7jDx~U2TgOC_tZ3pRtvaHuka{_7k8PU{*csZS3N}Si@w5?Coq-+4!9`{LhHCPB zO38aDC@ev7X*opYl@QbVWs?8T-djh0DfLJ)g#E|oba!=C zb#+xutM8**x4$NRbPZR(p@H4YaY9met<$FTj>3pjh_ZM^*9hj`;Jf5m(M`VZdw^mDxW_y6GB zNB_o&KYWH$AAOE9AN?0+KmMHXKb-y3=Q#KAmpK3NR~&TzG)bqN`STYX=Lr{@xcC>s zU%$fHzg@*?a(w)cpW*QP|H6Ua{R6w+_zRwS`6Fz&@E(?*ej7_qyoSX`Uc~ZaFW}je zbbemJrI+8qTW@`Ux8HrATb{Xb({?!G;t?06hC`=CyitRAof-)m>WS6lfn_ohsOOa# zNoHp}tOq4veV^Q`fb~Prnt+!5Vr(s2D*F#qzR6oPpV|@4@ed`noNgVVX~kQgY4vHAdNfa0lDBKX>?hV(-%( zY`=-Y_qVYBdBNb${2*gTMF@6W@0I?{F+V>z(V~s{A#Afd*nVg)Y=8e;5VoDYr`BNm zjfL%dc8<`oqQ7Z6c61Ecac&zbWU*;2an6s0cSNn$=0{s|<6hPwD)jV?z$2Zypks&5==5kubnViW?019*$v1Ln5&8@z_2rI)qkIbF z_ColEo8T+cB2a0E%$5t8qY#Sp8d!RdL)M6=P&9ov#;-Vv-Fwzx{mQwh95EmLr|iPQ zr(edxRR^$m@fuVPUWn>}i}Cb|6?p%Jt@!6VM{(pBxyMba^alD9i{9AblFHLRL-%RxVkIw_be>?|=9aF1`0Lww}3+S)2A_%#vp@XyImzT>dN; ztly30Yqw&@_H8(OWEZyWIfAXbUcidgr|`_ilQ?zmeO!6(Q~dFh&+++J^s9Wg@%7i= z;eXd|bAjK#ym}Q>z~Y0aQz46bW(fr>F%e5#gt|BQC4{W^6bma(377u05TPC*HwpB5 zv<;kSMi5^6=FMBUefu`YjT<-c1?lI%|Mv@=xOfpG#ypPn)KnzK#v;yagTv~8S#N{h z7>g)lJQU_+$Zc7WNB2UwqZsm}awyVjp~&iksJsDC7Y&D@Y%ENb6JV{GgxJOzNEkQ= zNh1~^W88A&PhO3Z8Ea5Ke=`Ox+li5D4q)u&W0Z6hVe0;in11jT%sBEo zW*xhNxhLPm+|zGi{^_@|@a*py-o=75Z*%A8oO%=UXxuu>^U!5XKX3^Xcb>=C zXHR3)#^V^gmORT>?nj>`JJD~!HuRgf6@%w*#n=@)Fz4yLShwpa4xM-&moB}I*WY*- zzkBxsy#3~TIC$_lN-JuhB?h8H6NNa9h9g$1f?cCR94Bbe_*W(*TFjj16&0_jsAW|t zTL>=?1+4bdUID9X*RHJ!Snk9ucOn)m61d~nAXc$Z54-gAbnf2iGEo|spT39Cfc$28bKP2=9-GBUW24$$`;Dt^%zZ}c51B_)L$ zTe?qUf5ybbAT2G8gVxKo>(`3Q5<*_Q68ZX|k{7T9!P|vjALNBAVE}h=4=ksE)$DyG zCS3Pl$R|e4_acFB;~YdZ+i?;woh7v?Qb!}mSg=?VDG0j z_`YHLi-qlLI!CAnUW@r5HlA!6d(0wsUM#IConD&?7St2a-TYwhM+~-aT7&KLpBwx= zu=mBn_K_HDU*DM@?w%ia`TM`?{7jm2ek?*x_5kuCmg82?V(&`~wtw8g_O}rFY;Ujd z^HZla4=f55s`#y#_m!9zmY9IWE+G^Xv4kF2%G7>PBvqrNW;#YsK8BG`TteyaqsXe* zj+CtR$SmA~^n%TZO&p>k$wWeC13Gu^jIJF#IRVR~ zQxB9_Gf`!ahcPk|kcsxFM1d7TALT)aE zk0J$riUb6x5)f)mL72T4B2%lO%^MC|%}gW?S%a~2w&U2omDsU$Au6Y=$FPOZ;qgT$ zkkc?5DV3w)sGNv~5l>+KvIW??bt$%QT8l|D*CBWCBBa%hMry?{pnU_{E4=#`a@Nn^)i)#`PaykHe_2Tg#vv_H(neGx;-rS+eL@~JCOH*Y%{rftXQ zY3uRqw%vH+%yT$>>JpyW^$Ip@xPU!7Uc{cmui@D9ui-BrT)~ac{(x&={1?}*-gX9n zzxFjJB8drA^jK_(;k^h}En{9abN$A*1V)?^feJ}NSfNRbww4gG=f&VXz4$gzq3YHx z8W7%z@R;s@`z>wnb^Pz@*ZAFsA7T0W4d_+c8%fq!IJ8DsOnR8rTIiy*P$~7q_%TAE zu|ckjL%1Os5vDAJ+42w?TYykUF~SmhBRr`R^0ay=sj!th0P6gqh%6ioZRtqp%f`Z7 zISIO|sW8;dgrQ*;41J%3WdLE&T-b*#hHdy#M2}bw`{}n*9U+Y5Z zxHU){y9Oy^Rv~HBN+gY3hUDQ(kU;849J&a}Llz)q@LZ%0nuFv)PaUa+CobUPrPuK4Yj5G*cizX_Z@o|E<`$Su7MQ76 zMX+mCh$h=;m6F@qwHn0fb)0~eL}SVtO-RriNdM_zRz5fZYxvN2Fn#K`tulDfD=o^k z#r+6a8ifMy4jYTBlV-Pz3w?*SsG~L7D`2%HTv3sV6|dY0SiCTBH$s+>U%IG8ZAtpR zL%pczdkGyU`Zt)qhfr~eE*Yg_6Fo$+pMDU4o~Pm#{rk+e?binNgyX%hluC{0@|**0@kkxY6#E=4*di#YxLZ$;YneQFBaB- z<3$PTxlmQHf;0a53JgKvzA#NJ-5qRxv9e-m!gSg;&KONylgsqd@s;CXxpfmMdt_Ge&IZE2isR-2>Y7t z|DQ5^d)fODgY6eFgnjCKex$iPKUmmt7aMc2wARw^CJ#S9s2I-95B`4GdlbU&S;Ctr#UKB{1l$ z=ouW!^^Z*#h5XcbWES>CdgU0z6%2qmxdg_9JVZsOKxT-A+#C;kb~&;KK7pEP+tFv{ zPE1^~6UPqi!@F->z?D}o;KIdMaOLz_ym|f<-nw)IAHMV){`~Gy{P}~k_|M-z#6SN2 zAAI)T8~E(=tN8bSzQBJ!|B8#T#fny}_mxn4;V_W*0DZv-n2JWjQZ$BaDWhR7 zejJt(mN8AxyrWG>PEq?@IIL!HjVJR30Q$D3XIX4(7Wn)p=cRKoxoQsi@7Gc8l zWtg{Q1J|`Wtk!$oPfoPRI8u*4(r!_i_IHvW5fFIuzAzB9Q=8S&GD1S~!V z*1ZZ?LeYvnekfi&7zUY|dMOH!{C3cti4DV9V0DIkfHU{X7Um zl*0D^&jI!x#9;fQwfRAXiS#t*{Ag@tez=THW6Se*13S+5N@>aWJ3n~%erLzxrvTeN zw(TrzU$C(KNTGd9`?|IH!E--jdp~8xxR?3C_YvD~Vz6T&gkIz4EMm1syy68b;l5D7 zVwVrP6R=njt1SU5++GZ+HW67_^{DB;7g;rApE?&g6}ymMwVNEz zf=V}lTS7?VU&SQMKyvy#_=cL1kXi%J9)alE$rGJCdZOE7ei)HmhXNZJJGlZHc?A4> zc7|t{4)Eys8+dg3KX`ZVgdSZxKoQadb4S-;%8*j5csvc8CuL&6;A{-8C`CqQA4Eo% zlXg}>pE?SLoUyPLPC!^r?S%+4Bp^_(hi|wBK?(~Lwmc*j^v95~)3IX7N@8?x!AmE0;nR1X!$1EZrzRDyY}J2+4Fe) z$`$D7TD6WiWR7+N7Z#MUBFFeJSh%xOarCgB>T5+ ze&-aVZa2{+F5Tv~d@L#&Sp8dP8B*^Ja_#Hi+-`#GUn6a#f#vCPNGiHD?SDhtNZL>H z(XzL1eb+2rHO07MaS^ygxOM9W2QOd=y{|X{>sxvsxA9%mF}==bUtYtB*RNpkwCS+f zlc81{hyg_ZyB`IGObJ<-8euXGLc_I?M(D_VFhUw>LP(?;!I2gOD$NKW1V&lmr?io6 zG=ek<2-3zQ(3prIQxbwr>5!VUIFTzPItO7fy&$s}Aly-i@OVlw9M?NCrdLbexnBY6nXOd3`VP+> zzKsL>zr)tew+TPKfOY-ZJ^1FSr*Y%#1x~cOzUu(4Z+I5hPo2Z{?R&o$0gI=t<%6u} zl{+De7p~aj_VQ4`ddLq2U2aJ|uXq7VA-A~|ukHkI7YJ8v1#jnKU%3ca)bmOhz?~JZ zn&VxuX~KN>yOi*ufb}bZ8ZuNUV2zyi7@Ryp<4O$HK;sS1%8C`}(@2-~)0s`Lyb)b;!vX*y8@!K44+{Pz>Q1uw(O6fo-!p*!yp7esIE- zV1BS;#o{t1B6H==xHIS2`o!|E=k9i&n;+Q&T6pZWHb?mWV*8MV?|*hoek!o-Z4I^$ zSlGU!^P_^y5B9h0vM(50m+@uFxXbTSR!|3<#&V}lCcjuc{QO|=ueJHnp1C1}9Ty6% z|K}`XQQG5)b*~;+yol8v4=jH9AVo@y>_B3WJBU#nm(~|$1D2tB@LpsTZbo#{ELiQ6 zklO2MMvU;FP!;#3!H%7Kprc0*OwF!G ziZLF(K@kWb=ctDk6|Oox@>{a~4SGCAy|B62pr?W>2xMqW@YsmRD^L_%gQjESYt z+Ebvh#*sFY-(O-31{GyvNJ%LY?dg!n%<%P*z@sZQ_`Kjl_WgonFq`AhP@IP)V@t7p zP6M_s8HfJ;M!*nL1(`kr!I3ujheW~KUkc9vVk8GCAeHOkh|{7t!;GB#T+|Pkj5X`l zVb9?sIDhsWUO2oDd!Kp+%NOs!f~EU0bIw}KnlKups_T)L+Z!pF`J~-B7*Ldf33d6H zJ7XMA&&G zC;!G@{`yaR{O3>b(MNy9dw=*de)qwj@a}tmz`O6hhqvDT9bS3k9bCM81?Mijg0tse z!kKfIaq*?s@y5F!;*)=W&Uu$Pg(%tv(&k&Pv9*MrUGCt8s`hh>^UC^y^x33sF zV-aOZf;Ki2_Vf~D77apWp9vT=dM+NHx(u`Ct;aGl-=5yGA3OG*#F3-tagL0`OP62A zt1rKfIrA1kqf)^tSHPx>fJq$=OQZs3f>BOIEvH9TtWL`A8&gEg+)8J)Z^QCqW>7;guDQP6v$%Y)c^zF$L>9g`o5_Qcv^+v*PXp54t4N_u+v zFL-|3ozThlqZsU%{FGqZDh7McENp*q&yU()>ilT={9yazZs!Mu9Ty&2Km8lfmI(Ay zgKzJH7O;2`OXz*YidbR-mN1CBG$sSS#8}r5<5*?LMt;q7Gz{5^^n#6uOPK|WWi%XV z3z1v74ZUi1!x%jtF^-9dj+>06>}4pd+mG19VTdx5mqkM|I(F!aPMx~rx1BuD&zOlg zT`YWpR0s$&q4Q(jL$N5*@!ig7N!J*R^vFGq9Y}<1fo3`)7s!dz4VAX0ov1kdVKRFlUXUxRNi4!qo z)M)e>JQ$4w`lDe$Uo`e@Kz$<_qxuGv)zqPPRUIm;8c|(UkA^-2Fm&`-tlYE}Z-4Md zeDU>lE)e^7oX6Dy8#Zh?fbDyZ&Vo~vm7r2z6k`}_ty$V<-Wxf8Qk(cmEu`LUt%p8h6ioH5?}N~u&q zE{}8h@}P_NRg-|liB@+6EMf3=Uc_ocylV2o;+GGKi&yOvvhL@rgbxL*UogCQCFXf0 zG5qQ4IE8Tbm!W z&zv4tE&KGBgxLIG`-X+>S25Ue`Y{l;L)b31tvu{~x|wU$FSM3q7g3ZaquqN#b4M%9W3HiN;W7y++kXyC|ap`kl zu#Sc`ZUR!Wm!o&XA=pzEz-AwhxTG0K&0mXxz6X(Cv=9Nrpij#y7@}cv2$m1;J!lG9Uh&#qf@8O&_@NKwz?S6#RE`SGYb92tU>Pq z3z68XAL=Sguyk}UJUcTBYiIPqh}z+(D;kc0y^D~UYDaifGz!wQryXtapc$x)GHMujy9X>t#!{XF2~@ff<3c6jv+M1))mqa_XL`GZhD zd@1UOEV1UaryQ4@%(GQ$H_}?;PBbY*n8pv zwjDZ!O}mfasV%#)WZg4(a^-4FTeKA8pPY}8(`I7G_zCDYYBZ_`4@PO9J}9oKM}Bz? za!V_aSy+a&yh5a8<{}{_3-Jl5h<79-g|^X7ezVaI#98dH8_clk46tfx5Of`kDmA%p zb#v?_l?ry95s6ki((H-Ih)YI6d@8E*N>E=~i|UeE%$&OrfBe&5xvw$a=9V&k{{mKX zaQANs-*L+%KfU%1UjOiqSh!{*^2rz{q~*gApMy9@7Oa+Jm@SFWo8zH1#zC#OL#2yB zlr|blwGB#@1(8u^D3n@)2J%P^!nqh)S~8E+2#<(@ES!G+UBwW^os%onP>?c_q-<1_ zju=@6Zb_p?V}@31hQVNi*=&c^>VVyzM8+cnDJl8L&Mre?K|LzV2cxlJECvmlhB1#X zz@+IbIIpWEE4E_&hP`-p`w{Hje;S95K9A$4U&QklUd78Vzm1n)dIQUrtb{?Wfj&G8 zCV7Mtg&cbF+|iQf3l*rG0+xo`(&dEIJIkVULPah`h`0cAF9O#0#r+Cc-zV)Au;_E0 zf7a7yzwjR$d|muMMJO~bFppd==b(QpS*TFJ(;O_@3Ge;FFX5sA%Y|QrYYkz!`@vmX z+T#1jD{Ko}uC+SE&WWY9=bSJPn@_Bt#QKjdCzd8w|J@)~mamgN$F|Y6{VK>K>`mfT zllPU2=an#UJHLdGUq0BH_Z2H#H7^|$Uq0BjXvK1`O9>weSiexdZ_g{%@T6a7qlRZ= zgR7y&AG_N+_xHP&VamFe+wXdf20?zN41b<4FLrHV{la#zdE6bBl+1GZG9BAbENtJp zgB`0M1GY_Ku=mHp&JVG^6vfT_5StUNA)GhtIW`}kM>toS&$lcup60rB&X3$5OsII! zhNFn#ITuRpEdf6IA8+s8c5M2`73mlV4`KkjFKu;au+MJ)P~ z&i<|VsneQ}#d==36S2g^tM+(d@d6e__!Ytcbpm|+$aVZe;qM=goWceS8MPgmh3k=! zvltrlAfy83t{DSIHidIq3#2M_$F zV`rrLDv;qwL$JyQsXiXv0z&cIj*p^q=dSSV?u+i-ywSC*2a*gbl=dosDy0mDtXd@0 zPeRSOr_eZN4YEo{BQ3oeqw5N>eQGZDOs&GK!9~bUOM=~+inyd~WZE+@yjLtn<|s$apNSwV*6k3#(EGRfHbVDl4)~I>c$@P%2_! zu@=CbTmV~Q87vuPuw_)BG`kREN-8k9t}mei)AKVhDAkDUSOsz{k%);3gC<-8ZI}eX zAu`Cx`;I=V7zLx}VD!@M*u4Kdrp{Z5UKRDo?A;p~d3mHyGLVp%gg6I%{=}251NK-a zG31`3ZL#FVnEnovkPx2?N3L{{x=C|sNq<$0ZW;0Ub zlTen|8)d!9(JQYAvu4f52OoZnufA?tPDlgDbFsPZRluTYLRzMOd&?%Auq22IXS(N znOTDL^dh9C_CjiM9#Y8PMf#zO#Dr|}{K_KzokgB;1V<(k;>b8TvXB^`P0o{TVkUV` zQV*&eq^9N}Gb10_S%t{WE=I51QWO?cl4ofRD#{yCQ`H|04MWgpz-SB|HU*={%)!Ko zi!fvQa?F{t9t#$2#j;g9v3l)JY}#@VJ9ZqyzI~@~`0#n0IPoIRo_!e?F1(5tFTKtQ zSm)2Zh^mSjD5YUAhKF&Y6-5^&gN8g)sDMSitauMB>UBj0E$Wp;MJ{?yN1jRHtcl~F#(GevRV_cSYd$`9oS=6;X%BdyEHakSe|W%Sb4E@VOjPZ zdmVRmuzA`1V*Bmke#*An;$?FH0Du5VL_t)yoUpxOdBxJi5Z2*t-(4AZ`|h^Fx|NZ- zX7Nh+LR9qGi*kMck9lBFuT)Ga zszQEJE^OKLkfzr{U(gQ~1E0juG3!xKG6kmiN|a@1VS0%T<=Hl(7%b4L?Zf~#Ko+Dxpl>jwf&Pezk|IeXM~p%bd#C|9 z;aa4tVi9XggDxQt=B!Gjl#f8w@L4G9GY(1Fwa7`$#E`rg3`z_~tu+Y6I)C(w4ng0T z2qbFdh|`-9uTOy9k^*aDZ)BwPL2XuFG-Q^cG%Fu*8NCpj(;IPV1u(~_L#wlq7jhjp zPEoQz$R*+M4hV)!5dlMLA@at|MeUNU7{B2#CNF&knYop)TcQzdFvFtJBid*{jLCxd z=s403Ddc=_6!dOHQ8}d_s{2jCsHv+kckNCrUAZ1L1BM|vw-^a=sfe|hNO=wECkt#k z1LDmZ*v&?mO?KF9Hl)SIA~!aU+;cJ~(i9g}V#I(!=u=aNWJdzbqzo0UOd2%|RKU_| zVN%m$r+{Uq#~PZZgH3NlLUb%LlTwixpGex8geg;J;q`a_h_9~R;DX5Cy8Rul)2|_l z2v%$mcUHh+^E3-x-!;*)4DXRey|ZXMvHyH=6|cYZA$ILQMf&O)ES$3*3umvz+$UDz zi5W{VZR%o7p0p5?CM>|@aq}=?%xsJwH3MTuPRE$xQ!!@PRE%z7VBaYmIeZSsk6ys3lNWL3 z%q5&Z?-Z~uz3?h7Uw#uCp56h2P776dFmw?zXu`vwkx8Hm3q_P96#8&EEK2${LXAMY z3g@=`@|xdSlY_V)+d%OR#(0F^P{yn!uEN4=Lh}U(3T+dQ=mO<5dMMbU+NnuljaPg^n_)>3- zAV}yEKb09#5m7KGBB6`aA|l*GUYIQ~MVXPTh(LOz28oeo*o^V8r{_DrWLQ5DHH{OI zl~)U$CK}Ol8Ilyf$klmafVn3I=zF3}Kbg>M6`yz7HFpJ&Wyo&STxi=P+s7DpWL#L|n83(NyqI8DP**?=GhomszWE zidh;h=e1?k>0vjSkwBLsnrw)Rbzt1YNqFPk-*aD9q+d+@_BNbiRvQ8q|7FDHFC;cE zLFBx+ZZ?0(ur&eeyYIf^p!?Tu-oV#{fB)}Gy!*kQaQ4D$*uD1zHgDO7Et~gaD`De? zy?A>4E^J)46C2j-z|(8CVg2f7v2N8?tX;WgAiUYS|{NT)F|v33R(^ z*#@j$>SPTSq?T{Q8d7HMs%J<&+cOlfL+@TW6zEw z*thE#4(vIBgZoe6xkG0;(dyWd=Q-i(cl0SI&~4JPhY~>Gt>*~GA^FGjFTsx z$Dn~DArF&66A=oHOv(vYDyalfp%Q4qWH2kE?g&`Cw-tphGo(uib>#V^l7v9vMu746 z_vfBX>@)0#hCT~vTYiddqt9nQKfe}z#|l^!FRyTTdq;5i_{hmtPPPgTU*AX$Kffrl zRdQQ@e;!p6YVy3NXzmags3lt`{65_V1<|dJY~7*f&I_UGY#H`kYx~V<&brxay35bz zb(b!zL##e``z&JT#L~pl*)|3T8xbloyAs+2zc1Xf=UdCerimSkAQhD5_FG`(kcL`Z z2$ME%!=yGRVbL5iAu=c7GJ6xT91-Dh&2Yk%Q@pyfY>RvIM?rtgJLjmg-1pmTsG#XnNEkeVyEd!J_lvu-)^P0#VhWgqa zXkZPzc5<)f?w7l{?%m|&p?#7^`bOwY!S*F@e70qT@?+JSG5R23uPp|9AMWM|?E~5u z_tTd@H`;TL?VTU(nHv;#48KpgMT#K;J<4 z`UD`zSB7bm#$d#l-AK$|jrimRNJyCnd;AQ-OmaLQX}#8=uk;SuVA<>83{nF*dfLl7R~ zh3fnw$aBh&lu(E|OEOAr$%r;5Av8K2A;v_g^{M0QEAuqpikVIJE zFEb!C%8E!+5^VZJ#460NE7VBVT9BLA3+b7aNGYjDPFX!-$V8;o4nab81++=UC>=f@)3>~c#al09@#;<3v1KKWZdrlV zYt~}%x~-Tvbpd8fT8vfmp24#lcH!Wj=dgFpZalYiDb8+q0;`ukfxaV_q0i{`nEd2k zOq#L4NV3mtXd5$8a2!s6^B))fm!R^w~%d&Ru8-0 zh!~RzDM^Xs`qS{c4?e>6>vWkPaQjwE0ZS-OQQA7+Qp9R0UNnT$=@(z%4}bjxmtT7aCr(_%;X`L};J|4d*nb+&9XN}_`%ZI0(t$n4v48h5j(xk1 z5~#>T*m(qdcT&;m5O!}r$ZhwL;{!XNBOJlOT}}>=atHSwC!D~ceJ62vKjjp;#wi>j z*E@RX42~Uka{RfoI7&G}Ifr9M&*S*9^Ei3p0!|!%p4&f8)0)zcAEh2y=Wy!SIjmp3 zfm>Fprk+L_uar=lZ9=&*!+l(Pji_c_rl%u zGYdaXcUy;8{`S;!H}g|Cm)QAnFLQ(+Gj<$#bUIzD!qAV6ux;){EGks-TNYltVuh@` z5wIv?0@h<5JrU#^h#rr5K@p0;$F*)YJ}u-cbsfEd?5#9jQtq9Fb=7!fQaFR1H5#B)o$q=outM zNKhoq&p7mnz6* zG`^1($z~gDmK+$(i3p8QBS@-3Xp{v?OCr>k1Q_&oBoIoh@u;#VATuQ!*2HWWt!XeB zNIN66(8{IINP-dK6#y^q07$$7;p^=Msh<~VpEnXDe#kY3Vo<6aOX_2>XKD>rj;hA! z@?NOONJD0v6*RcKMHvdYGys0SA@K1FAZ>|+HlY+r)l*P7Y8fiVtw!naRj3%U3`55* z!i0(QP~SKnv8fe^vS&e`T7cN%dN?WuA+>rC5=*L~iA{kiIt%k>FU6&ENAUK`r}6rQ zgE)U;FP5)fgF#O$#^|X_F@D5!j2t}^LnbfA6RWpk%93YMTR#<(N7Z1>#4HROI2_rf zGf+2t4KnllK_fRK(U6Gj#1a&fu^lpaKKc({jLgj5h%xFAYtX{3*K*r9a%?lG5p7f> z#zfLAdL-FskasgO;}g(WR*AW@=HkkgxA4`~>)aB;o44B*ux{S?&V?4|1vu+)3RXf| z2wJyqaq+Qk^Fr3m>$q{_2EP328b1E(zwzc(C0cTEJyu<0^ z7YNV0aOU_~oH|N4at5c#_U!TVgy(VgSQB*r#08FX9JHRL7`@ z<>V;2#&d^H;m|=UfSuqtwC^~_ft`mjbigoTP)eaykauh9g(ag%H~~v74TV9j;4noh zVO6Q`h*i9RMVAutakAWfh43Nw55Ihn;uNi#g)3LjE1}mFD_psHTnXX5fq0Q8I9MpG z(5+Lrq9ThBXC8jPnU?v)(}ZPR>)@}+rn_rL%lgI63Cp^si(Q9J6AE~)=fvx2&d;B3 zF3+EHZ7YR}MZ5sS3q#H=FA_QTWmG_N5ssYu!gMiV$tgO~e6H7^<=DLZwS@WI5@x;Q zWkvT{!AeZDY9U-j&@T)Mysm`tu3E&rVwMdGmktWVE7zdy!uVJ0(m~f{gq(oYrUzF0 z;$I0d=yO{LRql8wVEuxi>$Tk(EUa?+LNEXANIT`ZpzTQ`1-1=S}qA<`?oD4l!qP92Mv2YG1xYX&5uelKiEDI zBJ3Zx{mIhab8J3lT)1O4f77vOo7w?i&TV-&=`??}$dWO(f7?4Z`0e)zdtDZ`-RvB3 z&X09%_DyU3=eD2S(4PF?*YBS_e`gM| zq%HA^6|Tetth-r4$OmwD3Rpeh=jDsXx_QB%Hsjd7wdgZpH*#{HMoP{yBxf!|V)_y| zQWhdDXBBcvHzTiV2g>^FLt)KMl=Rz(9^Mjob?!*&>H?Lu2pYOv@KFy)L(H({RzYJ< zLyS3tTV~k#(T-4fNnuku5G_+;U~U$Qs)oUyR1Uc=5y4S0kjgdC1t}2h6#`GcAcQN_ zP^yT*B_V0jC`dvi2T;vWo&UkH4BgW%;AfM6egLt-mvfFth-jlt^-k<*u& zoYDB5^&`YY@&>~0{58ab_z`Z26AbVJHT3608dIT}js*s$Owoyz*$b)UYdCFHk2WuuH*yGBBq(}YY&m* zIPU2h8dOk)J6Ba9Qt@-T#cDE1Jh^cM@&HNQUHP8RS%2K)xI+GB!&FZnAIYCCJEcu> zBCfc8#6a)RpBvb{r*6qLYPck!~5Y0qsQZ8zSpz-kKqgPM_TrtX9jj-ANb5k zA>XUlN}sLMai6VM6?S96VB)F#jyV?IBrFo!x7B5piJZ3R1{>4fAAccZpgH&)abJpG zYIy@OJ2tMT5M{LQIUWY3a3}~d(c+_|zSL{KGS zhDPsp7dU4e!Qg7F&3KyG@ag3*TaRe%@_5BEPxE^Agt)8tZ>y9E;i+xW%p2 zRBw|)0_!^7qE%TfYHqxwhRD90*w54K^j1hdX`a3*)rO~)nS?JY)Fj+~t z!{6P zOq6>+R!5Pc0|jdDn$x$IHE;0S@L3DDOZbfnYm)mq@`;NOgQE%XDaW(c`iEDu;MD%! zRL4I4JOAU;6;%da{my?q+kD;=HJ*vqzZ}Z`ZX6XCrST0?f7VINrx(I}*w^lt*NL0r z(&(XkcO!QYrG%F%b7ObDk%l*Q)mP6J7+pwrb`D>aw|d>@yw<7lJvWR{y-Mz_L~N98 zDY|48KgTv5BKE&3kNf@pd6a!QzAE(-Q}qUDOiCfylpB$}-AkbbgM6lGy!aBejz+u~ zZ>{5*O4V6L)dIF;pZD;zYdX|;XGSfT8eMw;I41Aw$MOY@6#BC6{WFB-VQi^TC-{s$NU(iYlQx2C0NKKT)@{&Bg*@JH}B$M)_4%cauiCp@S z=pTq>b&Ty5q>G4m~1!~iYv0q{t4 zg>sqzyOi31^4vnabWgjnb|wR@kPu~EdDGY3dl}s`!4e%b8R_3tbh`1<%1?@e567@h z9tdSu?7=3j;2eb?&;dsZ!6 z09UCx#?N^=D%vib7N(4k{fX>W`BuL-2Jx4R%*V&6;E|P! zpy*7~AY6`4$VA!151k|ROoe0m%%L?Pr9|^k2%5tXX}YR7gt&5knTMAgjB>EW8IQ2wmA9B*HG$IdNDBG`r9{E`zoP=pqr!- zK844lF08YfN4Uadh>MaLmb+JGgiBKpL8bE&A;<|b0_|*bSSMitjXKbA;%4Dfxs)XD z#3Riozh?RQ`3d7RdU4{s_wc}3a+UklpL^|(T;;k#a*A|rxTPM#R1~9sI8LlK`)YD)VwnbZ;FCSL@0s|;T1?h0yRV)q}V=MKC{0-WMTipB%n~WJoWg;q( z8}L6fGxYR_cJ{X>VRD8VOHFvAY;F6!Be?g$a%Vki!hBw0DTfZqN z!l`(P%vVt2JPA=q;_(a=-i3j>qPDf_19_AWc{IrRL)FPoXSMZ9)g8mVxf6?eI-+nNjTSMl3aBjrY}cDxTws&C{{+{-MiT;6=_JKh`qW}$h4!80b2OTs{xJvr!b$>5Za9P+}3i(lzW(L@Y`!}Kt zPO*j+iaao!u?WULnLF=rp;|<={afG$l%h1``(K9f4`9d9QZcVD?RWN|GH{lRWJURn zf{doc;U>o6b9)#ARReW}4tyz{#gdZ(y4TXab9UXV6u;D|TsKz!_@9WM5yhQs$GLQLIF`IHc8m5Me*zr5W zsspy|$1)SksLUq=?C1IUf}iaOZSdAPm+~N2iM4{kv@oPWIp!2AUaEC_NoOsz;So7Y z9eJ4Nd&=0fH2ad<3h9q_gWA#sYCw9tk`nJ&y+3WGIf}i!leDoTb$>t@);Vr8Cr5BS zx;z|lR9S&yS$~>_oNPaKZp@xKcqGg2FQ>O6B`XOJ(MeuT=!65o&N6ysZQy`?y-9)% zKX{=1mo9K`n_j=e4IdKQ7olh7kNWZU3NY@WrWmjIBr6Lb(1mkQQrQ}daIwo_^;5~qDhb2;KD z9D!omSuhl5*!g`AuRdp8pHW>fqUr!6e=zh-q0ajO`gFw|OQiX1pqTc*qjS#n7 zI#^DE4_tWDUfEYO-+^as4@h=?vIb3Dfg$WJhhbem{)N*Js$RdfW7RKwe2px4;$Iqj zc$GOc7{RQO8kg8V>wF>C`J(wvqn!Ku{ylG;{e%(0*4@&{^}({k)grb_F^_~%rhbt3 zBL0AH9y{aiAa$sQEIf6g?O?8Dv$Rx6C8%3 zb=mutO~k;)uuTnIHL{TUV8G9W_K&?epjODX!{_q;%U0~iGZjD>d5Ce5_r5i-k+IK7gakfBoCy52PMHF4JnAJ$Q(jz^D_cxTkMmjB z!Yoyy29jDgWiwT>55cffH;;?`h`hC~=`I!TM;{*=>For^1We_|pjzfPY-aigQX*yW zR?NrAbZAFniyjmVYzY!ZYKnNW42f!2S?5f8+QSWcm?$p{cPc~XqYVBrtWh|eZv~e2 z59`sE3Jr4JVzjNJ~g^OOy0`+Z)x&TEt3HD}nf{j7J`kC%5yef|dx~yI;U8vlH4jH9zEK_JjG~=j0?{gm@tP1( zv?y4}Tc8mnRm+*kVP{O`B>gC6EaI#rp;f`<1ap!v3!#^}=!ZW;-?VOChnjYm1jA&( zRY@|zfC`Z?q{AuSxJ?8ftVjN3xqj!jCXPfWi?ooD2hJ@Ke;2pG-e)t5gCEZy?#Cys zwVG$B((fQY;XfO??;82~z9(??yGLR~U}NHM=D_3ePLMI zBxvB_yVauI+wQqD$>nXLweR=$x<5GRneuh3SYjvFTcWqJrfVR^t)}~$z|^ z3{2J*(W&8X+xT~bvys2gqxCecRPnVv(gnL}Jg~Lc)d)DuXIk}@V|=i@pHD6F?IZ{q z*&uB20sVi}w0P!nwi$c49o@2;i`VzbE2m1-*Zs2kWvK><}+;RZ<}!tYzc9}S(#`kLxA;@ zSQFtTZgYPJ7+q9MR*Th25$M&mIDO1v)XKB}wH^6fw?lcuoQ2~_`k-(DNh2OvgPmWc zS3)5?IpOj&Yc_3`Rxu^6FRBy^oI5ui)tPPlW(pnG+(*FZJ^Y`@HOyXlVqWEON)F>l z)+5n!g5U>OqZ%T|l_eqR3ppPbU?9z@#C=Y($N~Hl#A58wHaB40Ar~azyDYrazT64i z8$8~;|8d>Vk90Fz{WYleZ9Pv2QfIml+-y!f5m)%PRwu`fH@4rGH&XP?P+uY@7^`Yb ze1CXw4PK-C4PV3)nWE^JqtB2}TASNrr_7Iboigb*&(?uZTepAgs(b}@!*)GxqQv9$1(kP3m=BBc|R>I|o%9PX=lpjwHDW7Ze zjKsg|-14GScoozJAu1z~OX+-wU0y+QPI}(Z5AgS9+F&2}q$SGn>y+pZXGL z?_}J5Yxq1vB!1o;;RdM5#++FGi)zEY)aaL2HxUY%>?NXwD&8Lce=yfNL51JKsR1ld z<(j6+h<<&={sOONQHh7MZM2;o-VynF-f%wteKj`fK7M|wZYDFufVQ9qwZr8GkpTaD zDtSLB)mSXWH$N&-L9B{tDqwOHEtAF=+j2uBBCP>&e_+!z*(K7PcoJ2o4I-TPNyvF# z?o4i@L3xaVg|nHJ^?j6DW;ky#$}%>z;w}Bz^=;VL2qj4>M~Q-fk8i4%uSWzV+T>8} zyvZSn;_@0<(mU*zp1Lg^bacvR7ead8LO&vWd8PrrRV^6_32u2Uq5gD&x!uL>*pM=n zs;@-V({getFX)lfvaxfDd?=|}T;=ST#bbYK-52owkQl}`4X9k6M*FB%*7TmbHq_Zp z^3)n~Z_Q6+-&#}Ayh;}!rBU@uz->WOCnLhkP)KI_rwS=0-VO8qF{mT#NbHRM#?cLG z;OI$;(-R+b=y?IG2YukazGHq2`cuB420z{eUtMi<4>EqVMNWa&2L%?(dp+WA(u&5B zd~3=@qzM?Mk+G1B@pNn3X^q=M?7BUn@ArQA$|iy$~Snu z^=F99>F!gfYDA^p2K6fjN6#)^9k}xz!_@!I$vHpbXTw2w*rE!DX&bFQa#tf$XMyKE z+SVYksP`e=@k^52mmOZbME%IQST0T>?zTrK?QpFKrPlAd2nOMCA*E<2;o_n&`=g52 zFNJ-pGD2Iigmrk%aNna~bYE;$dbhC=9K0dlJy}UEA*2u>@*`Tg5N9hf88+d8bC%$W z(%m=imKGW>l-&*8iM>7Boec)T)Vc?2G*tt>315~(`|s#_k&nwqU@?Ut!dJn5SqYsI$HzY-T# zE)7y_WSi4R&P@ABK0rbYrpV%kX8VcklAy;(#LnZVC~*o4?^Po2og8R%jpUg`7S6G7 zIhL*+*QzHlx5x^&8T`$ht|Uhuq!#W1-7wD_RZ7f9l+nCaF9@2&37S9kw{7K6dVjq7 z6x{3(qP?93QchuJPb{#{97g>Va{@xb6o3RB;mL&c;oCY66c9_1uHMx7;Q~F>Jrh2= zV}87~N=t#`F3%{yG--F0UU5=CzB9~|seCoEs@?|TStiE^-M@XD=6VO<%|Cy9v`Qa; z5m*t(Ui-9>_UWRFP)kvfDs)=v-)?dnhl6>{t?wV`71a0WWo0WW$F7-u47AQa0Js97gcExPZ*3f)IV1n>e zQ_>K=>6N2v*hyn4|NA0mm`qt3Y5)M`_i*4rzemsgP9fNiJB^my#VR#;Eu1N%et3|H zW`HVZ5GuM0tu5P)M&_ns=Oz0B8==QgV#F4Wk`Sup6e(Q@GAs;@5d~p2!C;dR7d3WA zqhBj@&JZF?1x52?ky;c+$4$w}`I_C9gXKP}FTEO z`1VCKSkGH@mLTz}w2(=K`h<}kzPZGau4I>5s2I*}c`s)+hWn->*=R0K^nzkk{nNl@ ztkrEzg{+~jciL`7>K*PU{yr&1Gz_UwHqxgdF%1n}(2Nr;SEDaeR;2@{jRw2(xk1=4 zg;VRz!jq5rvntxDDX6_)HSH%|a**q2vpjXW-+8zK4YMeUEA>`1ry&+GStOhh14Mok zyzl<(rPgUB$Z?|?Q^fo93`$?b_DR>zX)*E4 zpWG_Sq(h{$1rFKNaC;{T&(`VL9MBx_ik!jj50gGoJae)iHSN8ieEYo>$~tg_nx_XQ z#wvG6K{EtDv9Zhxv#J)04vRkZF3&nnK{qEM%}5B6s^k@7?Fz%O2$gYgjAqWqe{HJo z1qmGZ17My4*dzf)ionJ@nth&$3~u`!hHEXkoz^~w80 z=6mt@UEew&n=rHPPHXQxPs||+e?^_e)053Qjy$O=<9Ots`S_As41eyBC~$)qutnZ* zv4$J-q7suE=i?+;jd>+jKb6Jy%`dMTVx@!)zo-+0b9r0 z{o`g}jl{KuKQ%QqCur)m#X|`4N^8s5(shg(fN1(iy|6(jm0yd!R04%KqZ=kLq2DVk`oC`uk7Qc46iW4_NqR z@@dA9tF)fgPrY$A2JwkH|nj~+K(jxSaKai0%Z)mC5O`V)jA zuTzslu^sH&wmYud)-Cb0TatvvDsH+|J}FDHQbSr{2olyRrb+&m9Q{X-^g*Yem*h70 zW^lW!77WeWk@^>P+W&N*%$Dd(`#?Dtmh~Np8ns6Fp&bVV(7URJa{<_G()6-WCq$1r zOo_z0jAy8%w*kEA%kTSNm)vaHoEc5deKuyD2KtxotH?(VhE3!08yrLueNmDgLk<#g zWN4e!$_RgX3H`%u`Ig!`*+vdq`EL)dij2-vd-`dV>ZMdFss`O{J2X8x7St>f3cxUo z>8u$%hAj3RL9Cgi1+dLG5ianB+zF&t)?j!wKb<!{DUK znLSY+8TpGGNTr=swzi!%d>rvOoFB&=`lue(K3VaW54h5e1Zb@%go)d$~xppxJ zz$RUrXM6CJ94?PqzArM&f0Ns#2O03Gg#Uzv4me9nwX7#I!wISi*33+c12aU9G=%KNlPNxxnqM0cy-fnN9@3~!qCOsG`%EtrD3~@FNu!}~YQJ?+ z6O!M9z#V-2yEKGb5;{R1p;9TLo(Ojsk8v|2k_?SQ9fFwX(n_tV0n~(TM-kELicvyz zv5wp_zXgTiPUbjq>^%LP6D@Z0Zm%W7Q(qM4;rf4S_tSi)`97*T2GVx3O%I(uLbJkk zkT*_)r}Zn@Y2IQZnx4&ntuu)}{LVT!WJ5cd5qil)D&22s-YDB^ixRbr1Fzx(0|atw z=Ke_9qSsAh9HL@wgW;R6R-788cc4bWX5hg|DBQ*T@F*eBv3Q-nA`-ag=bgLnpBr|z zWn)(Ga^-O*`=DC)yTv{YvM0W;F^GkA$lMvv%pcBl0r!l7H80oBAby8XG3?QGoN>1?$fwWB#Oaw_`p?%b*4>N>8b zsHBMCsBKMSjuVZK)>-Z*EsD#0AJ;Yuaz3d%l}I&~9hasowqnzD=;~i3amK!3Xx8Hh zIci-$RaPyUVnGhp6>?s4Ov_u znkok{IHJ?C>#NIb^AK>vz1vHS!C|GzI8>SfCBR zb>hObh4~CgjQll$*ddgH)6s|RBFWrIGJS!Js86r9>~@H4 z5}8YCG*!{iR@c15uT?bFUe)-b<0QSzCrR(=k!-@K1st(nM9g&v=C-+CAAFcxr!|_2 zbvgl48cj8)+wV9#YXurN*&O^aZE#u+I`y23nS3k*i;LvOE4?p@+b-i-A3Z=Yv2*iJ8UKQaz4Iwq+I zP{H~a0B} z%#cFPa)srV;)eS*#?pKBkt0PwnVKd7mXdHby z6oPnDX3)Bd01s;NcNbB=_SfT6Xl?qljANnLm)i1R^+`a;Sp`_OP4b6nCB_V({wYF~ zVB%L87{MicszvESB${%Bpm!9X7cHMXRLT#iS$XIP<4JO!c%CC{Ag@d%SHBgS{LhK- zDnZmDX<#9b>{loi@U$fLXKA(5@o2UmJ*hW?MSc6}&@5%6`dmM;ZpY$#EomKn0?IJn zuKz@%Hc(GyCBE(&Uq{(7Jne`e|8Az+m6xX#iuX(WG1`UbdKr)KI}?C6UH*zynBJ!v znl1_@+y*00gZiUJ2^%R+H%U>3^M@rT%dDkFUhZgM+cYqi`UW#pXcX>qEwOy+v8U9u z-7V)~0-Z}FwIE(I6X`RdjfIsa((G?P7y^EeOm*&m{o|TP}A13*mCtXHY6QQ|}`1WS4;(K^QDeSojv%r&p1R&tZjQTqOocY$pSyw*>YkH1rq z`o}~uXw}N0Rrw(M>S{Sbnh#H~W5d~!U$YvE=c2muz4%k^y{Ae3g~ypayOz84XQ_oU z>A~ialx>StCj2qEJIB0!hA8b;f)MQ}CXb@G$4*X$n#s;eA59H>l^*Utk^qITduTOe zU0`EhQ>6ibNUvL@E{1CjT+B7Ad3_wB{-haAr?94fo6w{Jat(AjDkx9ArAh%S25mg9UusF+`mn z{3~2e(m!6!H+uAMz0qF$52i90FO{)SYelbm-Sz_aVh}S7NJDTcp((*tBYo)J+ecA^ z=J#Srg@uH7y;-1G2#WbELfK`gSKztpekkzHcT4;rO!6WTE?J6f(!K;u5TVFTDYOe6 zdinWBirE5On>ZSNS7cFvkyw~^_n~P4i9?Y~&+&xle|kd#a`sV}J{ zg_;h6y)r${hbNUGW+6DxZhV+IWxFJgFU*@eXN%&^5?0(ouS))YWSW)p((0$v9Qeo4 z((wpZgK)I;S)w(Y`j9yB(gpWst60f%BHFk9Lj7A?3&{`^!%}zyY~9s=JjfjJ$U|p3 zU$mEtk|B6Qp3K0^>az<9cOMR37_U3rwhR!P0%vHbu^#R!4>%@?&#NqfUpF?cIh*Kos08tE<3=s`lp>ZeMw*@GkyE&Svkpiu6 zoq3%yu+n@CRw-AJrLqNPZb*(9NOJ`9MV+-IDcC7UE#Xu#qDI+VMA$#Ec7N^_H5Wl2 zDMi?_|B?Bu%$thi_Pc{3G0M3U*MSjp$fzZ87}0wpzWT;x2yE@W)iAOTyf}^!e0}96 z3*6%hcsfQ=GfO@h;9wisBBboYPNfJub0srsK{4xYBNAOOAaNW+ealJjW zalK676TDqO6|6fV4`_1W=`Q|yawzrs^_Zwz#1}>)=#FnP@B?=8;}LiA?UpA<=!Iu8 zuP3B|FnFL1wZ}7reSJLk7>9k9Hja?Pt#4BZlbO9~q(%4xfZ1_aHylS7oDxP~Cx}`7 zf%|*ee?0xv)TBy*AfaiGX{$1(=hY2E;`NfY`*~j^z;zq%p8T0ilXUyS#a-!FRP~W? z$Y&>R$grAp-Zfmn37{0RVzU`E6xw5;E1;r>|1tLx%Ou91h#R5LtZ9`XD^HyjD)TW8 zRoVIli?KP!&vL$5P0G|a?z4%F8)EIC0+R1n`qB4NsXo{^^n>qY19Dk&dyLP~6=D9Fhs~dAT z(>eo;6^!C?%u~{QkUXERmx@__l553)*Hl7uCd~*ukY?8@4r2X`m;3N>YuDgAmD9rY zXrkwX;-{bDKwzka3)E_T>o2^?{jZkkD*vO>B@6@a=T!RvV3bjv29Xj5`<@cNI4#oe@mDAGBPq5&7rgh(dlQ z($cWv(K?do@211ie6j?ta~;MGF88F_3mv+**t2(1QNjxq4H3{e;A?p(`TkzLO%SqaS9 z59BNq6~YnF`DLk{g3k5>`!KUw&NG!_S(gtuVIN+BKaGHp%EdQ5-FqsG%gVsRy3Yys z%|DKp2+L-sujI3&)E0i7`p6}t<Z*pEVEmsIuHs7H~SsWz~}=!%KC z_Oa3!zZ6VoMB+HGBG}LuG6=&6F-H)saU-B2pbw1|e)8FR4)QtsS?Kf9Jo9*YuJpLu zN4(Vj=ymGnfpIVHD}ezH!pg7lB{CE3A&Sa33LkKw>@Tz-*zWx+>p-xz`EN+@mbKa_ zjFy9SK(mO$%sAY#Mm)Ay)~vf5W@NEu@VEEE=It=y*XQCz*W&?C!RD)c!S{E+oYzb8 zoaaNaoPW*48)QpSl-)lSaHrf%^;fz2RC-)B;$UTR{w1N$)_cAEdr$9cD0$6{>zp)w zmPoN7fY+GRI9A?e?!{3NM0mn&tGVd@fc~Wx7(pAAwB2CR`GAjE?GxA>2g5?4rFr(` z7#zjaS;P!)kR*OBsC=!GlAQsnnq#g1JuXS+ySMwW9k_eNdvsr59=tZ(- zqyKQ_TAk^8-L=|fplcccWW)9WX;%<0T%e7D{zD1{@dD zw1HB=x(KvR^0($j-i*aua(?LDwlrCWCis9C8{t5{-W)p*v_{m`7G)~5gZ5@)VyUR@ z`ok_#QfJnIg9(Jo_Nv`kN}TX#@s|if({l&jWCC7Rmxar@yI0$K8V5c5-7~>0%`&VM zR9AUwIfCD8ZvCyAht~=5G^&er9#qm|oxd zokdIe3)VW+zpgsQ2$<Bu)5N0L~caH|9MVk4*)(V)+ZTNHw6X!Is>%`f2g24KEkFW2GcmCCw<$PPtPOXNtKp(k-;mH=6+^zvg1@UJWxDTqiqt=y{ z4*PqNFY!4y6d;ACk6ez|dyNPDU+?5FSEgxPk$N(n<1hfgLWmf$cLwQh%v>JFd235` z`f#!%4&zC}ZM3BeG330Q`F^%E0hMd`RlASauMwS4Jle4)Rg_C-zjA@YJlzg?@gS?l zMmCZ_T6j#FF3c!3uhuA!kC&IRi6;jK1ATzt;A6Sc5Uuh^!)lN&E?kqc0)M3Npu9mc znL?giG%`v8JhbrpBb8X#p~Ca?;|p$w^5kC?C<8b62x~lEY*Ig18d@~PxFi{4S+sf_ zZjH>WunIWXSW6wISdD_E-6UQeDrx+6E3nBH;{)RkqIB_`wEDgUA8|6Cvuv8scL|s> zeo2)vq2!-)lI2sL`6gUbpCJ5p1*SY8$d0=8`4u)-qZB zN&{-u6t>nVz-P290Pi;Q^hGM*IT9~Giwu~(Mt>DHLCd(cd++6s9(}w4&zo#Z_tR(r z&9`0w_lJ(BzK;C&;$DRJ;8wyHJ@F73hz#{WT_T=VHY(px@fy|j@@Q!3;}0;P*$ui` zOdK;ibE1z?<-mL-)>p9h3v=Sf4Rg-&C5&3n3r;uP(ZR{$=D42T_F+4pV4Ev>_wqfq z8s%ElMUQY|{`(Di(9<4c&fA{oWPVrl%>lb>(Ym38S?hGrZL*)UCT8WwPFUsNGzuX+ z&@WUxH_gpmst%iU!1ButSIZKS0c$6)tJcS*&MSF%BIVE9sc*o|gtuVr2a>mJGDtU{ ze7Di&f%Kx47i|l%%w9?IqxL%J=Uv zov$R?IuBBxS_tsI;D3bzWHWIv6T|nmQYg_uHv|JPePdUSxK=xk z$aY)(+frwxu-*eeXLv!W$zmMx>wWT!Y0wQuks=O;LC;#NykOQ#a8Li-gRXX9B^Fu_ z=tJ+RT|021?4eyNww_Mg2;54?gDC#1;gSH*#xXsDhwq041sjycF++Y9Cb0U!JTo6W z>`lnl0(9s6`P-1yT6H`HANIe{XZYUQiY_*lcgX7;q?8>gb+sHoW|W?b3nONd+jrDW z5Hx|QzJRo{KL5{rakS~~YH^zK>Sm{AGlG7UeAMkAaF4kY2%SL$)bx>~CWz1r>;FXk zou`{ncak_f@_a{gbw>@Y!xuhlB~Qv^e4wnND_=xfQLOeE!wi%M(kpJe(=5A9xjg;{ zZ_?r638gRI{l41{czwmI)pxfTuL|SqB1;jPPevS~5oTK~ZNG=aJ!*lRDnodPY1RXU!KqnG=Og!fw5cTt&D2!<^7=kZAj0}Rh-|LtQn^rr zMx#7Txsj_)@`Z72cyhAjDWU+MLDCjK^(xOIF2)E<3zj36ZK`U||nJ=(d zXalh9lc`fjt90Eqm49*JWXpfQ^|-O$-PGarRX}Ed{lmaBCq-?=ic%$AKsy!fS7z7B z!J8#`!R-f^`V+-1-!K6K`3rpgz^lc=5f%Y{)ZA&nAw<7Kh*RwcOT2-W5K~3#fHRBh zUcfg*#W5TXvfk2sUYApgE%9vM*O)r)z~_^X$m-YB+6ca2`+f zW0Pn;n`0YJNxl1pMXjrc!bW^K8rNujWaiVwW?YiM=3_>JVB5{-oPQ0dW@jrP7tFJf z7BjNG7RIEVsG6zGU%`QKX76ueLC;r=uWt9Eler)G2OL_hcckpE_W<^{;gR}nP;Cn( z`YXB`gi;$h4kl^^sBpC5che}5`8>hMsAaRn8( znCF!&=V?A=fdLfjdN$D3)h_5RAqyO9FDxy}g8e~n&^D^7Dr>JwR`1Bnq&g+9Bu{bu z?Xz%L^8tM+l|&4p{v50dlhPq!&XM=Rw6KURdp+RVVK(5zS3(#$@4hraY=r{bbmVJnv%CRcy;v9r55u%-W^Q|Xz|7zT! zG>Rf(!c4}fX2c~52x7wGOBfYoVl_DysU}*z$`z*%nrh8!s3#=7&!o)a;_G(bW|k4s z)&`>m^5^`E%r-`H`DGSwH#AkoVOmHv^s+U)*c4;VcAOK8jVSfNp*Yq(nSOB#QI&lC z-A3w*|EnQbHJB9+Cp$H?SI_1f1~w-H^CV9$eioklq4Ykc$cw;`p)gjiK{xn%{jWoQ z=E&=M+E2fceLj8*>37%)k0}oqmrYgMX4R5-2I>|2UXsl5i^ZRdWfqlB?Hr2uu=!z{ z#1&=zzDxy7-%*-u&dTBbfKRrG7Ev^uDi@TM9ic+*@LzWt~taSKgY$g?P#buS$HZ5*+e8zY+Q_7Pmp4gNQJgNQP{xm*Q(Jbc^bae@M&|}I+w6X zTPa0by8Z#6Ilo*l5uUP@-2;2^CJPb^n_VRz)j*N-m+un3L4LCGOOQ=_VJy642)Pul z$5h`vzt|q?VHEGA;C+K5uS+MfkaQzr7Wh>x+=75RhQe7%gNZ4CZz;E7FUr%1?VxZ! zc(Y@8dHtx{84w6C&7Q_QVL*rcQ4mv4x_#avgM4m&@^|w2V)3hzOY`E9{zMxYCbqns ztcvl;JOnL&yPC-BJvH#+Xy#}`%@+?q6z>csSjtia9SZn*|2ViwT^pCko>rqZgt01TG zeRIIfzO}dIi{*pG!{?H3O_+8W!;hKkA7Qz%&u*wy!ux=86@7;bU6tvHVIuAhP4k8gkLvU_ua>w9zj2G zGdzs`_=pyYfom{z?B;FATI*~O!sKYVIUfiT1hcU>Y{Yr2FaPWiF05+cKOZAM^LVdX zYEx-qllAb3!4<5pB;Kk|n0HE7FVL3r&5=DWi=*4|38UpE zRL~7=Nv?^zFX5e|$S+~SJuTm6)iI0}1!ML+SO;|$4z=7 zQ~xu^8zs4}yQSv5D)b73dU4@w4*%f1=98+VIrlXC17+|(;iaxIt|jqpe~UB4bpP2r zrvvA}RwLTe_GFxuk#Bc>lSZOu|Icv;!CO5aiC)rTJmM>fY#pp9*iH1;^c z_OuJ<4M8l5f(O${#7f99>RVA$ogngGvy6|*G(C;Sey#}>FT)1-tB^kU_;w>2X zVo~l2$l0VMnq>LWE6No!E!_mdDoDG+Jkl~@7IB=t_PYHAKNX;lQY7IIJogy&T+Ike zOtt3z#*vO^OH?S9UfzJz&LfZ#IDk#!(KB9Bo!x+0RqhhF@nnJ`N#7jo3f z4yhPt%kGen`Kec{WIE+SW0~Ne6~<>IXLB^@Q^R&^?X8h?p1-vL3X7zc6CjP(VKRwb zC?6degP3oAyGA%<&mjS1!P5@}PfQ5kNkD{7z%HMWGOE01invz zxmX^_EJmHY0B+M}8@AZh_R@OJLh4BqEy>ksnP~}_(3E76v?l%{&J&k;nj}=fg*XnK zXV`M5O35eRc86TR;%|;o^v|tt{y!~my8bE&qi3Jz#6P%XM|=M=NrGUJ;b&3>^R*I- z0AWwM_3!)$E|Wy#zXtc)e-~d~qsv_O-#Pi%y;2qNyNO{rDBRKC9D!`2nl_1xG8Nw( zaFyOhzlaKS5_5dxKXIW5#dOXO6H8+6JM!M>Z}Ioq>Y!EldcRV0b@FsW=CR#b$^I6( z5d_Ofps&;q*vf*{)9!JD-nQF(ydmV+gu(XKP7bR=?b&*5Gjn}^rOy%bMwZBXLzlpM zyS;IFJny)9ydHOP-5u2v3_2wx6IQeYUO|obkyetMlP@VyFHm=O1;N_eA8UTkicO98 z(6+KE2A5!c+S57I(F8@#a;MoGe02qL11*y&a3{#gOB9fpTgTLu zJukdTV;vBR?GDM*=$mAwxu2!1@E3%d9{wY|9|7T_z4aqq+ezsEpfhgt5YFnrOSGW= zD@lHYbn@?lVI-AJ-<1rKuWh0!U#1rK;#Uk-CXYqFoxH;g7Af2^DISNYpZSV=W^7XL z8BYx`fYlU5{>7PV`*$^*jzE)3rJr!1#16>-$}K_tu2Oo_u@B8|P=`z1t4Y4{hfCBNksA3K=CL^pYr1q2dnxJ3@cYBkUE3N7&1Rm^0lag0x*hKGj*0g&) zA-2z2hGS6Zb3Z;mx?{yr^u_~#8n@Y=*-Sa;J1yg6kI-kLlb zZ%i4@!KXK-j^WZ*CJe^2!}{RKR${kzcdYE!fYk$=@brM5c%rpCR|KY)dUnII9+gZUwb%^uoI)4d2ox6x1&tBm5^Cf)$;{|;C-8r23`X_vO;(HuE`VDp;JdLe; zkK>cw$MF8nBiOKc58nH9KlU8>5(f_)<-D*ctP+DOT1G_y*1o-mFz@~a$j{72MRp#F z($i3wo`T|>G}IL4qp7R{&6U+?EG$QLc0Tu|!E9RscXTkz7VqGJbq!$gs_uOg3cK}p zDi>7WHVYX!l}_cI$#a0ke|b>seI<^4#RDumxUzd(i37FUzjP;cJW$HZhe9iNqEN-v zwKy-X7uT`Z;xZ{4QnuJW;&ONG*;L#|xOZ1&QvJo_Ny+tC?)wY%uErAbG}yWwEHUXH zDm$nW;FJ`!5@K7~j|_?=ab%DMSMI&7L|#`?o>y+XuB7$Hfht!@ORc{Ku>MZU&dzq) zSX}AmlO7FgYP`c~^W&)JxU{Xm{o1)+ETOGqd&e@?4x4vZE|f{xaa3D>alK<(zD{gQ zY}2(};W^Nh+7M)~W7`Y$u5G$fOY?)5wE-2@0J|>Stq;MD)cT;J>w~`s{=V5c@^V$q zKNImY;>(<`-9IDy^L2cu?#AZr+1opgDOK()cXjr)AlP(VJJNmG`8(dfb3NOR7eD`& zX7@)4*>`;Wc3cRxSa_soi27gY3j5BvM*&z972Lcs$|46md>mOBqDDR|||14|qO ztH>6Eb<5i@`_@^=slEy21E!*F!UM?68H?nsaVV^qjhY@0qPk%r8v8toqVmb`^-;iw z0<5lG(1ih5zJ5Hwl6lcD2&xc~n1`Bv6VcE%1!)D1Xs##kA|VuuO3Khwl7LcM1Ttbm zkrH9#f{$yIYWVwW;peY}Z-5*=0ZMrL2k`N=yuIM>(-krwKIWE}w+|G4J_yms5U!IU zL@kG&J3>fC|c{Nxh5$D<4O1D>1y{g2vN$S~4XUi_4_;f=Vvq zzf`D@LlH=0as`r9!$BmCTnn9C1GP#8m4b||;DgB1I9!T=Kp2#Aglgr)j+*qL9$E^{ zu0bV75K(N99EFi8bdOb{AzFrHlMKOfIyU{%AdTUrhgPd6_d;#*!R!?Q{Ma-`7d?g; zYA_%#RD%Sg59cLjF_8_t#sodNjto?DW7B~4TCEA8AyLri%!m)tATcBuDt#zflSwGI z+0ZW`93!(6FeyI;(~Hw_M`bSN*Oy>vQx%r?uEvVKHF%;E= zegwxhzK)}>t;V*;7UIxbujA|E$GBKj;v<1H@VZ!R+1c~dljR&(O z6ophLzsI33zQ*3er?LIuDSW#3BtF`46dOPN9Pey8jCVgiNOS-jKiZ3rK0btxKRJL; zHXp#2tp~Ap&lerQiuJq_02YN;n?K!-v14yQLq&IVuc|{?9{HJ>k%^Lw6qIFVpfogbS~Z%7yl|b1-VJd9K5=AgfI%pspRKYpUFtcC`MhMDM(1k z>8Q)EXysyHB_w5`amZbWj*fBa?@pZoEa4cTC*D`Q2bOcNcJbE*?PB9B**&XhYQLs% zq(r1*&fABDEYk9{9ov>4%MsLgYRl7htUT#we+JH}t9Fj%&i5qUPCCz)JD0`AmN~;E z5kPXPqbXBw2Tp9ABaCtdt2#dxC_pRT%Ss&E$`!O?j}1CQD-pbEm*90J^`*fi34ruh z5cR^k2C)7H5_?~X1GuxBQ%^Ubm6d%RHer9X_|2Geo-Jp~r0P49r+w_3MCWq0OiFCK ztF_0rr|;-;H=*ptlU*mQq}B$%KKeP$%TrzL`xDF6GZojfWm4sA{%XYD-<8;A`>=Ue z61TgY^&zYQc1>LQ`nbHGAME`JdA6J_ldA7bp7wF|?xf13#J0Oydso`tmE5flsWrl` z53y+b=xFCpqW{ryb$n1tQsAmH4=i^8i%Ni3Yz!=#7RE;6<@voabK2cV?lA^c%~LUP z%I!!@8;JPiAt)-DhLXyesIGqyJzJL|Cb}5cb-fPWGzQgmUAeCiI(&)H$G80mA%$5A zF4%eB(RZV~&-F;p?}`3>d!aJTiYXZ-s4j}fsB{B{WtmYPYeHnO5t=|9Wd8K)fNFUA zE8y)XgO3mWx*@Uebse#P9pwI9p`fv^yuG-XSGqtY6f!^f`|&ZjD2NK6F|m~NON2%) zRuugbpjIV^LheJ_`4KxZC$B4dM3H`xkRDg0M;8MFwFpwvBZR(C2hy(;25?^`lq>1i z3VF~aC-(D()fq1hVCSx$7 zgUv7)jWDa#h*Jf^LQ;cD4U5izD6%GuIyK@AG9-nOHl{G7CnS=0U`1;}1cqhA;>NsW zOfN~t9aTA)S69Trq@}&e@mOm&tn62dr~1|5>9z(uH@r6otX`Wq1nX`Zg4b^th}S0! z#7krP;lfgXYtOx6g zv7n)pj8}mLH6>V3O+>w_x|d@~V>dk9REY)M%P_aH5cgE()KYx; z){EG+_Hlgp@LU{tb~TP|dJkWpID#L4{148byNI)Af5U%%;XSE-`splw_~93P``ynt z_3e-N;;Zj*=)`x}^Z8fUvF`*v+4VU-+3`6({PYk9r{3GNAMbp$hoqn3!!7%X4&dW$ z2eEVK5$xW56#Mrb$H9XqaOl7>96HFyz1qKz9uNE+d$~aF`$-vXzZW}q?Zd8J2RN8T z+w9%DA8)LG4+HxQ#Vw;IW9pGW~UoCW{ z%LQ1;=>;gM9onIuBko6CpULPod@gK>spvgsVMkq$wmT6QpM*YRA4cP#*{E%u)=^hh zKN7YCJ_x-lbq25mh(+O*J$SnSuf#F0Snn$;d!TkUSUc-|CHA)BA&UT497W+353sK3 zud2A%awo9V;r%26PdrFsp_8+m0TtU%45rvTFX2d_aLwhNfRzYbiG#B{0V@%-5{?E6 zWsJv_v-g#!URctxu>NRKFRW_->u;dsyZK}{pndzSz<~CRjyM&r1-Z(z z<*Z!Qv*m1_mAiVW`MQ(4`}9O?A2u&8mm15HamDr2i-LN}{T>@owjFCryhiAlbbYXM zyHc_DE%iLulx^!OFIC5mcQul-BUR=}ohwPrmwg`Mdg0ogmyN6S!LAc=o^8Y06R(ff zPSyu|Kd#EzJS%tgQqRqu#Lx0_`mz08<;CSvV|g;JxZc&ZE3s|FKR+&ajj%sIsM6EZ zoqjL<(US7Il9H4smKb7r0qyt?|JD}`8HyW+a*uHzsU1z0{5VtMGkQAf%p7S{T#{ShT*-(YRdlK+da5tF3OOA^!F}nlLozZ}U=WO29U^qTh}0=y)&{_&lf$A@ z5~*P|sbIAzNg9A?E(kn@UV#WDZNo_#ZB(H)LV*D>UdXigA}z##q_80J?lnjbQXyZj zK%7B|DAG2Ol&3{mkZhuHxs)i3G9cX=iK4_fRK!N2Z;}R;x_<-K4(*9o+v7@Ym@yh}-#Qxa%osz;+OWE&#DzIwOG}^2OjU;9ZP#vVSe{w%&RKE+_HS!Tat@= zO7n0xP0RB!yCM&F6z1U8+%!zhNx>ANo3qm}F+CaMQWG#HB_5-a;xIBH79$d4F)Sel zLy3mO#b5*}8=FGmRtje1XX1g%5-e}2$J%j&@aF8P*z)K?eDTJM*!R+EytnWke6(mD z_B{VIzTEsFzCL;g|2lmdr-_cAKEnlBKYr>AK0kg6M^Bu=7hj&j!OxH5z>yQ!fAAQu z!^g4j&`}&ZatsH*IF2ulp2Sho?)dRDIC1hToFqDZ`YW6{(=Kv-n%F#b@-%mS^28}} zeTt+faN_uJ(*7h49z29yyLMyej$PQhdoK4r2L|mFQL94-d?oi*--Gj@MSb zjHi}7iG{Ntz^xN*#@K;F&{p3Q1L~U4*1aeCc5g&OX%)(I3XqeMhV;Z_WF)2_D>)U} zB%eY4R;N%iJhSQb)mS{U1~Vs= zV#e4KEF}4*v#K$;IoqK<)$rcA=+`65$-Y>Z3$QACPT;;OXiG@p6rYfe#zA+X{|%3E z9##WyT7~N7NgTZDJ?0^#W|pAmh`Al@1yweV>-6h{o&YSn2bMT^I}fkI!i3a0=9K`h z!~xr#!Id+>5@{o0m3_7?+fJybajG1Fk|S7h{PLeOaJpKFft3KN=rKWOSS5H`b#s7L_83=E z@QRhA=am>2$XN6*e+8)gwDLJgmfW%HehZQt3w2)Yt43Sk2()Jv@s)(*Qq*m-m&_I_Mlj~wwb z9$B^(qei~$ROd=kw(gp}krUf?`m_yraQ?>~ZC$k!+nWEt$6P=0J&Yprq-A%LzVw>y zD<#@@(hckQ`xEsM>_LcPF+lo9|3)`_Ar#ZOfK5rBt@Jf)Y^M+7Y<-idC|C3UOd2}NAxJHktubks2zdCf(Aq;l%cew49T%k z7?NFvyv!tIh8vI@r9*m{7Ri=CBnJB+O6vua(wBoxK3%=x(}e;oYP&0Z$k;O9E>H&e zKuy0ks0bwOXgn+54uC~tWznOI)Wb=o)QGUJ4BvM+1{SfIH?WC$^|vt&$%5Q^Ba!BUq;+^;%ehv@q+`Fl$vX zYk0s#k6u>C=ul@>BF>~jYPf}qCl+Q_BFm^np-ustK@O`MVdISJvFY9^*gk(Iw#=D^w=g}!9HwZ=rDA4%J6rKa2gZK7)7enT7Z7AosHTA?$nOS)ADV0nQxRi!;ZL;@i`w zaq9F5oH=s}-+uEozCH65zB+vh-+XljXGr?h8496Jl9ZHveHveXb&|9@jqkoXjqkrc zL;9Z}I!VfD+ml=yTK_ev|C;onwrDvoGS2DaoQ)I5zrgWhpX2D~2l2(hJvg*$2R?Y? z9Za1t4GrCzFlp2TtY5tzTi^T?Ti*Bto7a7Ww_aF}7oL0;k3O&z56-+7cTK(x)2_b> z69$b&ThD&zRnv&ZnjUDWZ^6Kp0T|wY2u2MUihfNkD9bBAdO`xyW8*rMa1{WnIL|Q- z;p2DL;jT&LXl>wu)Q!W6Fr+tsTrVcZisiFwo$OF}^+y0K3ZR5M=V3K&5$gKSK-9nR72KBydk(wL$xcb#(BBPU3C9N=y|2XZN(``gaAo(tqOq^|FAUm) zwF}1v>F+>3bp=~^@!*OoCZ^0qofxJ#ma#Ti=;Cb0IhAT>AB!DFoM*=t`Z||6_I0jz zp0ne89Br^=j_sU5l(-)|C$TNZGUw;bUkhGWo+wcigGx&Fdj5-m_HqiKT!AS!Vmz!I zy{)96mB`CVT-M=%CAyXbR%~7@*27B3v*mw|t^usSxZ>mEoi-DlZ9-jbJ_YXycB9k3 zpY!I&mDsj4&zAjJk{Z|3GFRnNWu8dr=jwT|Wo%wb^j*2yfV$g+ir0vgSUa7qkINMW zG~a&vi-Y#>`<5%G|7c3vx%x-j)B3GjPdV6_KYtU~cN-~x|NSpJ#-otxg%|d5WBl^V zMecgls$F=0<1wyGJU7~x*3oPF4yaw)p5`fF6Kw1wDU~p`FlX_Y$G-eGH(%l2Xc_%S zuPL}%wrneBYunb-9Jrz&i~ghKQtw~9hS)l(cH;HHzEgMWgO$`;ky;;AeVFy(YQ6s% zk{Z|3GFRnNWu8d7rJ`+qKo%+==u*|4laoSR>v_ydW4XAPWdY!S7?xy)qvQnZU~DhLRCdK~_Xe7kt_URYiv_44A%<$hfesGtDK zk3aq=0$5zUEPojnLrYG9kWvL21fIgH0GT)Z{b&plMx6=~ z1`3wskkQyy+92o*CMZ>UVwc9G(m+pRUv~KrX<%)lAlc!3e$HfEcv_He%bNRl}^)A}Yj!aIyw$1_g?(21FT+2r)+^ znXI2ms|BqI;b_ZFz1mvG7jpTRs;DRy=@pQ?JJzJfK3n2#h#bfVDH+MczwoXte-XkAKiaDc0T7(~Z z`9?0KZ8s5p_}<&tyK6hnoH~ZRySL$;xBrO`HoisLZNTnbpW^WT9XL$JI&tg}zWibz zjvn5HBm1{w@3xPyX~XMSyL2Ijw6>x!w-620-Ld4JMcB0NBW&BS8J~T$1KZx;hAr=G z!N+fWgm+(j8*e=GI$nDGIXtsu6&`tDDHh+i2rC{~jwcqZz%!4m#*0rrhZmQx#ba|9 zWAdnRsLn6sj}!g@04p~m9uLi^#=SRHaz_jYw`8NfBCVtTzMHF@?ED!3i;8+#wTxN7 zd0i!@=5t2`)3VDu>KoebaI*7z0jwT9dbGnUD#xRPj_`{0yy792aBNTtUeQ=r0t6Af zuN*-LpYqU(=F7;n7_eN^?=Kc&UAd^Il^7h^p_BcZ0;vu_Me`yc<=Ey*)b3p+04f*Y ziUKJibuULyB?efIM+PYjatEzg@vw@1W$=&u(x4~02C)9(%F4=e+DNzq6zoPt3@4~} zjj#z~H(c(@#G58@n*kE_w2ZYO&Wr7^b!-_sCM&j|E4ghew&kXslnu6wy)U+2O6>ix zecXB3ub9SicKMIcI@o9KofX^9 zmE5)!+j7%R$_87;-WOXhCH8*UK3v{Ky<}VFT38?KJC#}=>{?-!k&)r_`{|FA7+Sdl zSW@!T153*LsxuF)kt0Wr4{L0|6pAn$=C#KH=YbwOaDAN+jV zk1f&w@)TTA?<@K>M1Ozy%jJ*<2Eva9gZJ@;+|L&Z8A<*5Anx8ie(<3I-6_PP5G+7J zMB`Mc;3ro@p`yXjHHbAT5v)^j9#=Yp8OGocsMH3|8;c$%3{q>MCv9na`b9u`Y>|gt zG{CwNAqFKPjB@BTDlRUTLZO3FZh=M_2AwJdYPlBbKsg7vv~mTE{xayua|@8E;Y-@e zXxuG@qW##ShCEXZ0s^R~7MUZtHfc3THwPkGC*$T6790wl+Q@ye&?48vNRLtyJ6e?i zCL5Ctyrw62@jGU|d!bCS)h# zhIZYQlZ;ym(lDze6Ze$oVSX(Q^xh56kLZKP}(qEAyJ zZk#Y4yS9Fcci(&+Lk9OlTfg2I);0hGd-ukO0sS$kwFR?h&cLC4JMs9khcSTk8#8PW zCXF41)sHU2_D%0$+ola1wEBGi4jkI`F+SV;4mNFg1?!)C0xKV!gE9U4AR{pmnaODw z(6b+&T>LmbT>k;Kzq<|F-`k0;?``MO9q;eLPIA3v!zUcj`rw}%xpp*9we{`Iq<$NA zko1FB-octBPvEAZV^Nxsjr7=9WZG^OpixF|js` zxa~Dm^|}E)hu!-p11#!+B^)25LEBk?CI0H5-Sdi#c_ltB=p6IPepHZ!AcE`=OAwpC z(sEYr+KKDz*Uodh9NFQVJ!S2&dA2=UCeE{Eot0nCwJUr4HGM8(Xhmf|(#OIk7CLz% z22e@n9YK{lSd}PI)&Z`>URWIvOE@A(;ScM1bvXdbmHvE~bq!$s#pP-%Y(8j*O=5sG?UoH3 zuoAqTXkPGkqFz$8{Tu6#bd+)6XX#e1FXw@^@tDI{>(?FOY*Eqn99SZ4sBNLm4ecIa zv<(GRw2Zc;c?z6pe&x!~96YZCP{rOG-{%N74!utnV2vR5sU2ZF3e{*o`j5_^!YtP2 zmB`)txRN!(_80&B=>0pdk8AqlC0-xw8e!kPAQp5AqJ91w!Q4AjXYfi2VzB^=g;-Jm zOYDKwKi`BG7Y)PMv2##VHxi?UPQt>G58}?Tw$r5B0R_ z3g33oYe5ulDHPsNDP@rP`*3B#(ZP-wSpKq(cvQTHmOtcveo)DL$o%}cJOx8nI^umZsv75C*pwK^1rpghDSx1y-x2E^Oyp_7Hd;HQT{-W72=UxaC7 zP|K-Dn2Mhd{qi6c_4J|;i^k}Z^Is!0Yc)tU(b!mWC{%ic{6F^IJ2;LbP4kYOkqF!9 zMmHLbhDXD+MFZ%D_aF@62!J3+f&jfYqNhlaB1KP;qC`p*MJrL1NIA+-UX-Jg7v*PX z-CXSK+_!rdv2%O3cVFxu7d!JkU%pwLKy`LC0Ll$#f)(*ZRc2*nW>sYum_NSnn<-hW z4J#5@TN!!_lJsP;mB@qHr>ACdOD?;`2zM&2%xHxrF%8bt6pVMIqt}y*0dF2=6gn{1 z=fu2XHx~Kxv833Gr2#D~F2J&q0xW08tJr>RSt0H$_w&{N?r*8a>4AxOb`Clh^n*_i6g#xze3`dQ!m-HIr0sw)S*?i@_a z%S3B-8k#e#Xv<1NcWx$nvNF)a@_U)4v;Hjd+OfJMAKM!$aJ07_FD##jOMAEB@1H$~ z>&Fk{_&^^Xojw__tXYot_iVuzrys&^EJA&UctOsQ&GvDUtMttD!oOh^%tYO$cy%-2E6*xvv~2`6PVI5 z0prU{(NtN1)r%J5>f5j4qf4*ht4}WByX)8R;oC3am8T!Y)2AN7;k{e2XWa_S=x#@K zQ6UPQPWasUSUhtcE}Xr9&)>O@udaN{!PVE-zGMCT4qspX3SV6L0$*JI0$(zHb>%C3 z{lS+*`qjtZ;>)XF;`*h}arxy-c=EwBSjy_F@%d5eX1`^}_Y2}44q&aBQ-?ikoAK6( zJ}l_3L{Do8TI!2XS5fdM2UzX>8!&0^Zp>Qu1R5tUL}_IUiYr=B;IH~g0hZ!IC{`cT z0$8#I7P$;+!K*rMaTOfzYB=WANbpJk5(O0fT$16;Xi~}#_fhV*T$gs)8bq<|>}G6k0-*FJtMTTz9?u2PGDle`~`RIrNnDoZQ1 z%b?ooYS{W}>=0|%+A0`S{VA=mZUL;DSOoum6eY}%Zzn=$ddo=kbX`#LU{$ka8_7C;UJa(S2Dn&$=YZx zgy8_ztg1A;^zb4qTz(&X?F%q}*>>z%whzbe*@vo<`6#PeiHW@rp|j^+7!q?w1z3@h z5r~c^D=0l8V~nsE(~w|ILt$+%64SC#QPa#O<}S24?eOR2z@XEyYXq30YZZ7klE^|! z9~Z-22=%dKu|@ET+NM6-&g&q6MXLmo$VD(JDh9gfXc%H6VBkUAqZN2XZiGDkl|IO| zk3bg1up;XzN2(ra787eT9%c@FQaFerQJDmTfy-bZmq7~$MO224VN4oM~g zSm{W#6e1z56~6I1uwct&tl9A}LA*dF}D6Nm8i(R=aAre!!f*oD3AHP}&Kf?bW} z*iv7LHC07eTI|6h)&|9}n(KC8e!h$C^Dx(A$81j?20aR#n&QYtPo52(*;(kc+t8ku zf$8N17^p15WY)JS{zCK>7ox?P%kImDrmQs7r&`d!)M`sZTXqIIax&1Jo53x#rswBk zZoZvcdhMvG#EFR$@Y13=c=w*o_?u^*z$Ygj#qj5N zubw@FzkTf`{N~a-`274ccC^&8^tCz6Go1)M3+-@z}p%LP$M77r>(6?Y;Bw@JHbx;9V>XipY+^b=LMV40rVu{#S!LEY@ zv4R1X0#$+mmVhu$XY-I0I6}wTAVr2MBb}2a>Qpq`hFYQJLeI+@`}xrO3wMoty}F*^ z{NU##UnANKcfDMsnMhWDh{V4U?oE<0ewQj z)t|3!0j!%?;oJx1iAK1|r+Na~J87qCqH{}sPMXBt-B>4}T6sVB_#kLQaB9u!H+h=& z1Z)&Y^jj=h{4$420&EEvLbcTscfkt)D6uKlRL}E#HNYZKd0~A;9-^3p004jhNklQxAZ8{xw09K3XN1s1M)5dO}&Xj`-m{VVUs1NT0F zCjWd?)T~2q-(fT~Zs4osjSjFV239nWO=Z;Uk(+Mg@t_K;I$$uT!dp~@o~i=0=jFnm zW8;7(nxL1;!irWKBq^3vWPzoCD@v1fmM%61x|mqRvNp&9i&iC!j#1!OWE8tDY8-bV z6!ERd+G-eJMZyq6?uG&PK_(@DyPnl!OmO!pp$gBI#%~LY8lcOHj(_Ogu1rVth1G3^7PBSP*Y?Bf(OPI7>Bb?j@MDsn-FJS2**$k6O`nKF)=!IBuUL@rSXqh{Rvc?zZy@)o3iES9ENV`(YrFtO`h$tJkc&9IorGRuNoOClQcve4zs zLzg25-R^8mcH1zOK$bTTgCtKLX0ZLt0taRnl695`%gTyyM}?1DWG$st0E-K-g5-B& zTU{BBbvEPlw263b_EfyKVh-NixD=PSuf?Z(?!u?LH{sJA8}QA6?fCAMYdEFWv0QKk_3;{j6$mgFtmX4mB3{19X@wNz- zE%$kGPi+MbceLP{IRkie^PTwm@e{cEz&`Bnn1K76>T$YPSvm2A<+JhLwhj2|_#u4v z{8JosT|2M`pB*}YUp;jeAD%mhDJ?CiuPMXX#~;BP!8oD)wR4v>v?k(ivR7@C2^Dat;??IDsM6T99*#y8U`)Huq6~|4WA!Q%fKu6IJ7=Bd>JmIl^1+%xMONh zk=!4-AHi)5ABS%{xE)bPaJ`}TE2p*lqov?>g8L9!U+^`GD4!tKFeFlgr;*^(Naw;U zyeptu5}X=JcZ7f{Sp<4Ub{`C7kMG5I{>7ZPc!4=g^^#c%KPO@qRz~EzA3OD8?1t zE0x>4`CVQ=ofmD;CIhU|p7Ut$WN_dq_C8xf#z#0%A<|m;BaM%6{ZQv?<;nRXEq0o0O3V5x9K0F{VyRalT;Jxwo2NHp z#odphV)}AaOj(1r$@gIYo(Iu7ej&y;Zo%Zf6DTWRgeaY9M1Vz#iKZ0@2^2*m*`!B_ zI~QrzWO$1wz+laQx3CV2TB^{RXGdXXI*fX9A&eMu8>ARl<8J>YBF5b|1hPm3xcEMb z0UpdzGnJ1YhXj2TYlA?Q2}X)P#maE8a`CJk13RaSiQ|wv!Rqm;VLd{+vAiZcg& zu3Yr6J`iA=$kOespKYu^^IFDZ@A5_1zxEF7TD25gmMz31ySC%uo!ik`QvqA51?g4` ztR@2zbUK)0VmMGNuq2>~{U$myGtgtpKrhp@ylhNo^)4*%U}I@94m8x@RBsnvTDub0 zPaMS)terLf0_>=&z(Z{fIMLgVvoj~-_0|7ll zx_1jMK6?^xJar6jz3@1W9@vGh3C-}>9jNen(ct%S)fIVB#`<1p&qJ{@58aIo*s*>y z-g*8azP$VmzGnLBgYWR=2fyO_;@Wpy*Drm=MP)vJ|4V#+`D=W3=}Ub2-gSKZ_Gh^A z`UiOC??8|RNM#UxL4XM4UPn? zWJp442}sWWbJt(uJ%x&bvCAN7Y_REvC;+8G@>EbN#L9|b4jl(uSBdm+nH!h3dm!Zr z$>)Av-2zxQsXQJ}$mBu5t8fr2+ys<@FY^hHH1SbSie$|U>}dji?dos2#Dt!wul<(8 z37VX}$jXp}RmzFu*MqEIr5A{`)Auu99ggQ;Ifzss4Mw{GMEeWV0Z`5W`-GRPnwJ%HSIjPmzxthnR zlHajB2IO%NEC@&iCuz^RYm6Q8^l;qE9q7MIHeQ0!ws_XphF57?)x^ ziau$*Hv#0t7?RUU-+v!;4UG{RuX0^#g?siRsk38s2%wP1g?b#wd1D^AqER-ZQyq(lLEcs0@7@#J5I>o~3%sP(9(k8}c{d z?33T|yte`X_2NYuhYB1O{S)tx#?J44_wRfhh&si%qHm7+`$u{7jZ&`vSDqI%wj|N` z7tcvPC!{t0god86#`71_8Xu#L6ZvnC(9h*Y_(LqP!dYLbL6&eKB!vT5;amt8Rj1+9 zy(_V9&lBibwhL8#%hAxc9=rD*L`TCcG&XO;=#TbH91i7M-5H}7<`d`4xl&SwEyvAR^Y5FD747V{wATuEv z8K!8yPhtBcV-ynOqhK~fA;Az0b9@Xe##ok)hB1!i>0{V&9G59B7RJ~(7Wuw)dgDz(dddMQH%!`FB z)z~nl2U})N$JSW`xO?^>?w&UbyY5(u9ZcOCaUI^=bvKq*__4rc$Lc~4 zw$_y4Kyw`)>zj!4%Vy)9ecSP?3(w)|nUgp$(2Jc-4cOS%gEF5Ntu@tn{>hVg;>00z zHr4PLSB+I=sAX+*H8-MfVh4IV+wkJkXK?7=?Pz1=JK4XL+UsgDf1nRfpFD^c&pe0= z=N`fN#|~rdqIoDO@WIdija~2aVZ7guy5b_#6nRnNWWO)=eW)q&p|52E_HNvYH_p9* zkKg_rpS}MTKD+!iu3!BYpI`Y#(IpD(P7v#BeD)s2zf!EPK6~#vK6&Red~op-y!ZSi zJbv&DrgcvV0WY@z*4Q-~z#>IyuLxd+k9|d!S89kg>@pZ?c@-L$DIC0Vxqf`m zqty9h)%|1C@qP4DwmX)(gUf_I%i(k|uu{XNz%d6(GH_C)xb?~TB2TrKq14b`lv7z) zsgG6gDp;YQXLQMNt>p9SGJkq-C3Fj5-K6rfKdSP?Aso0GY4SwAz*V$Lg*nSt}e z5_z;2>7jf@iUrJdKFOj<8%^l1vI*76A zzfRt$PTJ@^wI%wb?&r|6k?w)6QKVQFkwkyQ`EZ*u5e?KG^jze$y3OY?g}uXY6Hs{) zs?JlN8-09?QCedqXiO=h?Ire1cC#_Eo87m7gsWH5Ge1A{zQ|IEo*9*+cSd6^q<)p? z{gc#flcfu7REKys>hVCLF+}mNlroBS47JAr39DoEYURCM41f$pzvjA|^)aX)1IllM z-wz){p=mL$X>8GWqx+|0YG1x5b-f{ZT9TeOjSm8x^7xR)fI2-=zIuF6-68!_jm_Y` z3234!6WELABg*pU!vU63hF}j_#tqdopu96thJYje&gu6~?~#so?^5biAeT~)`2Eo{ z7j4p>z6tb=qW7?P;mf=}1)M624N%+SnY9w%Co|NfBZ zZZj0H;1x-RS2Dno!IhQ;mTZNkw!l)m5DG1+&cmU*S7PbL6PUmC2%6_?KvVZR z?A?7odfOMErF{=3Pdf!?eitHRbfW^SsBw|(d?a6i&|);f%kDiR*#=KRDT<05s4a5g zz;r+Qe0eCz%z%MnPQ@sJ+oK{Q5PADJM2s7DA>;}GEV9C)a89I|Vj35KRxy0#LfRYSBAJxBjd9~xJ_W4Tv3(p%>tWIxkZ6cOvN0Oj=4j-xI1pKyUQHkWdD_sS?(dF8GQ!voU%vrnc_Kf|*aDrfMrp1}CDU$gR4CQ7G1H_vA8B?5td_0j5E(9WzNDS}8DBaR+qfVy@ecMFsg-;rC!`Z7J@bP=`k* zHsgtDU3l$|Ie7QZ1-Pxyc=il+l5z7JdE9Im!sP2K$g{loK!1Pj0U8c4D1~nk!H{% z!>C6k^}V4AP4;Xwq^6)dBMrS-X&B7Q#?pKzhg1)Cw&L9UIe6`!yRfyZ6%*5vFD-p@7;~B-@Jf#9y^Nd{Zp~1s}t2FB`7T{#I_Bq@ZK9QVB?BK zsPYw|vbYFUB|fhDs&dp9GfK@SaU*sjA|E+pCJas4wxO)>p_~2`fBq_}Mq5*v@`)J};(sc4F_w9qif{aP_s1 z@bSCXxrNnrvbehR6+V6U3w->}=Y0POoqO*(2Uwq9qV#9@@U4&ebr+w02kV!v2>~y+ z0M^(w8o&||OSlgz5Gyory8^I=R~}Tm4l0skUTIrjjpWW24m62;Ee)R&5Ji2gwO5x5 ztwU~Gu2Z```5L)B?RyYy$>%67=c(%nzAm_5q5aps5A9=F;qyb=3GSl;u>wFT2rvah zreF&xResQM06=M6LqJBZKNwu8Ev$kyc5AC}@JY!JZ*ip@E9Y+x>nqYNfOV6qy1F`K z;_!U{7Iz;MlU?K+16)POF*t)J*RRsD<+vZL04goAt2SEc457>m4^28)pzy{GLVJW1R zD5Jgy(ihkNncp`Z)5Mg+H&xv?u;CHG4{FG;qX5+Zn@yw^AQI~0~Sv?t)TXyJwM^|O2eTpV&qeW7gT5acZG}jb(du7df9QdahJSMd!;o2=7Z90)@-O~{e`jbr7XV74tsz((NYkc% zKSRIml}bCbaex&7QuGe!-O)8PMnoWf@r@xcPw!NGm#97}Cm=hGQ>|~C_>EKD)P@>h zh4g(;1!7h8DE%A$)(VL+rm1l6MtT=we8}%!ynh*7sgKp7zfJPrtDizY1Ym`OSYrWL z1g*qgj)5g~S5p=aZ(V|(nL99J!-E)Ha{zM}-j9hGbWb7CK z)&Lbj>b~ufh>TEHAfz}@wloJ)lI_TG=A){z42?b)_V#%&Sn5JqW*U#-q>qi_ZiM7M zI0UdFRjUq?0`7wZuVP}NgRHOUID*^>qoZJqja1wO4UsVDZik-S3%Q%2Vzp(CqjS+P z>0)8gMsbEM1p08C}f$Ukzt5HD(jDpEWivpm=p4lkls{lk!XyEAub*XaeCw>CZH@M6%Dp@jL*qH zqdkiUKyS^np)D^P9Tazp2TadGTW%IQDQ1>~+zb`>zCP~eXTubC4yIDDb*5?FJoGb> z+u>AKHhP^3^qTI@#k>L!R+ag%v8ouGDt*{dQ;Gx4wK&=_9;f?SaAsO3&JFb9xmi>3 z?7RWIvSt}BZQF!rH?PH^l?!li)e;WFZpX6+_TYtw@5jfl zp2zdY9zt(T1@bd8QRZ~QnVbT<)e1+F1+Ek;a;+8~H|pfBd$4Y>AC;NuXiQH*7aN~{QC!n;*i{92|yz$~WJbYj$TB^&q3*p3udbCtjpr@%3liJ%b zsiO%mo;!*Awr@mhZ8K^FJbQE>o_l03o_z3L%$htA1r7%aoOV=| z`cUUDK%K9U$HgjjIZ>38hcdQrtE$34R~I%eU4v&%J%`J$e!yJ=$=Zr6uLxRwbn&wx zef;*P`0(P#9Ac3^y7&>UzV;z5U$};SckK-UFE;|P=zHk%`FLzxvV!gG>_mHeJDX&? zcx*xv<s16TyF6o93`D|P%U#R5z1J{SzJNJ`wR;n-K&@vgLEILSbS zG zl=gU9gW;4oR;ATeQA25|tXwAe908fovg-Vy;{e#AG=VD_>U=*dtnffe+ZyZU&@F&< zlZqx4THq=i#F8hUV&B%bICNrj1L6RSO}f7L;-C5Cjl?H=0ca#dlPub3qBS_6OwMSN z%aH^uqPl2e$S1PDS1e(;bxNQd0RgH2^rTL^$9+Pf~? z%AWjsXp&3!Lgxi!A`#>gdjY)EeG>UJk)`{lV_`j}SY(B_z>@2`5p{N~3IY`B_b!hC zd15N(i+b9>$M~T4E9Z@*aOK10-wYaS-@=s(moG~$C#P>j9bv|YdM}R!t-POVe28zv ziDL?E5*AUy3Xk#x=IV3u z_d{zOXh{ZGR9^mj^;2l90E?sruGG?kSm6Mc>_R92){-Sl6zeOtKQWkz^AE2;_so0H zvG4#|XK%-hnQU@=>?rPDxeZhMkE6HmD6;KMxIHRnM1Vyi02LJ(ieoJ{o3{L5aZ?6HSVRp5j|kAai{TEb-(Ps6(92z+-8}>2!$Y z?uLQ5T09tgEMoQSTwEMr`)}PqO+qv5!hiKG~fTGFzERuj+4D_+= z`dB@p;%JpZa!-s$LP8D_6MZn7D_~BnLQZxkD$CZRvTg@^{{u)(p9q`hE+i&3u{PO# z-bVMYtd>X+jx5^mht{mZgX`De!3}G0=l@%nNkwUH9?J4^*>MV7>^@yd z7C4iw@TO;A?eu9_(A|w9_B-*hbK_I3Xv<2)q?~lj^VoSDuLG0X@z}z-IJR&hy7TO) zNid<_Y(^Warz<@b(`;Fom7jwpJ_j~dl;FYE2{^ZGJ}&Oqf=l<^i$knmo%J=?xn&(* zJ^ut|OzA?IUkTt&`%<45H6u^hNW}x^x@q& zd;eBE`^df6vuQQj>T2O&&)&zLWqolWlMi)d-R1SbpXY!-*N$p$0gngPR#SsJW-r2- zLuYXLr7QUS?Jw}<``_TR_rJtPZ-0gl-ueXB-uxIJ5UhInDz3fpAwIhJDL#1fLk_*J zT=)=2c0L>eUTy?ntz5Yh`}Xa_fddCP40`67XYkl#k8z+ib?Q_+@W2DO=bn3T|NZyl z$dM!1v}qF-ELeaYJ9douKOMdgz@onqFTVI94j(?u<{ND|dh{rI*!Vkn@+7uy-OAg( zK^p;k0s3+UKX-PaI z#Vsw=szyjyf>1xzeHNnUrheY?bC=WVyeX5zyAg&P3tAd&e8}TLq}7tkX&tN6a$WL0 zs-<^T1Z$?l2w&}PXb`k@Adlie^%&En2mrD)yXYAf3L(+qw6S-wjpb~0p+_PAhUqc z^t+?qruYsJWRid5YSDSRhJZBzHzEFQc~JrR;@&7v^ha2IiEo)2V2OSU7&h#d7!2ct zwX66hl7w}qEcJ6&=gDc>k2F5yzbWD1l@R^!zWjIVr_fj-mJG1Oo+e;wfTgy;k|9<& zfF&g0744sxlZqGaUyH@7w_wtugQ%Ij4h`M+VB6-M*t2{mCig#tuE`H0JELk$0E5%=J_$FwFFxlO5x7RKoYlS2u6Lm#Jrs~EC$;tE)JMMWZlDKeTJ$3!Ws9+IdZ0g?4pG+BW~5P)NfP~v#eoGpCzR4#rTwDbfl-DKQ{~WSid&aR^eFxWSm^G2s7*JP+*Ej3ArF97*S(QL^CVf#m4mH z%nS^$-z2#guJ?Jdhuz166Wj3E%t1^p_n~uQBi?)NDeTy^8WUpFf{NqJswya$xoP>#yVN z*|YrbG(oM!ix;D#qk{vX&6_uKcty~QfYMmqzP}H^nm2DA@5}k~=TT5lfZe-yW6qp8 zICt(G9)0vt-Y#{gIauaqF}!SSzxV_zxOSHl)q zq3~+hg)r3mNLsv6Wq4o6%7gWltgt8;vjA8eFa-b|w*XU3 zeAQC-iL4=LB2Dm3OjK!tPUl9lz7m^UpO&=V$#nKE)$nN~01<9tsvaMtf$86WeB6?v z(Vovp=SMmhPT{Umj}Lhqj79SJ;NOoijE~VozYXCgO21cvHe}JsAyVKsDn!2x9-E5& zrf5&US@k*Ej1Y4&@!YK2(mL&n9-Au)vZH0 z{>@Q+f9O8c-z?Dwg6Sjy%G3ah%F(xmBrHPdI*}*pqOw{V%Qs^*(fIgti-ScPDVV$L zHmGHVrMAA3A=XInN)51t3!zwv@bJt+JiC7FKlH9^lspvW9gFp3}# zL7zx&u@w_b>dKa)zyBcWYZf3k)eC2KB`oF)4gwV^0BFpmVpU58Qh()J=eyRg^s)|bn@WuO1!K|?kr4l zWpP+V>apjb*Pe|@4ocfF-JOF$iksyQ$dQeyIhmO4vSVd=309R9(`y9E<`ZglzzhBT3BdQCZI)>mS2#{}Fne=ZhucA_-PhJxf2c$tb) z)8I=>M^Q>D3InRicVffLL3Gzva<@W{IT0lmGsd%L(V3l&$vIhARN%p`)+U_aun`Zf z+K8fzEO?Ww@EYS$Y&4?Wl8E~B6ttwJpd&Q}U0JE<%SyrQ92@55#a!}%Sau-4lu>!7yh4x%{^0N84>Y_r_GBuW#Va1$9c;fIG zTzmBceEQxOLjddjm#^ae=Pz@(MF8v43s-RIwGX&;*84A9#?kwZhk%zG0azsZ?yg?F znjbG*xRATyk?S6Pmk1;k7Z+pKu3cEMVg)}(>E+9phtv~J-v?k(`vl3zI*eQw@4D+Q zp0{Dc25i}~WeBhxI&_HliPG!Wujf`|WSK?xL;aNNl{FH;67Y(oSYMR|;MFj|%E?h6 zmIAKS)>k6-6#*=H)j_odmVj2_EU*ZS2$-b?E8G-ALDu zR4!cJNasgOYv%`pC-pt3%gS|$a-*HsDjQD2fi#-T&nHR>65U zyKVujn^0t0D^D22L_(fis3)E3$tS6$WiVtCLmHSKnkVw*b2Jg8$rw#MwXS{g$*=i@ zj=&A2X~IVnE;Ybfwen3q5f#^}!4Q=rprp>D@}hn*IaFICkZ8g>5GX@!{`R+uTMzY@ z^3(up73&*KJZYmce9{;IO=9v$^@;LARKNU8=$OY(ViR(jtkPuqg%_0I%yg{2o+SDk zRBxa@`B}>C4&|xJw=@rioq&!c8BWOKL%v7(zU6Y_*~`}qrAIiYt|ur@N^42$I{BPj zM&14cY^-d$>%HM~8s+7>)aPkDiug(4eiK>>S6{fi(dw125%)pwR10FsX{~WF()bul zpTdcLV+4-GZ;kf!n^FHpN%Tw=D^A6&nD&$=YfEaEU=Up=$`iyQ*hHHeV3FwE(7U4F zq_B7r-xpDa>f`5FAA~3^ey{XQH{BHq!nh@B;M+$1;$_(Ph2S_{OZ^=JSie>PmfH20 zzL~U9-$kDKyjr_d$LjB*tdYi-`n(t)@;et}K}+)ABGOpnmi!P2XcZ1#kqB0a{SN_H zGQ<)fO9og%^IFQVee)q~*|81x@0^R%_b$bWoqO>7;RAT^6-KGF6a&0rlTlflh2w@O#l^)UInjtrs~MT*I1a87<8@rL+MGUy-1x}lkNQGZ zSfmIf7^1kvR=gn&7FsFLlmK%=VgOVn!jh=Ks$?sh09(^wwWP7UWLAbOmn<+E0}33Q z;}sFe;xd?7I)NRVVbmL0J7(zFJ(9bk*^mgY(~tV{7Wmo3)1FohSM~(7*Db@Up6P)^9XF9zuXV8t0Z+{$9(!<&~2KgB7^v%#Cm(&=QeWI=v%BK&DdsLV=5 z9mUDw%HS}oC0l`6t-0xFvy*F~4V_LKy2c zfg2O@ooI5g`h8wZ@fTuRMF|$MvVE0h95gxDyLPi@lFyF0EEaf}TDF|uyOSgG}V-$t7$ws8XM4FRfDdY zT6D8-TYp;%hg`chuIBE5JUBc1E%h|l;P8$OIDOw1JbwQ@cy#Y(EFGMRnqnVZtc@!6 zyy|^LJfJ(RNLZZjg4dpl!n_;~$_Q$exm{>1t-yl*Ie6@Wlia$B;$e{+;k7qD#+3`# zaQQ{W3X7oC`>$NXl~+H+wO2mGiGwFYz{`ySte;xn2VnhN8Vz7+TVM^l4+dLaDG~rn z%kpX%VyP{#1hArG8MMe?M1~}Co|b;>a`H8!_4CJ&sQ>%4bEDVXXnFY>`Fc4WEVsKg z1fu+W8VgubmkC#Xr2KH_Zcg0-ST~{Qe=%s1K>v%O23R9WYXV9!PsD^qJ+YDV!kwpM znn2MeU=2+aMO>DJ^Is0RUR*~LxL*e*dBTNHoEKJ9;k0Y#m7%hteKFysJ&6M>js6Nz z8JZl2D?^iL0k9}vnLPhrzNfmm#C z$#ITG6O9eIta^NCwWpPq&&e9gc_I0nT#lZX)+WXim80!gUO>T>~ zH%j05dsZJyc%=qdY6~m@ zu>`;pE`-x-3$Se2KCIce8yl8R#nG(`aBA0DoPTH^K7Vy5mdrea{F0f7i8UfBB5G8C zb^GlESE3Q8BY2aDM7efWs=2gW=eo1 zAs`dU1hdhIg!p)vI2!(0MHY!Y19IIX3n*ip3C`>SOsMQYLw-F9*n~7cZ#>#- z7GUii$1s0jEAlh);mBeWaBBt((Q!OjJdfoSL$SXopnJeIGFn-QQE`)0EU>uCVr(po z6#L3(Lb}z$o=+z7?K$u|>~QC?v6PvC6iXru@g{DCm0}{W7OSjqNY-0%WW{Dic3L{O z+9`D8z{mF4?3xraduEAo$Ti0y-x7~Ps|mgoGfLAes7SM-I^Bx#8CEo9r=m441D(zs zbh%vI?XV<03EosQeCZa{PDK_fsekd>%{ZvST*p2c1sL@wl+a zI5Bk+`icwC;PGHWz6%q)4zw4#(d^DcM?pUN%1Y2%R*adAwV2va zjUrnnY;0U)vvHEk-eop>m$c7e`)rn4j2hP83V$Ig2~?34R-p&07tg|DhxVbdv;-|x z6=3y5IJK??!YtY*=0r^e`itV}F%1Qt%s;9u2i~Q^?4koD& z6yUwWlh4W(V@~e?P91!lL#z+qqIg%I;Myx6;7R~qy?6c+2UwRbT;cA758wMp2za># zu*R;D0G6=68U|PuTv`B2#J^JDm282f4&bhaS859^d6hwJC`7PBaU%?`(azs2`g!^p z`V4PIdGp&Pkn-a~pRu|6$>oEu3AUyRJwL2)`F|d|1+Z>H$&-cA0G4_ZA|@wfrrSGd zf6(OR`$$+9Xo=3r<%P&Pg4_z}n5?7JP-fhBX|D-7yV9~WSA*K7GI;b55iclND?Y#BoKk&(^+&{V8ST(69v`AF z->*-h8f!i3a>K_2DpsygT&rkLq8Lf)_Ze=J;S@mvHR#d;SOQGR`2YSP#sQ9o!4 z2e57i(fH7E6B{eU64wQfkDo?QKJjhPJC%P|v?nVpZn>p#y%3d^;Um2-0#^cbQytVE zeK!QOev|z+?!&5xCNVSX$OsvIQ2wD*>=();lqO);9Dny&p|& z-IzITI@YgTgX6pR;fq)A#_~CPk>?)ISHp{n&=0w_k(CuG6lmRsNOqori4zQokJn>% zy&b8k>9D&ikeWpOFTnEFG7MBYVdelUumWKOx$u$xN`YCdE`7}HJa9S%8K+?5w0dA# zf*!6+E1b4edD+Nf`Q%oZVm2VtYC*ci%pr`~5W(YR zWu&p^m646K)J$Y$=E0roM4>YuMXr2!ogU=pIpEI8W9{U?o@qmFdIqxD^RuO-Aj?Ye ztgJ{+wsKIEn#5#DyuBMN{!q zET4Y}%jWDsaZU+5X{;}-y##$ccT1!|^KrTuz9OQs3L~wkNUoGhV0Q{sPu5q;N{HkZ zspGDL6w@ln%=(mMW&KX&Fw0@ff{h(#BwKj@l%V&qJkYxmbY90@5h<>giLBJvy`-mF zk(^|PJ1YlX_AG4dxn`K6Vbw?Rl^j#`vB)s$k@uMW2hMU2N|lkd=*oryVohUd(s9v9idEEtO?B zJh2(;o2t;5pM!=12b%MpXvueQORVO6J3DrwtJKFerKSRdjqKl%ZWl6H-_i|wWEu_p zI5WY(`c2X!ji6Iz2KpNtP{`hKiowY4PshsX;V{ObIKjv*sV1>=3q4M39bbpXX7r=4 ztO!X4RxX8&gG39=F)=X3L?W5hnPXw&fIZ8^ST<(aGb>{EQeRq%YIYyxUN<%^UyQe2 zIEzKIXQ0AYi29O3)Ry{DPAdo&c(}ToYjNht0W6r_!_sVgdfX^LimkbOIf*!RTmbfVnjh2QQ%vE9we z6k~SZOq@Ra7%pG9j1LK9z4kG;zPj|{6})@?eeOzl_2p|EY8~G5!(w0wo!ZrjPo5nZ zlTPpHgwr{Cd?}$H3a}hbHwIQ7!?IoPjHtf(`$MiBO(Ov;VSzQg3L#lwDG*Dnv5%Wqb_Ejj{p)|oO|C3eEjF9TL9}O69vbWCkvxNEO`Pd z0M@jrk0KbVggaKJe~50jdVZ*Gv>!KG{>C+J>SI3`V3CH$$4}p9MK|6KP5c#WnCCb! z5XU6i$O>lVir0rU45xSSUH<#^V`?;T zC8Xs(I2M4VWqmagz*1Xa&8W}El&KrgF=sa%Wj%2D`{Aouf;ltp!}BM1W5LudNKAGh zf&(iGARdhfZiz)PqqG1P1szua7Om`;syE=y@=WBVq#?&s40Bp0l2Y?9wZehPNTes|U`y1&k!nP~Efub8R%b>E63qr! ztVu{owxG=C#N8_w;*s6kFtM=~wsZ?JQ!Pldn2==Db5}xgKTIHts-!ezq}kwgcv0i8 zKy?YJ9F@LORCtR~<}E^Lej$ooY_jjnMq-H(E->tWKzaW_GVXQhjc<5p9#1f6Il#TW%%@fcWvV-EgwWSM5*E|b;- zf@=xfN{y`53=|tIhE{E)7-33Temz-uQ4Fytif0zZt;;ICe$@GkQ9|x$*{R60CLrCU zz@Id|j=k#`SoN_;Vb9rSG4o*PMYeR5vhw9FJG)O8+k5!F#_d2|zMZ@Mbr!hMTa=Gp zuM1N>cFgoRFx&0KT(Z0>^xzJk3v0`~*fPEXyV~loxV{!G?ApdcCwC!iV%Ig3SUrvT z4m7elI*SX??k_-BX%TuW%P>CQjqF5Ips#wQ>yoINA8pcw3n8lwYZqw1AAU< z{90n7*!d{f;-cVU_ga~hh>4kLnBmOB@{%HSur^Z?$d%QKOtS?k=Kh7L@95!xE_2QE!v46+is4FW*Pg6ZQo5!P`^|!8~6b;oC zEZ>KXcPzjo`?sOBp%Tqi73iv|M{8vTHq0HssU7QaYWJOZ{NB5<_s%=e*WSu4?I`XQ z1#zz`Vq=>uu?oE?aobVI#+5fmfmlVkb`-OB;kP?c?8(PKcOOn2IF5Iodk-JH`Vp?a z`~e48?>zfnASTu|4z-T#I~oFBZWLhoi(L5Qcgqz0-DdpZ@3!I(f4!dVx8eW$>vj0! zKkQ`3+wsT0-_6VXuTK~8Yvg*u>4yTWqLMmnfAW8D9eUy4aOlN0__{PaMAR zKl$;U5C1CU+R-!?fTeaJlw)Ag>VpKYl+_270PZ4)yKo^C@M<`KyEeE|TVjQC%@bfI z96XWpM=E(8;zW6>~}3k7_`u7tw?NB|>wKf1pf+wWSA(NL|`pZy5Lrd66sFvh%H}m-5E}1(oa}ijgRqN=OAk^_=pJUUecX+vQ zn;K4Sy6YXDM{ZmqPYtlBUV>8O61r;T>)d^fta+%N1@kWq#YLlXWZ@I)Lil<}|8EA- zyVZW@p<_dwQ=jMXi;Xe4-dp<1kobPc<3Rq~G7`KZ(TY>@->)BAW3j*@X+f;fTnI;k zSm9g!sPKQuyW=ew3PI~Yb!#LGauP$DM&UOS>MTWECI;`pG+q1 z9w^)vje2GEK>?o>OErQ}iiYw60o@H0+@0qKth!>zaw`(ifmIX9`id;M_-cwQ9ZQyX z<0AMqg$@_0yk1Nw^`ot{5M_27JQ>MwrC8ufPJ}DT0%xKkZ%QhP*!Zi+v!TXiM}58r z%|$-6mQsH?!T`YPPf z*nnlNEm**Q!<|*tXlK`TRFt8syaYXE!z%Z5aiKQj(Bm zu^`)GW#cj%uJjD#u(aQvi^IF_!I3@Nx#d&2+l@wFG1@DuF|n?Wz2_1%l@w#o)(v>+ z?4#&p_eeq3i(HO?%V#c+Tb0kAaeI9Q9(`~x2D&Hkcyd+6K9m-E(Z-(71NW@P@m=e1 zYWI2^+qD6U2m4S{Tnu|=I=AE!ZiKWi_jnYDmdonT$wnDjbFs9~VTaF^hYD{2X7xos3Lbkf>zuD>-;6YCzrw>8({tC|MLv~@Q+9FhyTj$KRd9fBx4e z@t?nY;!h5+&R_X=4y<1O=>OpKTmO!iKKS1(?|=WK04vx6tDNmqP zHS9VlVqj^lKuB`ALgAHGz;U$&RyY76=Z)puaGBx#NT6jb(zMQ*Tv<6^PTz=L zeBrN$ter@7tQNUsQaQEdm0Anuzcf@A0Wbnqv=M}&JOWY#un15QxFQ!ex{l6K-kX8d z?FeE$aQ{a`?UFm%0}p(t39x?1{r;E|V?NyYkjH_@m(Njp!USb}3~7|#)2-kC_t%a7 z{zLLckk);L3-nKt|Gta_v5Ja{LjHdJm>NqEceTC`zzXL^7|sGqSYb^aUyt$A)}f|< zBTAd*z*j#DPX824Y*>J&4lF}Y-9+f(2x6FUTSNq3{Vy0|NdPNi9HMzJaRZOtlw>wy zQDq8uy>mE|@R!ki2?!6yr-H28g9ESWoir%pVKPcOcPZ$7=ubOj&3^BT6_xf0Ed709t!6&FKG zGTNG&uyfrS%$z)kzP27rY3t?tzSc=xy)E77ZR|o%V<%Vl_;z$Pw6kZ@iq5)bbksGW zt!g}4nVPHW(Og-FrixlLme-=8v>f#%<)|wuLv1m+i}_LME#x9VQ0Xl~OGyoSsya~X ztV2;oIf`xL(N#GY%lo&ZqoN<~%t}_an%$opHfwT_%VLHli9Nq0q$VXIg+05ZL?tFy z0tKTtQcNy_TSk}+@$A_V;8H{uTeK=6S1d`fv?9pJt*rtvv}pB2+Q;&J3|CYHd!IT3 zd@c{F*gXuiHDgYDBZpWu9y_WWIjG3ZLYXZCC0Q9L&P+#XW(H4JqF zK&%o>tgJ$JbuA{>HLx+*gn^b8%xr7Lto8|*)7g&sofENu?H6>k^Hl`rc64HPdne{h z?83aRE_U33dF_L0+_htBa;2+0zQVAi|Oy^pt^dYfBk9p3xHT?mH&*01isAO3m`{_wY3 z@Q1(IfIt5IF1Fvu_B-&$-`s~k{Fev*WB_a16TioUU-uz!2U_HwA2VeL%mi~7f zf9nHmJDL#^FLHd z{XeYEk$_Hc-$T!jrf}DU%U8~6gEaYk__TKZSmpJ$b9giyhe}957C9ZxYD%lDavWS< zofmp6xAm8=Z>VmmZLRSkB>#QU0#`z%rKKT%zkY0u1h3R_uVkqKmKtKoF|Y){ zqREjOVub@(A`VttO(UA7ZA8VSW$?H3qqJi_3L0l%V&fnl-!U2Ei+qTTA()}pu)Z1w zSV9D#C`OY`XM!#&mb?7TugykodJ@tcJ|w2tV6kSQ!EM9jawja71Vl&OrmR3X1hB>- zHYy5<#&}o~3`nEZ1}!FJSoFwAF|)~cItraOloh(rJ)r^ncWlACFF%bhuU^EjK7J2h zGkyE<`}q39ck$7?uj0bllUTK2E^@Lm(LJ$+yKOynJ7??N}(>tf2zr7FB+9qRa`y@=6(2c&9E=+Eoh~Ab?Ok(?j5ri#Utl9-5OvpL`{ zs05v-6&DjsCL|aFfQxC^f=kC;KGlkej^Qwp_VMhRvVua?7Zqad?0#&SKNGXtTQI4% z5}oD6XfG~8bD@XFq^i%iqt=s)I(IJW1FCiApvK9LJ$5wYJGi@FbAbn~MFsf(**ovQ zF0Qoi|FHLJVvjXOMS2J6y*FtB(p3}@0qMO;M?^)jfF10;_YQ~+dyFM!likf`lfCcz zd7eMw^PKC+X`*>+?D@XU?2CGv~~gTyL-Inov6%M7TI2*3%7({CtoY z6oS;SaAZVABR4J{x$&_mSh5Iti{nw4un0wLyEtJ9iWVdaj>E zU1=WN*mHB7HxI6Mw(xdwf`^km94YUWvlF&9R-$8b6Flv$;A(3P5B5ChYlANAxU-El z<{9g=b?A=+t?LoX)_btK8(W8=hzSnD;;{MHRFR844TWfLEXKB)0%Rn_z{AlVhT1yZ z%Zk28NM2Y3v7F7#IlQvao6AKI%hFJn!!`O!A$g8@uraKRPr`w%2YBwQt~1@Zeew>j z9=?t%hpwTeZi^at`MCg#bhb50E!UMMHJ1jeoj;gM}E;kf@ z3BU>sEgERps3bRd1{ghYgB%-aw(@`5^e;1y56PD!s>=-e>CiEA#2g(H%$TVMcQZXKbkxTeGpDis#pLaj_i8i` zU85XM1YhQSJ{?*!DG~W}zO6TBCajEg5a{iIn&J$c+P58#Z(qV!y|?lD@twZ%-NQS0 z_24$%Jn2I3?aRnWTnc}0PaHe29WNi=LTh6ql4F)}5y+x)MNA^oQm&-PrC1)Bz?B%e z1j{(!TEu}@LU=5egvIp3tNgIHLT+5$UHAd3E_Mz@qu#$YIw? z42VOZO)vr-A`$Pi0;Ms9SmM6~wtDXH^GrveUpibY9pPYV3OiF1?mc5;Xap-GLs%FZ zz|24org|#4rK1fa?YaGMYxZpDGLh$&4tZ|PoWY*o=S(wrlKC$<;F`{!@iY#&2o_R~ zEm4%fy)QIz!UPV#+-)iB%?34;lc}l%B}vPW8Wq7krV;}K5bx`WXb%@GbfwTfJA^t> zsG&6i?B=m`WC35wQDtcYA9G`PnHj;;!~h<~`tUH)gBRQOWp)0RW(cyiVtqIvA;1@D z3&S|LDqX$|eB}z%q^6*5RT}C^Y%SMiurhNM7j0LjB%wMj8T;4Qj*ZWeRlI+7bZOB(6DACh;#38qAo1;^iw)m6Z(x_RMsrQ{wp&R9na2~i91yyrR!QdjV=`gz(|!{5OH^Vx5Sw~YJFvf{iOr)q zPvGw7?u-y$Z}_@7!`a#jPS!S99&WDzj5~UykM${JL(|=Ez+Zhuw{(*jZnQ*1AIOg%uU#$3H+|u1{WA<~)Ru02Yb9 zL?}Qk9qxTavNX`;0EjVQ*No2^#_eIH%OY1e&$&U}! zr&622jw@Y9-nXWGdA(BqO8qMJCEu5yH`uratCwF}-bQvTJiI~80G016feC3{WW;(b zkzZ4OUHKT~$Cd6~shzZ5(={c>pFRDF=cB5x>qd6g6_l0U;vsw#$|rBH2Cx+RlkSTE zYv+!qYT=1ek%twv7Xj9$jSu*ENOVmOu-MqtuA_8q>A2*_rQ?$ymv76@RXQF|>!VKb zON2^NS~qkqt&c&kE5Ek%xNJPbYBShzrR&K1*0e9LSL$D>U!}g}`||S!8`og<@@vc6 zC>@huSH7)Or`i^OKjdqHB>(%O30{%tZ=uMN)y0R3Ln%2u&6XP zwuMt@8f<)GFwZ9xF5#=-5tD+0B< zXGjXLfyvx2FxS`~dis`_GusH>wk9Zw_eFGwKj!Mr!npBtjnO=OjY1D6j2|a>Uwu9e zb7#%qpldF{D|166#z)}5)-~w8bsBFU+{D|*xAFFA7v3?wdD4luPrC3m)BD~oJim7n z%}q6Mb+pET-P`b0?=3v-zJdCZGNdm_K~~}_tXi@Xs}hotwqym;7AJF&@tzX5oNHxl z5| ze$Flk^LEGP>Jl8;wjM2&rKrx%KxxVf6eTS~Ucw?|EsDXa*o8=07>4ACP$Y!~BQZ1x zOM?TjB+w7>eqM-XeMGpsV1bJRLLF@pY;TSE*7FcxWdVOHGXz+hBFNSPQ67$19_+_G zuqu+1P@7JmDjkh^IcO@##fIWSY$_?jrt(s>tS)2YDaR&OHkTKnE+-vl*nD3)uoG7f z?Zw?o=WwcHHwQTcp~w?UXWCR~vwNgchut$T*?wZgLUdoc$mTE{7TOdJs0SBwOZeD2 zz{A>#ZJQy&*AsUx9!FhiE^G{RVP|9vTN5KVS(?M%j6wtrd01Zhl6Z8VJAuUum~m)o z2n%Bam>KH9l$}E*CF{2{)yKZJ4OmxM%)fYr-$gX7UZ)0LMgZ3EH9UYd z@GFD^leqUMau?v02(aXNu#_N{lJ}M1fi)Pw8qt4-EG>f7;L3=8dyN3Bk4#DcOA4}v zf>)xV7Pbs-%nY_KFXh|6R3D-bsXlana>@Ib?++%Wwn}w!4Wms|B z9gRf}w?vVrm)f;Hgp|f5ua~!xNL(NCwIN?0^7SK@1hAqOZXWjahOH0Lhg2WBKe^=n z%l8M9Qd^}uxrWn5uAh01e0|6z|2rf9J0!}(gK~(d{|)<48VEjU3+v|sED>T6 zxDrdb2bQjpEu6wrVc{MO16wy(c`brda0;?k8J?+0*ga zMxNvkYzPxuG-#ovIub+3~?K1&fy{G+W-FQcO z(T&%SJ8|*kLHPT5p)e;MFX)^XUFf-f0c9Dv$X=d~oTLn7E=@yLVk#?Bkdcsz^rb7g z2yCUP#J3kGBW2NYK_c9WC%8o(T!I&u0J)Z8Mbt7b0$m((EfgTvQl=FP<59mV6MI%y zV_$6(j%?Y9eT_}nSy+nphDKz^CS$&R6vBNHvCuCP5xzleI}i)J=JT+`V0T{xx>7iz zJA9o8ZaKr7@^0BWz>O!Ew}F$nC5Kz~s;|u1u=OQ++F0sq!(3Mf=4?*P*czd*H)Cxr z7|fjweJxd3;w%DM{ZLD5<_xTejmMr1>v8VTE}Y)iihWzxV{>gank!1sR9t{H1-Yot z%SKIhI;zMMYE=p<(pI88H5p|oD^QZWoP(}{#02CdEJ7xSU6I_2Yeg94w+hDckU%7b z%ttcY&Wv7&BG$HMRVvmO{Zv;~S6_6%td%)0v(X59KgiM}nM;=DVgMiO z0gUtk8mb8h))?KGuRo^fX6PcTtVD>lBt75cLRQ9pIW*rRO!>P$Z>hO4O@J|o3B2YV z0ge6b)GQOU<}APFJ84iJdFUx`{erVPV1n2jaxs>_#;+&G|BJF83eVX$ZKS@L|D1|;37C)?V8mg@f_ z)*|`jP59_UJ8a7K5n=}%jr=zz)Rv$)yO9fzTrlh$M|3Jn~Y}*VrjpmFwZyjp79hp)Xxu8m8p4nKk{ze{p$`SICMBT zBCfEfmok5Gq7O%rQniFoNg2p%q#yutRrl;C5_zn;BH9zLALy%JX5Vj}BNs7UZVS-K zz*KkoY(%>=wOu`Jxb78H8isUo@mA;bxmTAcP%#pMW#T0HJ;o{15MQ`ZO@NG+SH@rU z2i95Ii!2F;NIDiZKOH%hW>!pfry0)2Efq*c5gF-dgPGza?u4z8hJbF3GuHX)QBf&1 zO4Oz5ftran2g^B}`nq=;_y-dWJ1m^3*ufnTrFZHK+;Dyn)}nu@Vc|5L#qAyb0&8hh zC4_6*97}Wigqw7z`-`@?OyYTdwGm}@F*3!i5Z~{ z@)HsR%i1;gd?(h^Gxc!ri(K2nx1KJb({u10FL-Uvt?7ek?s```)TYLrqX*8Sb9tQ_ zpf@z**=F<**JOU`#Cyh&`}M^D^x0}Vs`-odzuSmjXc_FE(i<9th6*{OUBmAC^UAgc zo5KR-)MwL%2l5Z{^+u!Fh@moYFVaz{LypXSO zxTq3n^iZ1h#7BbTEFo^@#Q3lMI|2aVeG;rXt{N08wWqiz0L$#)EXZv<137J8*7TBtH&jT?w4T- zc+I@+?_58?Gx$6NC3)edB@YXIpEidu)_2MThqBo5dGx^U>rg@aJ$cO!N z_RU03Us-%xdE<4%rMRW=i0}(ML%&hEXYIH}x@xqEgv~&g_8SZCE5dyfF`2nrJo%k} z_o<_YbPFgIsnv-0jeR^n?2C`H_jU>20M;pQ{Msbx2YMesQUjqb7w_S*k6rT1E-xKz zu4RrrSMZ6qEB=Y8a0=KhSsT$0cS%J3cVY;e5_HiPqr(68^iqEKQNn7aiy}xIpRz&o za6;dW^Gr4~5S7!d)`PH13z7uKHIz7u4yl5*oo@VmJ<`=_R#dv?}x(1+mb8RTgV-5&E zb*Vp)uX8x#{S5Ovi!Tbe^mEs0>1%ttdtk$H?`yI9_5IvMXPn4|-M#!W6@01yIzGgT`3CnJn$pHw~`#%u&o+FIysb7!NJp>f{M+_-4+@Q70oz)6M?hS z?f5{fto}3@ba|NZ*mc-rEmTV?6t$jKVPyL|dHlLbK)JVo9noy1Z2rbK^zp?9FD|Yp z9`4?uN#g9JoN(W-@%;5cOgk9zHEb+FL^?T~w(Ic~cR}cEzXa^?tZhUTZE$YbY8`gR z9shNCAU!f>_YaW2I@r1spq?*BKv!ne_>TP`v|WjUW?)$EvYLY+TApY9>$5o+ePsFj zfZ6)8Rr1VAyHB9_p+YY(rl?_g$iBH0YBMz z*?;W4htWu2@o?F*0uB7L>S%oFmT9{gLuGr;-v!L7Oa?x^8f@&0tP>y@+4QQ~pvoVN zhlFdg{+U?V+2_|IvbC+~O}x-Su;@Y~=3L|lbnpSqJ2@K>Os3e!*8>G~H2(1ezu3@4 z8qs+&J3fi&+i5fJJ6NLb;K1x$EYwj;%LUO;l#a_2NmU^ z^Ko%@5B0ziH@dx*2VJ;iHn^MF5iaWjmbLNJNeG?oWHa0M#_tUbm?jz|?5^!ZeJ#)EgBE;HsZ-1$Aaxj%NG+ z;gkst%}qFym&e$<2;Qj|CH&_GGtrPS-yK<^RcG!fd^?35Eh1PI>usBt#1DGugHKLq zmJ>sO^(egXrxc}!)Gq}Z-UrgVdK98^OWs{p$1C-2YLG*mk|+L?p8j7M%~NB1sr5lb zm(!c|bkzB!)56|>`-NsEOht%Mz!$VD>pjM?>}d6QQ-kE1r%YwfgkNt=@a(wn{hYRU zpH9({-M;zZ_;5KiK#b44q#~v|@;!M`W+~Lm>jrq7BX#d>rDIhJn3RClc_)0npI`ez z80wVqq2kT20&U<-a^tgSm$YhSO)kV3Bk`{J*+ynhcPV$)Wia|ku1De|Tv*S!XE$)q zlC-ybT1^7@EZkR0n98pQ|HU!`Ie>snb#-TmbiJTB1fv1gO&61x2>t(HLplVG%msjh zkcnOaLXMHrFF7S;PyqBr;oo)_Hvy+VOIp4KERhKv-WsE@izPSe!Yet=ygzh>B2CcM zoMH$JxJUT*c8PKW{^8*%zC-_OkTUXTXnW*g$HBronF@?)6yzTl8tT!8H0<#9g0~0q zwQR&&EbKC()=9%OA!sU(#FjpQ*`B-TBmaTBy$z1N0wyWjaVW3@ym!@Y=RLB`T)w;V(GG^-9X?)+r)4Mc zwY`~IRT)7GTkNZvS$$k$WG^cPG+sZPl%rxL^(VTx$20l-9DGkzcG~5c zKZFJD6E}DF+Qv^m?Kfms90zu`Kyu3H;-Kq6Nf75>)9Y5|*%{HF+Hk*f_yUKPn6|c~ zZ;#p?Fg0Qbx2BKAKh_D!vQE$qXRR828%-2RRC&9)hz`+Qw|08Gn;rg&EnBpL?9nC@ zdEIt(Uw=0;96|A2&gQ!53e?7)uFkwSSItIag*v>?8~x+;hT)nb9H?|2`tx(^0q}$K zhX~a);268p(*?d7*mm_W;{EoB=G%KKwH}6aw+$N2?7&Sqd;iO?QLj+=orq#k!pZL| z7HiI7l+)iU;Rkv`4?&vKPF)oOaH4ChKk;&P-NzF#!3#&j5EyYeNktK zmXx!jIcQt%$^+&*Ehy*9aA9k)FFa{_54}<&s4}4$9zu;(eE(ErHDogRkxRG_FLBV(retYe z-!6u|oo679M3P47i3f(Y;#3fzo1 z{PN|wcEl4n`SrF$)d#7We|=nR!eVxYmnQ!X z&3_Ohn)Xhpi9Z>#XiLP+ESA--Mn=@t9gG6-06gNutHBfvBS!|(Cv&A}Dt61l=(MXs zX!6^}t%5H^a0BXz{C$2eH+9B4fpf@sebo!w&gJk}enBY|NgAT1Y9sDwv zp#LFdkw()An)vglx!nf-Hz8l|nmL1l*kG-xsRL7$=|zjgn&@vvq}ww^UPXtk z*?x-=!I2;`emEKAJPaZreETP9 zXp-32IJO(i?Np>!M-*J539~fj= z=RAJX&D=(`*F;%No!pL+rAcHf>S;{ox_Uz^{=2ZG^%J0aq5T_wcrb$hY;_(%2$xD6?wJMF(7&2%6V1WdpNTH8BNIG|1XWIaJ@aPW|2`Vrsc&gF zx%dy$wsPVS09q}(sVVx7a@`~HW)l>$>b%vzA>>YAP3K{RF;7;_0_Axpk6`>~GOMqv zmD56n*56b-|3;(7p-Y zMN9gs>}$d$ntHK|uD*~eL17JbR=Fzp`ISX2V*ggKlOETLm{4>&Oi7ZHuxFB#!`5Ar zl9XOB-?bd8LUQx5cR2RClW;Egnrs7p!iT`>*XnQ~jQ8H*XmxHqlWZ&TUSUxKsUG?4 zM{*VAW=iUf@!c-p00vjq4&rmeEBb4#%hwX=vmFANwu=XrX^LXj+AzN{e%M2 zVW*MLNosHi=1rFYiArEFS_Ebvf^YO=GNB;~j;QoiL_0{n!fU&O8rn@+#v!c>&(lqR zI%{Zyz!$9^SKDX+N(vnP@oq}^F$}q=8AU7rmoJI@T@J-CI*+-xCXL&i{@~{eG`%1R zJT5trCLY0dq}7Wx(&arlI2|Bt<u?JS%|?eiBg0u*3_a3`@~in_-r)-+SSA>~ z&wGW-cGKJS3*W*FK1CcV!5(S@z>LGpo#!AvdCZ(xx+PZMz`EPnK=A^6 z;^?y~KQD*{s5P}v5j|FU_Ad_1waE*3$nngiZJ>iZX9JfMHQ${BGz6Ybj-lV4*P5PQ zH$S3IaewyBEr#^b-f)vSNEiiTi&`j4eNC^-BI1h`X&uq+x0ZmpwAHVYZrWchE zHTaxiT6oF-4H4XC5rOY^_#Z^jgU4+XcRSKX^@HzJq{J6)ocyFh`@-b*Oh}}z4e3LT z41fse%twANAS572-1}Jq8PV1USD|VbB>8)nhLb&uHSD z#VpdpQ-rh{o;|VP-5#5I-5gWly@Q!oP5c9pb>=5WUyFWbK>uRXNIUssoSV;r%CW!wyiVuw{=_*qA&3!%FCU;WA*}qH zo>U%$oEm#6=9dG%xR|uNHYEDA&Bb)Fy`D(yV!II_3#G0VTr$ZhrV#V@ZA%qOZ_ z&CHyXwoWU9urX`mr1s{SC;5*=iSbaG62cYoaZ@>bF>DR5Bl;~zq6`UFJZrlY{i0jBV?#4!9jmOKu$x#*C$%*c&cKS2g zaY>++AZpUrohz_jRaVvQze;;nUeMv09kLw99Q67^+CN7m=+?+@ zfeA2L$-ui+YFpq5K5F&CP;9FPho&Ho%S-{KxvtJGTw#^pQG9f5r3yW&sG(E?eme_O z9-%&#c;15u3{sl+z|8~zK>~y4~yCCbGJ9x^7VZ|zWCQX z?ku8J_ZVSnL%sJwHYFUO@zdO#AAD?RLDoed(=au-k?~Qfb{f!R2sI}94p=Tu>l$BFLVFIs z28YS|t?vb^CB|~Jlp@@_1cTjNcZb&3r|9i@Ft_te6D$C~KjT?_x9-X%dGU+3jHBBF z&cJVYz4D3w4c76%FKCNm66EK z-iE9VIjo^bbyYAG-sjfi>9)5Y(Kk->T9nPI6 z9f3=+uLB*`*xkw4hRO)Js+T$UTQ+WI`*}`67grcOET7slNqhG^j4+ zv9=*_@C=lUG3=L3(3!nb%1e|?;&gv4{ZSo8L}#9t5KdHWbg!lbF04bj^^4H46a75?Y9)kdJPRjJ;9!8D0a|k&Pp?}hBp3mLS|U&aPV@* zpNKl!vn5W|ZCf+q$rQ6~Q7yR1WQ#2)Gt}P;I6EJ!Nc^jfa8qcueHz8QS2t&*Ra}Q? zyXy-kPZuvTUcRU7ou}<#U9}dkeeb7F*V_tJIm>m=*D_o_o}Oqzf^DIfz_#nETm0Xy zXCgKLN|oMS3?U(Ga9a7+?p{A+N@5E-twm{N;M252=F##%4|Y${;TfQ_*;fbMZu6Jj z<3j1l3a5W*>f>dJEacC7=rTsHd+D;@?dB%HIXO_o#QH9fKXid__7{|j?dP+1_{(;( zssYxx=XF^4!{u&9b@tBZ$1bql=Nd1vPZY5HcYFK~bGpQKpf-PKa%>V0{r#eGqPv@d5!h?&bUpaEX`ug_N;NIyL zgaIe2FD|5q8Dn(cb=VrO zZ}YVDt^uVP7>pSKl5J&x*X+CQeBmM1q>w}N#anCb?w%%m;VqhGs}G7VB{CNEQf_n- zgyQ#R0i3Wy8hW#$nh5>@OyKUhKf;I?Lm*Gn9V?v1+6*W&p$S8Q2lld)Yl z!uHqx%P^v=Yyng&#RE_ybZWq?sk2XwX797 z$>HP+X50q9!pK*`Ee$Y2`${7n`At}Un$q{w%ySbOd<(>)BX_hN5G|62>uyxNTJwCNSyAFX^ zh?LTW`s>+m^i>84RPymYrtfuog8^Q-GZ5(c{J7J2dwS0S)d2)5?(exXo$G2t$lInG zQBJS^-r{>wGigu-^K5kI=nD$l{DS5m`8B%mr;j2)947Lht@(TZ9P-CxOtV7;bX((Z zzl@Hr6$)Pr&GL{Q**Ffqk1hU#>6~=qcDF?1T&Ol*dqB9m5eKEhzpd*5V#=Q@?%Yh4 zuAF*m)^$MER@i4zcOIhNbOL&)Z57lcUx7mmE6W{3^fm5cD8?&oC+Ey)7@dL$M&6!0 z%efxlb2scshCo+F?c>NGSQ-Q;N53B1n~L;4(oAf__~xaBOf5ovE&L-ex^(m#sFLBS zp})VwAV&WSHelQt6~KUC(CBHpPd<^hw}>@W!YHTwDT6gWl%{++rlD+5T!O_I0gYq57F`^CAqOYMJyn~G&2qM-~Jx`JsHF-oT;7|`&mb#@z5)cC=6%p<4Fi(Lx_zS@mG4 zSUKr^J=P{Gk-dFzY7=~8MR^}^aS530juVWh&%YY;@vVU`u_c#K2Wxkxk)9AfvDeYo3j2Xc-%r5t zwuXEVjSqKnsOm`gEbOlD!NJ}Z@u7bZ0+;=@#n9$2JgOwzmddIMzpeSB#{u=nqBnt% zKxb%w}=-PrzKl>MmnoI4}V|CWxW} zuO^V8EZiNR`$Py zTJMT|Y*#+?VijZWN29q1w`N~YFDB#Jx4BfL^9lJa!{2apa=$+Id(zw0xEq0N#sOYh zImCpS@$Kh!Evad-`Q%>bXG)1#gH>6Gd{}zKqS7X8a|>dAbtu|&&Naok2s$>kH7&Hr zf3A^@#txh&?~W@vNON>Xg9o~5Eq^0{O;|@$=_6u@Bjn@qQf*VnW70rI`Q;AJnuZ#7 zTJ8U_s+P=tg~i3$&~nmyj0#(V&G0w?eUwYE3kq@&TxL^?(xQ)>>i^S9FuU;?`!S;v zHs>Isqm`=@ZMf||h$y@4pFfz?OijzvA!#>LtC0b1+ZAXEyU}W8bJGv0M`926EYjyb zd#_zevbVw!5w^cFoeS?tt3P>817nTw9$7OvKVuR$o4h{7WHzc@46LH5-+iPhKM8K9 zpfvM*P};$6MX_LXYbZ@)Om|4b;GRJ)%!3%nv`UkJk+~wH9SbZLt65d~tOuT=iP@bk z>p^;=@dd8neSW%TUe^4j4Q%xyxHKMT)F1L`0W3K&L(Mb0fUxa?ntT@LH)?s}PsG8P zKS5K)r-lc%L{Y?Cu+A6Q;%pTX(SO zkngI#ftYKI&5@HFG88KxM8%1B?%2Z}haLhghhxaJw$Z{2QMui@+}I7T6VL&onI@Wm z{B3#TB-)W7V6AJbe7F;aqCdG@*Nt|lPPy}3W%u-OBJpz4C@kTjqKX! zh`t2=-o32&7z$nQy@p?Z%6%mEF}CyZxJD3CS_^f*7E`49aExuQzu0v!!NOVP>swev zx=>f=*TDAHv(N5i%nKBC@Ng&4=WhLVn=CoRT%ec%SyB30rqMWhso;;hozl$|BQege}7HccjVuTclKZ(v>Lmd$n7?B%?qqG_W)#akEokmQnCr92(SRptxhCZCFr14q&AUv39VAwJj+0aY@ zv9bimSE0IC{Ph15vlUz@#x@0{K9uggmwp}Dl$gwNs>rO# zp6(TTp~#%}-&+3OCpErt{cb>h<9#BADpasbSn-oE@vU=yRXP^MNw>6e)j6J6Bl(6? zb|~p3ZfRtVPR2IBhG+qeRb9aq|26S}?$o)P8~Y`u*3V%GR* z%ORm9G3h%FT7nyVsY!G zXcYL0MWrxQ|IOL3q!`)4hWv>~yL)H`|A)Ey^el(b607Mha}T}xDA*7pqZfUkZxrplQ1q<^@=G3&c7TKxMdBjYmD{HVYl49)E} zi{2%qjy~u>kDDHuUuOb@s%FFPVgTtZcLpW^(4NX&1jo?N8L>pYu7KsocxwH z-7U3h%T2bVZUb;eT)&3$lnA8}hD3_q5si*CF(U*bMM300(Cy-HYZ!Xb7?9hi36DY= z1b>#?)=EXU36y2p)vS)7x>mU@@9joFJ7OIDE*n})9J)@O)Oot?_*vEEvN_1b#kf1M z@9g2c&;Q|aOWS$g?r-1rdwVUL?`f>>_uKx6fY)a;{O0Cqufa;o=6Y*{@7;#jWzDWM z@)!TMXjpy(^)lh;n2gS-q`|RD%_bIfe+gGLqCa&&Ve`Qg3q_*4onvl?jIH?G6?@XR% ztWfu+8<^9doGA`wc6yc6JbZu^zS|ZE2tNoJaS_#8t)5^zAm3WP$r_yP=5+T4DOJ$( z^Y`(kj8IG!JR=b9ew)*QQTSDN49 zG9|V&@kfv01AR7fWG_6T@wcfWP#=I=ULi2GE)?J6+e~OYw&C%SbeHJzrN6|623a>| zFMP5nLNfRhLcQxTng4SkOp*fp3tF@<{@*HA6jV#@Uqs`PXtbFpieQEkB10If)f577 zn%9n-^(dgi>ZmuJLywxKGsd_mdP2ZklCfcIq?3QE{j6e)nh|qV<$W+(pxtL>cCK9r z(=HX;K+O7thk}tWx^Xeod$sKmQHb$DLk&>=>9HopnKIdVI>WMBlrSi=ROETwTw3sP zqnXgw;9eL|9q*~{d&Z`03Xl&7_2Cpe!B)~2Un566J8!?061 z&m2`IZz@ar9oN0be3#f+-WMX3mv{94kQWOCJ)lGP2Fw#w2#TZ9&%DZ_f~3bx$l}qP z5Vmt29YD?&=l9Hx_-v+BibEEOMaI4TGI(4*WP>sJPORo$obli4cbV-kOqWll{5#`$ zTu>McZGXel!E2oAl0I}Bu7X}mQp3%o)6NT>$ zix(7gMv-4eh>JMbb#4Qi21;QJ!2nAp&EUiVnr7_=B!TD^kNO$}w5F8Z?FW2*yYhj2 zJC5e1T737#)NO4A)XCaLD%R9I6D=6GL0ISNvPK7zvj}8iU@z2}4t~r#t!v!l!p`?I zeeB+~izt-dha+KIouk+k*bPmRqYw^4W1if_3CQxSKe~jV!F9y7J}Ae+3OuHVhTV+v z)GNJ11+THY!?mUBj~hTc_-gl5EXm-hbMe)~DrI|{BkbjcZXefr)0G|=XnDq#zM^(^ zxDsvF?)sj$hCgaB<~dzsdT8nNjE$!E;oorQG0hdy>yJX>01TB;!5fVfe`T?n6ME?| zbi)l$Dg5qVY9MO3hdqDzt1|(=N&qSgUJk~Fyw^^yWFf$ugy0^;>3OPRGyLM?W~Ydg zE`{wf(A2_sJh{v1D^4)u9T1RA^S7AXWE=su1*0>`B!RUND2k*x=E2XR+i{)Rh1&m z)pTe!1=SQP2I`)x)SASxdae?dl_O$0dZg(QZ1D~3aCF9^AXYa>u;VnX7X$YwP*_81 zJe~7v;tzSV%jPXtj@b7LC97T^zC7r_=OJV-fx!9hu`t0Xu(zxq45c<7-c=o>9ixFKpW)}#_Mx|AYBN&`AuUT`0fJxn7g5%mVRVYVnEBDh zLO4<`6}7{71YL0Vy{ExXn6-%j?O+mQSSk^l?-sqdxiQV_uZD8Ft!k_mT_-?#zTBmr z`D|VZS`yOG1;288pCmIkR>(nr*+najizEBbiY}!29;#1Lyeu%+`uDZS)$wIMwOyYV zm%>`?zFtAH?JjLug9OGjuhUXbx|%WzIbEto2y>#Q9%Ul@ZguBPwg*RqJpC7MsBF5> zs-UQiM#IK2;W7Rmb5wNB3)T`h5xB|E!;4tGV?GtwD3jDn_Mf7)!-HEf?xh9uy*~o1 zG^s4O=cS}CN^M?BSq5u&fu+IASnfmP4v$NTil1J-&zbc|h6&k3)h4$NFL!i;Ie{I& zc3ex)jxT%8buM35r&+YCRheLwcAoFn+@7Yp0oL}u{DxVx>G4qX*NR`d5auC)oOyQTF4}j2Rq|Njt~Y`#$H>#2&|99%50ZAJ@wXg_91Lk67>-5@Mq`Vx7*7ul|7E^aH}%70 zwm>G0*$8TmLOzojc21BWa%E0Z#A1--FP{lm7|e<}o)a9>wIjkyPZyb5{-OC`M%#5CV;g8=7$A4(|1}VsSRiDNNPkGRJPJ>gRnY3-HR?Zhjqf zMAV};Vm=2y_RQFGxr@JXP_BXdBKQg+5LEvB{lT6uAaD(BSNs(*lgA6Ht?|5fC&=Z@ z(yA|U^3($m+v&0tywoAk?0JX&SZmE#**AEjUBOgpIOs*QC^N6A8if)JSWd`^CW6)C zR!WQbMLE)}k`k1$Q0`DJh^*)O?WjVw?|yc_Sv4W-7Lep1fb^Qe&>hnZVT*b@7=rFz zf#M=*;z!QJ1=nUmSH6aS5n~s>VHt_kJ-IA=rbjsHznD$gv)tGCh&ir}IXISeO}gAV zopZn6^WrGcQH^ZPPgJuyL2OnPQ{q(H2S?&gD61bciE?^1PXd^ZijqiFt-~UP$2?Xay2kS8anUYp~QaXAYalBqP z^}~BemfamR2m|(y|vSGW-PJ!a|&(KXtNQ=%{PS*N9$xFxUPlL zI3OS{1wAxLVn&`t6WngVnY1EP4Rv9t#$8`i1|8}+O$x(lLz8$ybzwjWCS(q;Z!8p& zOn%>hkJQ^O!Bxb#l)_wp%29r)U-lhTd5^)(W1C&K|8gsmbZDsAAq{FgC<4``!2=%{ zF%WDvYjKiW%00qzn!sWU&30R0{?&j85dJ^o;^qvZYlVWGD~)btrRFE0nO4^B~K^2)MGc6iFd%9+5h>18)9J5JGG8YV>7Z)503J7F|f#iGE~FL;w= z4uun4f|fSMQSI}pXREF7f4=Si-?%wStobhU&($><%)&yCWys-!abvIq_{Gpt@u0l# z#P`=E$Cm}mAwun76OhyoDOuK1L;7Kqh}`e$TW_iyeZh3vxxYc4$-|aZec^wT5nu`+ z%BSi?cLpc|Xss1PauM*Fw`G@ph4Z7neCg$c(#+C@ff&BRdc}%XQ2xh8D|wZWdm2Hk zt@`k7bf$ONvVEegCSHUFzhGV{S_+A~pJg_!M9A^q4qF0#8R5?oemiN?C>0v~3c~d8 z$1>|%o3DgP`QS`|O4ycuXDH~om)E3N1*`U1?-dqLK~oR#SjCTSD6J*d2 z=9Ck%Rf(vfkQc*zmMynIv-Acc&y~D!_pwdIwTpJDoD>qAX|kt6gbVfyUxe04_Pc(? zPAb~?oQi9PlZFXuPSx+VYE<92vKSY6I??eqDFR^RU%G2iDG6jFAKFYnaGhXBGXa+aXLg*d?MG`&^?yTb6RcRHvNOoS765cK`Mm9F| z&o7sR#K0b|B-|A65)`E$D7hpM=@*iv{Av(5kaIi&Uk$jIu zjzV97OioRL)hsxsgqPU4C^lsBPC1Ru^-Ga_x?lM250FVBi}wq=d=_U`4qN=Uo*aej zn9^SshB%22^Hvq6L&f9W*y@T~au#6Q@i`R8MH#ZTc9C4jo}hM)%h1e;h%JHZ?_UQh zq{s)*%Q-dua!hS)2epxz&!9QBnZ20IZ#s3{^ZxWQ)cJ+R{8lGiS!6Dgv6nvX4IlhN zG=uJjUmDY{+xV+Z7Xz&)3d_x{-v~xeYpU{)q6_ymHMAq{2VgB3MI?Z(DvK zWzuWL$PLIjR(c>-;W7=XHF}paL*hE&ZrhrFiJ=NM@)bpQ8<>*PDL~_7a*%S4LtdP6 z-_ahL$3BWe>8Y|rRVT{#F1q(;B$T&9eeA)JohK#<5`d{r2{AI*5haw58Ti;&t`Nk_ zAoJ1$DzZPd<}HqWRlArZG)!*eF^*1!cN-Yka*}{0zFd!NI{dl2o{a1W{ueqVg|;(NBj(|?_dT0fAPAQVb$g_9y+oHV z5`sYIX?3}KPWDNKD0qQVTw;fx@9^3CrPh!uROMz`*fFQ`2lsbVC0I}a;-ZXbO!_fxr5jZh7W(#PaGx*!#057Oi$ozp3Uu3q2IJKTRAj^B&~^&Qwb zL_y{7p{|j*FuO8`9PJl{)y8hO6c_d+?$=(n62~$QHS8gEEu~woW@e0Gy;qttMnM*6 z7lYgD8QZ&-XiR+Y9?Ppv5YjD0nOeupQv5KkpX0pFm1aynH>0?>Kp^LRLQg^T(9#HLM-_{;o*4?#zQkmCt& z+wun2Ou|8@%2XgnLbtcLik3D^Ib<5fJMaJek&BCq)*=6MF#Cmtgm-Q3_@I*}{|K}I zy;wq`$C1iP5&&@Hb1Ct?OfAFVk`Z8!2urUOr-j+A;UVZ3cuY&e4`nGu5ofk25G6sQ zfi`}{ea@(e(uB0)kHGC|&IT&-^e+n6#3k4$){eUKAus6F>+U3F*D5(MjKd|^uSK3S znnk-5Cy500JGbDu`C?4&*%3fc1o25}Jy`5z&`I3C>wVhiTl3PO_WmfNO+}I@?lP4Z zuSof57=B@ZtV%UWwGcTKl1)-c>i8l4mwd94yK4upe^&)vhH?T6o}lbHY$^9er)lHS zUkyVr{IB04#Y97MNKgZ*u11gwA+_{{nk`+7RuIKNuxMIdbLY#8QgqSnJuhT9ne^FP zfS6gH7IY*lVpGVz`gUr;TI9otqHS>0yD|vR zg7HoBPc7UZEe2_A?ZD+QTl$F6fr!H7VeJM;0MD9|YCTqA@~e`54GAS|TYPHEH=g4R zrOc&}lN;2EDxRRSvUh5x&A_tJj*@Btzk8b)!?D)g<=Sn8lQK6$J8wSi#j~EGlZIu@ zM*NHjWDt)KvRw<^Om=Ee-*Y(kpQbN|&M8~EZv2zx16%T*6hEsY`b+B(2o+KLw)+jw z6cPHfHHB# zRT#aV9<>K|F5}>at&jCOey2p0noTt{aQfm#k2-KLEX)oI%x@RIz!F4)C6~fBDy!$mx!-rI3&utRRE>v zE-q~QIy(5S@1_NH*XvRLkoqIk*ZB(pnc6+FsUQsp7!Z0&pQJ+x^= z=n~RQ-_IlU+X2_jicsC2v&HW6clW{=#x(vFJ$>--KU|9)y>1tNy={KJ^AT@eil^mp zRk$4XZuDbw!iBu)E4rL@FHL!JH+zbm6r#bpm`tTKfVdV84H)ZZxcn+1lLtYIT*ieM zXJ4X~4N@ZOLfss<_AJej;D3>SoY|t>8`=Fuqazn!Brx$734#0f8tIETJsx*&KYViM z(a{l3dce2l=-0qb7Su4et*^}q=jmW*@^_bl%2}*g`^3cCj2H!ftN6ap#s_d7RDd3BRHxBQu^x@AdJcobaa<2Crptpc{^mrg%a< zVxU!Epj2TnRiKssM=n}zv;)AckO@*#U;pDhWPd8z5@O^eBC_fpGE}fnapNah>5{Np z5p58yHnU}+cbrH{>&-t1KjEDavU1$l{9ULDbbfDf@}KNZ68TE(x&yZ*G3`X+%ilxL z6GUVr^DI?on~(7KBqUtP@Gwx6Ps&S_t}fzY66fKcmY-cVSN=fZVdZ4Ktx(H?Q(k^H zoSzdhL&#b|VWh_(zCxx~ldq>P(a9`?5bPiwqG?hke3WDZ)1+U>(7t+Rt8|MWB5d&4 zzjlj~T!rHpLOz-+-;;{MfFau70tmTQxDhOA!u;mO{)S%CN>eYFP6WpOgjg2s<`e{y zf=BsF1rmq2D8)N#Y>q9S(y9e2t9NuvFg_%rmOi$wTlm2pvwwkQ55Ms@uy z+*vH!x?W+*Z>wNAdxPV8CG5QLugXVE1UQvu`jxt~oQ%JKr|>aj%F)OdmBCS8LS~8K zo;)VwCHFknr`poi361{vO?D}+nYiCV4h&soE3o?XOYJs+q{K_?RI<)E`Tu2CHGY8w z(K9eCfHOte*s1Wqb6P*)L3Gza#~_&NP?=WMbLMFUc}rO z^Kt1M<%G7*z{7!e?$o{iAND|L7He0 zC1VXL_V0nkm_WO!G;YMX9}0bYBfnV8Zm`Gyl)~yDTfjU~e&_5&Kn!09voN#ufWrwX z_|D1<>$t5Y9mQm3q8Is=phvCWfhHjVj89z&sHivJGq3+!ZwOCYhWfYY0s&sDaG!{p zel2o#^qsoga7}_QF0~03#Rk>n^Z?7UQa_Xku(F)k0R``bs13GKv~y=NMDzt`;$@Os zCf6##R){({tazO%rp0z#3od^<_dmxVwnTpHUxbCq+}Wa?SAftc<5kv4<1BBasRz*v zqul#2mfSQ-1s5|!tXC?X7zML35vV@%7@tEa+D0Pxd?a6UCv;+m&Zhhoph2~ZB%f|) zhB@sEm?6Z7P*C1pZsf)}FQs!VYX7pn*0}u~PVV8jL#n8;cXjo{);Nq<4Np5Ip zRyByEL%D}``EzXji~PcNBMhuHOgESiXxFNf4o<-OxGf@p>H?ckDCwF4vf?4h4qx;0 zUFq}%&kl&yoG$5T+7ra+cvLaLyH$k&8cb@_5jj*cCm$*aSaRF=WbHdcswOXMP4-tG z3s_)MK~zMN)k&ku&H>yTAQEp1wM)3IF?E=@>C`G>i^`(cRr843KU?x;qAp zmJaDq6ojEjNq2XtgmibOzr8=-=lT7=Xa8*Xyv{xM+;hXO+aIdFI6vGZ3$L`P8ldf| z07>g!P6wT|-K>xh5<1}+q8+w1E(-eE#4#%+u|VEx9JVcFJcRt~+4b74~VR+iI{$E7Dv@d*0UUr30n zAoj`yk1Bi2D09cN+EgNT!Oi%`i&#I`-siEZI=elT>asdqd#hKd0dI6$e8;`3ixyz- z5*#cS&VND0gE+D#@_Q%Yc7PFwS?iDo+vL};e4vmrjFC@9HXdHgWSTYok*b-FwNwcW zE#T2Ap03gJH_$wMSacnGOx=xQ2Hng_gJ@IWmRM->GnQ$?@t#tvCcguueA(Q^J=u4mmh`51ignVevO=wpLII{*xc!#p#= zh~v^ zo=?^iU(?Sc4+%XT@n$}Syb1t)xgUuWlZCMz7{!%EbL5ue?$0ko)Q=zB5tcKl-%nAQ z5#ATqBp)cBi(i(Jp8z8LL&f0b22MP89)Ao}V`r~ENu57b1b^IJNw`UTQwYsI52?VH z`=?-BV{;z31v+adI;%&^5aXa{MZj)8A$Kp1+mtH~&SCzt!jjdW~ zZV|KTSMPR%y$^QANhzW{TuxiXdrUDahat@*w2nXPs3r9ASjBvIY=9Ma>cJ%+*@ z#oHn`A5A_CWf zwJe8HaC~Ke#b$dxicHf{&hd<4C-jK&G8mBubGuq4+P{`!B93mg$iS=z}oVWk*YAhZx7TP~G zIXm2v^M~CX3uxCCN=Fy9OGc#tMDh=H)JYCR!~j=XrNLa94ZHci7W7 zaQ*i%mFILUTioORuW!B>BFRd8{LtZ!M`&ZVX5wsa{7R%DgeKX=Gz#^Dq2AU zFA03Q8Cl_%2%Vh$51j@RguX%zl^h)XaXkZPf7kez+W!H>J47av{HNA8WC)?lDTKbE z(Fp$MOfe#L+Cj4?pd52t#R_T_XPjW5x2-Ude8RtulB@1}|4AZfnEZQ4i2zwfzk(Z9 zHLR&wMc<~k6<0t>N^6rD_1nxwcw$xICg&e9>y^_69DHFklgz)kjQZHLvGO3lTT|M_)EtKI;6r@#DD9QTDjoovI9XBUe8TSDGB0$Yi&Kq zv>Ii2ZWaqV=4rP#o{RQD6eG*MBoD}sipp(R#V(DPFymnQ+TT<|1f{7?Q0qc{?im)) zeF!_G*BezHqZIFcUKz1_af5Ljj$ zyUXa9)sSAzpece=*(GLXZO5NAN5U z1%s3a7M_Njg1^wiGLPIFTYP7AC0ln&&TO!75RqDfL)~h>P$H+R&7EN)XF=5PwBc-G zQPfbnq0RoRW@SMW5ph3{(z`3Z*$f_8#Wm`WRUhi?`=kzY`RQ0cB|5NmpKZ%gyIDJO zch|+B1dB4@J`AVVeHXwt#kEF=vf@zjb=R>7f~wL`5L_z+2{ugUZ#@!6FE|Xr)w`AS zKqyg31-J%z;!*fF!FR@xNwVXpTq~&@vh_Gs15+2Zb|(c+Iy#rwPT2aLtX2QcIYbGQ6_%IV+!%;aF!mU&6* z5L(0?-Ewi~i9*d&c#yE8=4C}U-PzMGVv(TB7vsUrJuHfEoB-1j@lZ{ObF zQ!h7@?xfIm7toFKzv(PEnb;8ONunG7_TZTuCh>RY!eV1TdZsD(n2EdSE`DP=*XH)@ z68Prvp0{24in(3fgOEI#ruSw5|L;;Z(hwVAc6;B6pTE>dI&kCCU&kY~R#ou9!+U^* z`p>gyvg;o>qbV}fbf>B==t%F-{5#rDL!PertptSK-WwMSAp+CvQJcG8i%kg9gYAjl zFV~-;zxgO|KR81=oWNwfqfV99^tDxL0$H03;(V}yE97}Td9FqA?oI&eCGt^>NMSdbr=8!B&1%FJBV%pLKqrv}!{HuQ$+Wls}_tA70IJ|l;CcexcKUAjQ8QTP*uXMnk&yJ<@%8eHDgcIswyts z+Wep2mwvI->L=@78+9btcnv>%F*VYj6zI7B)?~5#XKq0?gxR~zaEiNQb@+#lsMr^i zvX@_Kw1{D$-UaeAc`e&PE!hPNl^HWWtu28*cFY-`v$cw%?OsJRfFvpdz_b zPucp)J6K1{5}7?rY2_4cl{F8N8pP;%r(`v&f+->v*f}(YS>qad>U$GI7jiZ_2lO!4 zV#D=PGM#oGO`wB))Zw&k!jo$%V3s??VEFC98+lZ{#y3mdu&so&Dt61rhvXdWTO;eV z=qlFLf@b&fV8F%_k4}QRP)iEyTvNthhBC5s{nwkWQxCkz6jPAg<2oTlek7uk3C(|i zepZ?SJ5_N|s{r2p=)}gI7YB|>TQ_DKFNkTaR?2dd)f~f#*{Wo-2p^6|mq<1Ym~yGt z_!D`>d1E!PBr5XTAcip=*S%bdz(Q-ZziS_mjQVA19&FC|=pQ-BIQ{qM{zkCoYB!{cZ^9VN%fCc56V=B1 z3VPoD_S8@IT{!NS#{$TTA7HqRMrYeDg@XWd)?d7|YXbe9OCj?w2-G4kVvO_-d1MMp z{OxdE*jq-eQRlwKs;ss1dCjH(OX0#osYqpuqrP8uUWiYD)D0E zhGbT5iV%71Yokmnix5&@VeRhW7D|m*95NokD0(O;z=NYC6&?bG0Do|#3YUY!Z89Y~ zmDfjYmTjajLeVLZWn2403=OBz+Aa4vNDOwNoU;C>OxgYT)GGhsTs_~)CnMBr*OEM6 z%KOD9WK;@L#PYCSHK%sCeLLYw{pSgNKsTmG+;4sI`khGAJI-sj<-|5qA*+e)iMpT} zrNb2j?a%qIeb=w65I$QtF6KW_ioSdIe5-&qdSlPOGKTpikXesK-a!T3XbrzTnM(x; zW&N1wPBVT5o#i9GaM0*^+?(Nb`)z>CKSzJ3|6yu=36`6L2PeRdh%G>kl3Y^y)8jMi zh~KE|iv&)}@difV`d-rTl7s>2W*Hw3!Ir2f+t|2*hrJli%*^|uyhw1?c>SI_mnF-r}TubDC zTx)V?C=(+}Y<=Gh&Ct=&F!roez%fJTTGzTwBMt+7^#tA?85Ne<73U z)rG%T=4u;q>HG5qX+GbYu z@p>iMNI0hOE=ATdATZGPVfkJ=3eFK=P8?Bjd~2z#jFpK-mTEK%g5qPafb1+2b(L5^ zR@NA%{J4ub1l@$3X*MJM$>9~zuP{sj1C=G$r(WJNuAM3d(fCTQ2Q4@6@#WKg;t@&4 zGVphj{d#H8AospN^v%05h&>#V&vj+xhOA_zKm^}(v}lEW^}7sClwfN@io&EEcre;S zMdu7N8ZCaPJIxlJpEw;_01P}RP9)`8a_WgEA8y1|`fJ6ZTth*2oP>lNnOI!Qq?`?ZvMCR_CQ_IGyYf{WS;j4tM_RVw4%b!+Iwy_^@WUvwdIV@Uu$K zcpBOvTk?rYBN<@;>CjNs+-HXT&NP*38Lqf8nWN{&gUI~K`19>TL-qBiIxa{PzomFz zYy7pMGfdb-F0ScZ#w(mE4~6Oc3wI}l;PW^K$_VzB6h8Iq_T-$u8-s1%Kf(fwC8Y>) z`K{|Xq$#M>ybwNe?D!gPoqLM!Zml-d9=|!@y3+kgU_~|_bH8fceb3%h!|{8jCuO+s z2zv8iScfXwy(`@=zF#XA^-bfBehA*S*5D^NvsmisLi!zS!O~(FPO@F_n=9G+M)J~M z-+_B;5jsW=w|{dEBNwJuBBelvO*v`iS4i4E7luuFAAO=_pzzWXWdoo*O30oA;aih#kH!fQtm`Et z_R7lp?oE$T_bog#yiODo=xW%HYUSkeh0IXn+on7>`+2ubWB-O zi?;t;8>goFz~Uuz(B{o5I4O-ST zuKEQ~PBe}=nb22SX;Ia{u|uIUTFkKxA%$O$Hor=E>BCylb?Sgs9UlIooXPFTe)JNy zLa7+g{DAP>A~2KjnPs8LOubKfg&fihm(kdXePl&i*#k}Xdp3qtiuq_pbd9tJYGKrQ z^2MpLqp#?cJ>G7fs~P8>qu`Pko`7Z`4GNUcp0;av^<+>P1&4nK;5-_87x4iWfEr0ry}`Jnhv z;+j9nlc#=2lc`#}6=Y!|XVI4NTP0MxMWcn@TeF~$z1HYWnab7yaiFq}c`Z>}2pRh9 zUhHC61$X5Pc||CpR7~jPkKvQA{&es*BAu+v3D&*vMa&8*Hra2RH`!8O=+DcAGp5bc z035hxX(PpuS?+mG?>PFf`7PvCc_->Ih8p!}+Va4=Jha{mnScs&js;d_H*dunx?w-K z9xK+mu=1U_!fjQDjLPoNg&MxB$lUw%5$EvW7eMYazE12;{y90(JKf zVnrn-=IYi?B>GA2UVw~Pc=;P+(vwJ0lyVss$BCpEF}s{LEk%-OG3dy}VNFTl|8h!B zL6TVG4TkQZx5<$CkM0e8F=f#VN~Q==E<7t?Z&0g550FMbvcBHL)>Z(_&_K=bau4e= zIVxKpD_=RNXKn@86@P{6Waxb5)cZVEnu;8lm6QSV-2CRz7w~FuqA)UX6I&&oCN{D6 zEy=dFvWG5bJdTM@jyP%s`gh)t-}cqU^{5{xDeKC3(M{ut5oH3{;_>N-AM`Ijc$QIE zBiLCfi}j=`t~Rty`}VEUWh(u{WAMcS>Xd6m6g zOD_bbwAdoy-}tzf<2ip%W@XJ&Z{|d_Gs&|iK(m<5)*K-}c!gfzrghf|Na9y{>DL9g za9;~14h;R8arZc~URwHrO^|%jmw?N9c0KUDsoj}s-u`3B(8^0M$z=o=A7PP0g{5); zcEj9)j` zb(b?O@X>!a{3Qmc*kMpVKBRxWrd~GNSLolE%2Hc0u7K7iZaPDOc?At+lQ&6)jJFB0Nl^n5wc! z4FhNxTmV3BO|yQrdl3S&e9`Bwf0Z7wzgc|Mj{&ok(_&!RCNGf?C%1!*QfD~W+EDi_ zUUFr8O#Ng)7Oy|8n~^s)feIwv14(ZG7=5jUu5siGl=k2=B1R6;MBxlqyH3x@Ee zF|tQiSf#2Y#4EB;Ws}jw&Q^lTm6RD@v0&`gc?_zkSWc*b!BLTr*tPxf|E1=K#lHWM;6^HDXjsvYH{*({EY$j7kBmsK5*e zU2Q*rHp}s~__}lq13LKAAPsUH`jVNS3-8?=d<;JR?Uy5~P@vb9Oj^6*EDr>iR%(Ib zBiRUx?}iphV#?ktmn)h&v&P9jWh^Lr=@igcS8BZ{A+i0S2YwB+QhP!hk~=zos5&-J zxNEu8U$L<>j)vWeE+=Z&oeV!2QC18GGO(uZ#d;Rd*!78JJY~GUzT{e^;+yXaJ!^;| zhSsfvJ9f^WO1}*f8`G<3qEH-?)aS_rX@yiggnm(%o~BdlTdH5BTFj}_pzB*9c05U@ zZCjS*()rND!cim@QmY;|O|BWJ^rT2NL~>r4R2yL?KBrGpVW16*4qh%7ZswEIi1S-M z;SSLkyOM8S@RXcHYS#NqPtc`z+?s?3M;|BnRG7Y9F3ntY4^f=eEHWH14l#t3h>5By zo?zAyJerm6YZKmBw5m6~`DH#`IN8!0s!Ov_#$NCsOULl{qH3O}KVhd}SV1T5hn`vs zlZCQt@})VwUczt3cHg^V&- zz9bO(Z-|HRTEUiGvUWDW>MEvl+8d^G9L+q)dEU)8JrfmIgUwzrheeLTeiW(h*^ezDyp>*Q>sEL%7DZuS}ghL1lO4|E;F<`*mD>jb&r2In)6|HJn z&tOsOZrrt#4_MkMSpF?&T|H9-v^K$O)+a+9Z+6#43*W7Z%=6GW#l2Qh&4XWVzAa}p zq!+A7+;UFMgiti+Y7SaCsXlXQ6t$y|Y`gS-iC1$OOzbiNfA+LF4R93@vQ@MRv1gjM zQ##E^#wVKp&IdGdo|ZQ@1y$J`83XedO+EmVU$d7$3qhkpT=-cQc_fi`LnYL>#>-1h zFGiEkl!NM}KPumrijLwYb-7mJdCO{s^K(4eqGiR>u-0)rQBQ&PllP|Db7<(`cX3wG ze4;2)3T$XmQM}m}y2zwXoZIh@>!0QlJp4|`B&5RtwY6_LtLP>+hWmY7+V-G?)UYH9 z_C?-yzyTGDwc-WSsM}k)KjljGv-8#_cBGW?>beD)QE4y*+h}z(!~9xd>$X;Al#yi` zSsQBJK)7IHZaZif@4fYhy4m6mTEN``GbS(LFQ?AQ+`L_?&Ya=uv7EWwU4Z4ilI6P= z4C?+swE5UMsM9B?|e>-I+B6|?264L$lO!+QKT~>owz8&u%-GOW|#>O^_^cdF? ze-JyvFY_F-%525e(&Pnw}?90{4?~Vu{d890I!b&UDsV3iH!4*l$Ky7!ACWh$&0K z68InV?ME=D8b$V|{l~DR*!~e&`JJn&TRNRN{D0_UpQXT8LzPe0)a%3OOfv3X^oYMdBpBhcRGRHk^?WUmi zpm}3X7~$;}EsRrvOP;@Tq`)$G5_M__URPi80}E9qrDtf=I(D!*ip_bnK^anM1!C#> zdMQ5_*!om!D;cI065YuhFyzi=Uqcg5eCc+@UI(&ZVS*V{v|)ufe42zT>*kYJM3pJ; z=M)>bYV-Af8Lde3SuYh$6WA3@;x&h|?aVhR1(*wIf!~dLzZWz3#Ds}H#KfA?M?1Nq zLv{4kKP&FAS>F%A;$luk4o{Ipt^m`-A*O+rza0|*dO?gD0;Qzv{ym8` zj}e2g?*AFE8VU#ziP_)n94e-hNP6fTDJRGW_&_4t*&J=V@f@l0(kW)`Sx~L49s84P zh~-gPW5OSteY@-ZZ8!ouaeNYKkJUq;Wik*MvvlbW-l_rzo}qp z<4Pj5)%W*80^CuG;Lc7OOYZ%Wh}45@jLKm)6zbXh6eIkl2qsA!+%!1|D>va0Oq zYM`EtP6Pi+#-^BaAH|F}A{lru>RDTLCWT*l=_`}eL42?gV@#sYDF{f&X|A8=Lb~i*lgvL-<$R=Qh zgnfLv+Q=bH}^wADGbdvCYEt(l>ob43Vw68We#1Vr9JiY4CkL2 z>SEa(Q$S1RzBDMdiAHOC&e$K}EiTjSMErY!4zQfH=s-0vj8v(p@eIO9)eU?iEpFky zikX~&>?%l0?m6e7%qqvuT^-bZv6)a^eV#lTI0rlh(18(5qGBOepnLgGDfstSb89z| z#3q-dS~TEWfMtIi*bDHZzQ3}hXKm{+`L@_`liA)X_*g{aa~|xMzI|!Px%aJTb5DG- ziV5EKimm|9&_adJHNQ^9z1|mj=W-#M`A>A--sJ>ra0k=a^A-b^_0-nQ#9xw`t%Dkg znBDffDz_~UB?29Qpaz=Gf~p&jn{j!Gz*|5Ho#a6J0F0bNVj%QY#8tK|MemcDGS<(q zi1(p0f$>O+)~Sc#v4EWXx6;*{L+LP(9}JiF$FJEt9gy1Ts_l0IZ<}^#DF4CjgMN zTO^w*W&ik7i&&D*6&`-_Yv=IcB%J_br+f|{dAUXLg;|eR@xDF_1Cq6d=9>W?MIsS> z$E-&^!=&T^h1YUm!Es;Ip$#VVk(uW-RPMAPuU;J0t7?rn>K2!x*We90Y?O> zMsI{>NT)~e2_&aiGl@JnF5|Y#AWZ4odixYV-mN}+VahT~jQ2_sF32q~B!|X5bWX8U zMApxEpKR^!mir9q8ZjK5iL8a=30Re9UM;U3m zz3?9V9@DA=NVK%JMbXC~mOqD2MN{w>eg!G*?sv{1=z=xwy9X}y{daF-CHdbgfAjF| z??(vpN4!#hb>(eU{fFTGDHpO@%cGI2>(-y>$RC0V;QJ2y9!0QTn(#hz3f}sdJLoVt zo(~(HHQBTiETa!2!@-3Q=JoG?c%LqaElPo>qFor?yU3>yyTc&Do5_H;*3}FL3|bB< z80c^lb;qZI%)@iuQ!~MK7$M&Xn^grXYmF1LV$gFwYM79fB1F3GR+4$77`=1fAH%GUZ;0u3a6*6JSABdmN(h+8QAyNL!V*NR16y%%F^YQZ#Ow6hgnbIqG*a;$Ca~ z*?215Si7;Z!0H~{6X;U$VtvNJQuTs_%kgdh(!G8Cf{?Yz7TRofMkxmmLEoq&3koMY z{foHJP?gg&#r#HcaH|AxR|12(`~z7QLZGB9Q2MVovM45X zG@!pc;m!NE$R(r*aj$)8IXm#8Kjg~F$r6W(pHl=tg)U95{V{f`l8vpeT2;T!^V$0F zHv*mYhOR4`c=hja^NGjPLy^bP&#I=g9-b!mM{3{d6I&f>}jmXNB5~2Gxja@*Q8B-nj3^J#po;xMHRU?oXx}`q`;O-&s=L3+d5Lu zLo?D+cZE^Y-{>b%eQe$!cJs?GpUuroV?!q)a**siA1A)V%=apqajjsi6J}W~oKl(N zmyETa9v13~*r!vaMSro~#1NTlq~WXGGplgbu~sl+{@hJeuvW3finvs-PT9ob0Wp7O zQXykd4qtak9UT|+2^_>~Bd3+HrWG{??+Y$#Cl~&Y=UEJuiel8 zrs6&8PG&NM=3$ltSY1kxRB{~>B<}Nikkjhwl6LJRdA8<&ezHZpCOfI*`P^5wH(qe^ zA*ofokDq>1_1(01*5+XCTFBI&n^@}MRl10O3Xh!K55dtog(t`diTi}}?o8GWz{SW& z3@8?nzK@xtvV37CMyBWy4M?&Y{0&Il6(I{4-|dD`bVeaj$*mgI?|ZvD)gorHlJ}Ah zUBf*Fa&Nd3M9jEIIX%@A%6qU7OK}xavbv)WdO9Emg`Kl=-b7{oqWAw9%fS3OKFDl~ ztbtzq6Sk_y795ZBuem|)XCDcbAgg16O$Y5AT4M#rtsPAVF{6Z>QxvoZRz@~n($uv8 zcoLh;8w21vI6g<$ymxbxk&g`*7_o!6f|Jth!g<&KdzIw3~Kl0 zEum?dzuH*QONAB^N4*X>gQk)u^nC{A_vR@p<7}WpK8&rBZN$zyTGT7tS+f957>*rr z+?Ap@2E{XXh(Bl1#Aa%Yf64df(oV5IusJ6NBLuhs>ZOZfjFELLV62C8eh&{VszMsk zL<={w0XhQOzjMof{C)3~mn1@Pc5aUQOMV<6+JDeo?0=Y)s(Z;_^_KT@HTB%x9h<6} zf}sLh+OO|@Z3tU5!|?BnOUg;T?&>&cTD>2E(sC+=(hBBR57h+s!D{q!iukfMD)cD3 z1-IpH26sW)`7&+-XnAHj|VJ#x0M89Qvyqq0MvCWAmNb#0 zozs|P2fVX1NNzzkpg_uOs*xwvT`WJCQH9o|1t|xj;3fc(C=~&@l!b*e^(ubbDMiqJ z)hD;STA%RnKQU_ZUc+%+X-Ww4qw^q2kf_`IKd9>K+z*8zZY&rKlr29eL@~pww20Kf zEcIP~e(b(N60tDa|G`vH(1UAC&rcPu3SBTDYjCh;AY2M#P+ry*nij!4NRL8cq1LTB zn_xf)RjZ_8ttF3PNF`n3w~yXrW;o##uI>{V(vh5r?j#D?bS4iOA|&021C+Erw!o+% zhE9W_8jfPL$TNC^bDV!#c9nYvrU<671B{ng!8CB{_vz@RDfz90Xfci-#I{JXr>0g| zlF}ve#e9^t;MgkPT8N=boJv33x@{8XSy?d^o_=0dvxX2cRXzryJAJJFr?2x~aos=1 zGbJ;Set7u4Lr;2hBAUKw>u7kV;P>7y;v0kK!jjg?>{T~r*eCL>=)`0X4j!=~agB2< zrb8KM2R51M)#w;0Ni49iQC-lR`RnN)E>6)C(!CarG zqo-k><+qIaS;BCM2Pml$FWvy9L8|E9md2){KJZ^gW!6b)7#DnAc>xfzeg}y1_JJTK z9C+=N8qOR-EKm1XdGB^QEbp;V`71F^@s-21xu$2{rdmwKw5}W4+G|<&dozGh^?(!^ z5zs7c^)CvBZ(n_zp-L?f#8XuK%Ep}=T|J7yq(H_1A3D8BRH(E-`7_~ieIxsFeWRa& z-9sXcV!ccqNSZYv`2+kolbWg*jm@0osH(2)TrK>&v~7}XD^7H3C5LV&C7>=8N_dhI zjU9m`=j?dv&@^h8ol^-ki#DRdX-&c`mo)lEfCn_4YT(=hS_q6{MnX&ub!0SBsml0o znz)qM^CH$kX~6UWDtS|u-IQI_qUG68nruhdi(s|mxjuor2Mj}<&b zfdLGIeH4YhWspekVHf(Faei<}NmCA=H*U}lkTajFF^Y>iNDVN zSqP<*LC&K6!gS>Z2mJLXaW1i<6m}A)5Ne}SgQNOj=0E=e`YuI+syVjkr6Rjk(PS=>MczkY^B~)G7Vtg@r&OCs0F}n9-r5Ee z&-x@6=<4o`ANk3FD>8BhNcu1D?}vd-1IT{3d41|bs&X^DD~>^ zGqILE@cKw{@&BBc1(=36jIaV)=zhDL%4Vj5^=DSZAZk^5CwLl3j(`kE8^HAX(|>B! z#eeu@^WLLGfEH#|A|NzNQCy(p2ue$D@a2CiMM5(WWvHTTy7|u59UDc3rm`SW+)gsP z$}0cky`O9%qm7OhEgPPbD4Yq{U-qa1l2x6>s^kxsChI-p-Fm*Z4aa#(&E5(G159e@ zhUkjvC=(q#R@LK~r?v4t+%m7uCCLWP(Ka`A9k@Q@E_0}b+LH=q3-oHOZ`9exq>+Dqe}idOb_zGRNn|TJxM{9cTQ}yGAAEiM6ZFYd zI^%q^rFc)Ww3Wr9tz3J!!7pN4-@LZ`K`&9r?%&G#M5}a0ha_5B$z#Di=M-@O^T1D) zYCj+pnQMl$M|z@+jP@pW!FrZ@L8wVduaz;eZC_BGZ$#@oQp?k3{P|tZ<1+RSo$9+3 zf;TJDYsP5tR)jIWmR|-eAaXWIj!_hh@m)Kv^PZLK>I(9^AGjtJ&c^-?P z9@cDQ&(;-HCfH4NG}Z2yawcz@LGat)F2Lg@RA$9gm4W)gIMiGM-Hc${b}r2T+zJ-W zLaI9+o**(-J@*?+E;vDV@cxJlnjvnwy15bF^Ks7Z5e!4xXcP`m2ny!4=O2x;aq_0O zkG``CEEfKFUw4J+U&{RcYu_q?dK5|>BR}fukMZuOD2w&E6zRWxKdStZ!p_Q4dz^5i z>))dSQ;87oEpYqF4^-TPeMnod1Pd8Sse~j=z-2|tByzNnNkRxmlMd^>y9H185Qiq? zyIYHi2J_Cas^b7$F}!T@{^?xLqpq1G05B$eo zxDqs-8rFTDaw3IHF(&Z%*UuOei^Pcq-4Bke5-k^%oQohWN1wkhX;;AK2gs#qrlr2+ z4>zK9J`dBc@)vzzM-za0BS9OFKVW|`|L%TUENbQ7JpuKohwqd-laDa11cHQh_B&Vj zeH(g^cUvHgN?jfql5Y+R{;sXRbW5SXeNbZHVoQ}Ib~>aOk~cRL?N9kSF#6HA`b`u5 zAED#kI@AG=y`P*-0Z;fhy)7XRQpYQq@al&fTAPXEr~k7KAoJ_=Uig6#Vo0L^6G9*? z8foJ5LFTJZBW;R1nOUt!sIU?i`$h#RQ#>hVMm+bQo}TX7%djN@m^1q0c;#$tOj{@f zO&}B3%)*1 zua@l3p+EhTXfYTcL5{Wns*7ik-5fb1*L}~l0+=TePh$}zG~SyL6y;3>4dE@G_{4j6 zXaOkd{5?oAe!T)u8dO#?q4D(0OHG{$ug}0%QDc)2_J&x4&k0Gh5_)s=%6n6k?Q#10 z-pW}W8<1>i%DZkeF%4uhaPeZxwnMP4ek9}(K>umwiQr^`XyAMHWzdsr;Q6jOd4&__Jr>-iwttlQ;@4A8 z=%+z&v6(}uwwX5XUX0@n&BY5SQJH zF&wNC?e)xWMg&S583c)!P4~PchW;kpMZV}#j(|%Un{Z6ZU^AVAt;jf9tx6w1Imxab z^z>!3spE|ZJZukDFPsMgE%QNCRjjYS(QrynZ#`2$Tx4A$g?)!K!lB$WZK>) zylWmoV~b9ujtj5@SzC=;_Fu>wuk7KesxypNQg-3qb{T9l!RrWFqP&eos;mnbAaT%S>KE??v5DYEaftiakSVQit$? zNLe&fhzo~B^gJZ5cMFrdAALH=M^^2Dl#;W?lFara_9H&vY+>$$U zAT}*eT2Gm~cySd>wHZjS5vqFmerxS)DpU<6!Sc%|)Tn0?mp183Z=d2%3v~DQsFsfO zK$A^fySLUc5g)SdSgeV1fe;r z%iFt%ej)PGr8)nIsb&{# z4$*$}HlcP_ptVvHYl?*;yP7+Z53dA#(*kV=J%ZEULb$(tGhdlx5!B z5=dv#*iIq`4{PFuyUgb*$$lWTz55TvMo7Ny_8y#%JSfqJGRZm?$Y#aHyofgd{Rsq} zh)||4Q`d=r0ho*Jp+DV$H76@cv8%yJjoCbFV{@GTp?jFg*+$&!bK2Rb2UiyEH%pC+ z0ztGNvyF=D%1HzR?kY!zm5fcq)Y8&)K}DU|Uq?@|dcW_mcaI=15}ISVU%@&OsG>Mg zK#v7xe+T{^Y>vu&#;tNV8b>2Q`}QpBYL4Y|VaJC;ct9M9_RqZ>O^Jb#3qRUpk4<|* z*++|=<@KzkVGjw{yWE7akp=6CZ8MRE8})q2d%>FE2gVw+XY?C4$^7Udv_To&*^FVrj???tn>cAOF{EGp)^Jn zHZVe@nc11#E^p(mCmVV4LDco%E4Z>X#<9_3x>6_z1a$(lFc`Olw&oYjIh8R zY}cn?atpd!%2;HEK(zc0#QEH%7uMTjlSodjoVd1Wpk^yUBv%TgBZ}UHLk*MVO}xP~ zHzc+L4qzS#rs8LGwjmBh<7a;ZQf(Qt0Li>BAEu^7aJ@cF^n4Q?sSB86IsDy3jOj<) zDQr>Dm3dN&Oy@Xgy1sb#cz&T-NYwD|*VO-5cyXgLmUxF88y44j`@V$SVrFNc5r8Y; z^!gYri_GMb%!H>}8uP#TOFtaQ*c4GB0M6)F(#EKKls*}@9Hqkr|E&`tdTrtN<_N+i zM#(6RF+T&Oy@OEhvr4~J9C*u?N!O@LE1wo+t7ie!kLgdyF%(FqPv)Pd6x)7HBcCQ; zoifjKK5QdRM;wREx$-ASZnkQMbj!blantU?Xm8*reX=U{;7P?BiwuwPj21?3g=X?$ z8`%D}L4ZWUFq86%#V&kOdJD+ceEj%{et}@Co#VzF+vmPy7Rd1MuOig(Y$r7bp=aYB zrYTnX*aj?q9$u~NAR2ygESYM&kHw{ie8rL97napYX?IT%lM{@>Sti9h_b;)8XB6NK z@}{`7vX&XZNV2qd#8D?!U(7M>_JFf5#Zq)S!68b3hHjk^STN5;%BVdD^RQuR zTzaje5tpQ@unL9hA;i^}#Roa=^DK!uh0&Tk!7gB+B^NVaq6$PS@$OsT2_&a;(=e#+ zPU1+nPiDn%%N3u^U=*3eygyor#_TpApX&j5eaw}dT;08oC0Az+?cG9 z7xDNjGEV!1v0Bs;UbR#EcRocJ*%F&Jg>7)tu7<#n+<9$lgWUhh02~(@a>f}NbVX&} z@krXyeqZnj4P0T4@KuYe4172jMh0Dw@w~p$rj;Dv$KdF&;#+A2xAq$~^vDl?*m9VoZtjlmeJ4{(@_a-J29P62qWYytsz~?SATay?@ zuX{PgrZTE%rAMpmVM41m6R(qH93P+WX|VOWq{b0U**|aNX~+0+UPD&>$h%&9{uO7$_Cq2Ec>xCqn)MLmHaLMZ3qL0;YRX^cTy2}DWx+sgYb zpHwDBQHwv`y@C&eIlY*}|hTSJ$NKtTz0S|!;cghbY^fIZQ8Bz(t`up%py7kNagn^7QL2`lg*HPEW*X^v!B_V_gnYUjmsLw;eu33ww)6s^% zEhwg#fd$jg=XVDc#p|;yo7e>;7GDmWLc&PF-4%b2_AliNTw8I~C_JAg13jL{O1AHa z?n{>Rx7w?s(mL<8Y3Z2QkQR+kho6#L^>#v#WJ4gpihYRF2QBO8mGqkJUB{XV??2Z5 zoPW62sM39o-zRvN3}P`|8u=!pKGXII^F>6b0%J@sW7{h5m5g_-;JFYk4Gl{tDXa$h z#k^PmG8tA>BMD$>Ur9hLFNtB6L$%8*%7SS0k#(2hxM_$_=8{u@a;Nx_B5!DJSVUtu zfG36VR|->4FA`-C7GP_+i_~;MioOkd#>PtYvolhxGfh~w7okKx%HO^2Lcdxp80JSX z3s=g}h%8hGWZyIZF?)QJ9C21hXa_-X_Sj$nFE2zvg`*IhxQZuO5g=65zj-HR40ch zjRz}Zn)JS|Y-HB;slb9@d6b?WW%`jC@@OmQgX?AF3Fe{O-|?i~b*3 zZxzr6+cXWM#ogVDBtR(?FYXjA65J{7?ry;;Uc9&kio3gOixb?fxb)Bcyx-Y>lH`mN zW_NaGuHDaZC9!>`T7bC#wCaWWQy;{xTqUb2EwYx#bV?zp=^ zx+ptxP`SvTWwcaYqt<-lzctfruVm&y+_w)h{>+37Rx83t5;6*fEaSVu0{U;1Z0O@^ zn*7uRF%_z!HN8Qmv`kmVhiBPGFw>=trKS)xiv;vz@^Q8T3^P(y+Uu-RP1aaDJ3 z=^N#*%R3}wK&YH#ArJVZw*&jMy#6KhntI2}u^kt08kEJsA84wgl@NO9^Q&Fn~$%04kAMGN~qd2i*KB;wcEZ;F- z*7&mg4Sn*D3iyju{3GG+EzuzRczYf8mzPk!fKAYRN8xdMR`M5%9V|iGcv_plpp7bWUcBS+6CP|iU7$s z z#^R%wbYDLcoJdUp>Sc_$sT~@6Oi59h8}@v(pcGPZ|LP~yn)r<$1L&9ZI8_=_;k(xi zVN#%Qq@VRX!M?78VFyJYa#5>PHBj2jI`RNxevD9?s&p!qVeb|9{E2bu)Q#O#i|I~? zjo*+H0xaT?NdWpWK<`*Zi}MBRW~jl5=8FmIV0qTzPAvKLEc9iqD)B}EmRu1bt99_NL<-WqPyy;NE8;=baJpH6eG(`|d|_92kdT z26lSBke>e#2?Y-;Z@*m4KWy*n=!@J?)fhhDi5j)VoQN9quTywlUQQtjdtVYx(Ft2&WYNKUym|2=Y6GsotCz*O4o-ztaw_&#KfZbas%HPWwDj5 zxH@QYSl>scfTlO)WKlK4epiw>!p`kI+6s3)Q{FoW?{4UE=5-jK_>Yd(EU)=0W~I8FJ|YGPdgGz+ol5&#vtNJ3*xK2OBkh*cAdZur50kg5 z$qg$fcyG2p@V?=Tos8nEMuSpT^q&;H56!JaH>J&HvlFlyVoNt%@kg=F;~c%ps39f= zWMsD%Q{;;cow%yKTF<# zgLHQT7(z+UkoT0B#JP*dC4Qz+%a|J`izVCXHUX9kN4_aGGxxn$Kq86L45(Jd)p;4w z9@ZymDgCndz~J{q{;C&y8t6=!xH~S7dNi_w%psfT>Qd~Uv+etN!DWZw>+Ng2@EOV(!x27SRPo^4 zMpT{KCUUe~epg5tG}rYb0{Bidwy1O0Y{}?+Mm9?k_D=h{A!QlkW6IFAx27P+GSyz= z*vX#i-NhjTMG+;yt*UuLTj8_XaU?$M(e~>hD{xisVq;@J z)k4!y=X?aPuhs-uE+|hBeC#9xOk-Rq?HSt4;XFP|pd}Z0EJzu5 zf(PiK3O`}G2|~+P!2vtCi0qS|jce`}>?b5@Ov6yo-~=Taq?J3#OQ+8dSSQoRPxVbI z+h(t5eG#vSYEA#d9%cf2`mew8W1eCNVfeRT^A3^Pe#PYGjz}$_p1>NpQJ~R!@_}%1 zh3w2Ep<>8MNk|A37Ab7+B*EdNe|Yd2sDE-BkR_qxXd_K3XkEh?UmvA$Fneh!)l78c z!QW9-`yq5av-JTGS=(g{M|0eA|#_2IdC-y1ku{=r1w``9jAbYpUaOXu;HFm+rm% zOSKF0!35eCBFgx|d$XxMVjY(^?s!f8R3qBy>W6Ydl_C0^z>2gd`P7^V33ekR_*k;N~5_d z%FqaLg0X!9nX%X~RDi>}r{Li!VcZ*)Gju!oD?#C=@e9 z*XF*kC238Mm?_e)9~#~wZDYM3cGPbg?_oOL$b(BWR-w7huWR zm-VPv=RGKRy4ry#dr#GOWX9}#x2qHHS~_L2Sg-ki_5n->e8C9od_^xH9LN~~SWp7# zYbAWPgNvDJ|1X2JfddOSbi+9~IILsF_k% zVdKt98gdurKH>G!%As<_qn0n}e1jPGKE{*E;?qgV;&IAR8~mEO{y54o4V-=NJ@8|@ z{(G)~i>m0c%Fakp%1McH1MlN&;=Lxy9(k(S zh%a<{phk^6|N1G{P3rL7Bw1~g`@(!y>hj|J?TybTcejh5uiZWO!FORREXAGUYE*z! z-wQQ`XZcra;2H90d6n?k2^w^StD-$%uEqw|06p4mh z*1LklN5vJ*`}jP(&9|^hdqc=VXUqS;0(RMTfymJK^))31x zprEF^txiE;%-uS!4Un?Ui z>}L}7)3@L%u76@*M`+>clAH404=*`1KLLw=8`rBw=D=rG#@&OfsYTsqt-=oYzDRbe(ZB@U|xewJr@)Smk_%*kAt3QX(nR91AV7JyYi}m0v&e# zMi;U!gKqS1=^R6&-mcCrZ~8w>9xr%n`u7Z0FUQlLonI^aTLPh^4m5%>-_jkOOk?67 zoH^O9wR~=cn18-`JqLPGcz;5xrK8tC4LL2?agq8v0}|IrN?&xn7AbttM8^TdC`r?P z1k*CNey7&?(c^OiV6F>mUOr*&-X3Ha?T;Z4T1N%aXGG~g^XY9~thp+B8KJ3EZ5qj+ z1p54AqFyg43c)8^Ix4?KNf&4J4oq4myG@GXxQ5cJaMB+i2E6uOoq+#sn~k0vPjMzV z@2$$V1S%03ojlr#$lzK*H{@@#dP7GD9+^_QVCkd6G-V0!+};@mB;Z`# zPOlOEx#@I3`x$$CH;I7X{V(BgefW4A9;dD!Wf=nmDSGjdNCFmJhJCtIgR(+eJeg_* z%}lJ(fb1gg8hY0@|F4WN$j0x=M9yt#eDkvTD7F_-cG;&+{zYNu=wH1j^^6+jpN-At zjYe^nq}V#8+vFS*;KChM61&gFp9DfQm;*S%(z}Ol*q8de`eO-YQS4 ztwv(poq_k@$}oG4w6195a2spMe8~W?U1-nXle8G+unoUc5x#h zAFUJmm#2)LC&w3&8_%W9;c*HgL5HQi&?Ao>+b_$*ybbX)E-#%rq7T37s9ZA}NunoK ze;Lwv*oOVXR7=gww0`Jxt0KfUb%xzMAdUoCE@@j{DujdBdguXFVP1k<5E5u(WsAyT zxM6hXY-GMxt)bkptKhr)v$%<0KE3O;%xv!lOss53V#i*XB1&^Yj(>ht72MMJ&g?E} zpi6HvkFUym$g_L<%;fhi55ckf>z2TY_6Wrcg+&)W&nKn9#H1UwuR>(f$o+{s9J2ey zI3JVOFI&NCy26B-L}sdn9|<2fTnK$))RMo3&%OA3Kj1^<>z!pFv9h&5j=;_gh6$=H z06Q7YM^v7LFA`?2ZVO9aWORC2c750qcdEtx7a6}$f1<&Vi60)LO9joV#uK>@f^@z{ zS!jBL^w0ZW)N%Gzzf{rlS>g|{O)Q+dPjYxz(>F^rM}Zs5cqlN&JE3hq2f%xKZW45Z z{cHnc74*Q$iGKC^F1A}VG;rk@LRA?Dp?ysa=itha%b9NMo-TPWV0#WEp`|V2oFmDM zPwXvCdvA>ddFfpb?;y)a+nIY(4Fbzx_d0%4>i0ic-pRDB=|5@yNA0-gk7C&B0H8MN zCQqm`jEG#W?MWfA@4L~qA3SMZkDb)^D}$3%42Ajna;)kR+`^G5CvqL^|;(G3_7i-8ucTSYQ<(ME1M# z5(u{Y8NF;o!j`Xf=*(d-zy)B37H-g17Kf;tgCZs7X;W!%QcB%oz{xOnUJ!JlyKe3; zy=0Cw$RgUPxCuqkK}uTDYY@CUUlvbK%X?C~(DlSK7G#0iHeM7v&YTnh7M1GCQL~VD ze2-`qcME)zJi8B1rfToD+B1BX~Fm)?li)s-abX$R01+L)==)*}#g^RSx^ zx0Dh15v&M@!L-Ew|L*ewz|(Jk={5pRiS%3jFgT0?SuJC`;Vd>JzL2|f@K)<{1}&yi zaQ3?EH9;#dIC~orKnCP9pY%9-7qdBs7PIBPUwpJ{cLO+d-o0D%AGi0~&3(RlkWAPv z7Zr&srS?YGw(lH*Go+N3r8GX`2r~~ZhArDPKxOKH!mqhw0DVdNRQdYy0VcSnWCdXi zvQ$ZYu){qI{2$X1Aqz)NWxM|3;GNpP-QO+c>!zR72=l} zRyGt6F_sazh8}9m`8Vg>rfd`3=vw5EBmKJVJ-N!YWIfTJ7rM+~Ky%!tiW9K~y{)hf ztNJVPJoe0f5FMD88Vjp7>b-6P%YN+6I*pEL4h9JuB7wDf1iGo8E^1pRHb!}Vd5V|c zj`_O#Uq1fQr8y>tIhP<5$Mj@k&^8<~D`kf|ofdzP#kXK41JoS?d_0PDT0)ZasIcGE z2$oDk_c94c>YRTS@>5WK(ew92ib!Hm28x7R0SfPiQ15#uMCx>X5d2=-`j@*=gue~; zt~XbDyngC<4T$>z&&BfPI5MVBmj^Q^yhIJGs>w&h1X~2XRVnKsL-#ScJ}DC_8Q-j% zT}sC?Q7h@7#p=R+t(vGATezl6xW7=?kdHQbdtmnW@)5yUQ!`dl=SWWDdxC`hq!iDR zvb6mzqXuE@(s9k~@$B`oQhzMh4a9txrHV=`JWkREQqxLlOCA&cY2ms;7+8L35}?x* z1!khvN>YqEFJ5>6{cO!Lj|I385fW2&gb)?RnN`nX(Kil^*huUzLWS@Z(AM$7B zk=@#_hNCWE{YTUdRJk1#{lA7WlI%obYJn^x0bz5nn6vs?dSqM>Eey;}?yS z7l=_S`XanBTccgI5_=O7D`PK?EVIC4^4hnEV44(8Bwk_58+m-JM6x{=rw4I=wRG-O z@a?i0XKHzy12~O0F7M>(IrjH^eh!kQd0?RSJyg^8{*(Id63QY7g#&n@7vLF(d(vUD z;Ro&Y0Ay#s@5qq0QUxnKYrLQe*(F-Vv&sHqom;g9ERF{ex3uvx0rBM zNJ{Gs&!9kEoU>NP+6}p*?4Vd~v&0oX>~D7pVvg1EB50qTv@Q$}J=@-+Z)`A#x4$=5 z%|rT`vq-Sfo7vY^;V}Z!Kqr^?t=QNUhYG8l7{|b}`5$WG|J10Pw<;#)6pw0#oyH1# z&AV)k1I4;6*XfUgW%JgKJsu2@T0fZ->)JrJK1iVnc$y6)#k6b!&2QXg>pBa3)yY=U%_ zVqG22BwzwR3!qH&*Epa~R;;qM&xeh|HHJqGSZV5_^4I!y-^|(_FKsc+*uo&QL>)Mv zOQJ<+Y^ak9>B!Q_h$BPJg=@+B`g2kHN2tz9JDGWO>dBCXoR?=JmvZc!V`cc3ylAdOBwxpp@;$=PZ7T^zG2dW$XA_uV3FXF zd2iD?%3!Kk4yI3SAor~ROMMspeUCw2V1ml#BT`=XeWq58^mwJ7gEJK^X;Y=|qo z_i+F6X0UJVBh`lAi$zt2AkE&n#KNAo$zxS`%XJ?(+weXt$G^KBMr7P+-kdH%TV4tkv9<=)+|02c z3#6bILWx(TKH32&F{pqG@*p2pP*=-1f*yjJK90&vDG(z?`TrU&ZE9*N883++V&5QN z{_*>UI_CltL_)2i(0i(tj!_qd$0+xzF;MjKU|uz$wTQH21dwmtFJd)ltg)xMwyzp* zV+gMn2S7FY;wdHD{$^D{;7|3@Jbdpd$~-P3`d|lYKXR9yB?u9TH-AgeBm-QvJ^V_g zpCpmSvOZp$#;Lp&?{*o~SRuX0bZy34;x($M3qt1=dvPzfWf4zfq5(x)xu8#*Cw91(kh+-!pg%7l_C z7sCC;q7HMyim~b0nxe+Gso7(Gl21egYI*|liWF!@9_$^unb)TF+#pfpgXOrPzcHp0 zF!vxP0=JgDvDM<0lrORuuKqs#YfI z0&gZCI1fSbL{sfiQmyYz`NA~d(N0K{MwBtJcy()WD}v!9+cmnEbSd@}>j*XiFhocC z$vSM_buDAt9c}Wut?t7#SZR^y;Xt0?^4cPOtFkn&Z-eT>WHVCe@(jQU4UME87+=;0 zi`E!`+xLMzp^C&?;nnHT9F+6nVNQqPDI9nHIeO)73|(b3l1~3fq%gWD>E+Nfd<`mm zT5$fn@aCEk300nLSy`kG)>uBfOSAK4G-a zif;c}E+ql1m9?)F!rvqV{j!`TPmKZvm!9Pauf~*B6Q~AxDOu%;7*X#wY1VqLJJ(k zs(Fk27>XPuWHGyk{E95nh(~=ttsm!tH~w@sr?hc3RSvUta@Rj`wDT@>>HPKnj_=i4 zM4{UCeqvx8RE^h&W9pybkD&tI&C%(SySeGm+N-+Gi0e*$@O`smZtt)>TiyFc{;A&e zL~`o05l&JS)<%ShKdQC__@b`uK>eVkNPT#rhPv|a)W~uB>5A$zv2|W+-|pAIfJ=d2 zdJG;Xp}@dL7}(f_f}|k|hMHbXwU(D-V{tPR2#ONG#c)+!>#t(nI9VvRyVv>Xnr+9I3^QvFDh^4y}ygs^YE8O&+a0GEy zqW;Me&O{!W0?KsNl1qnAvT%^c7lv%Ja8iZ3zz@JMNEQ0B_O69HCUK8d(&C6ewkA9F z%HlR7<6^J@YBvGfhYmf~uPS5j$%??Qa-gkbsqdrb>()2;)Y``ehH6!pO_7won{(IH zq+41@jDfVJ<&z+XPWSg+>rZeNZJo3MXoCSUM$+_R(hecuN-*U6mZlOKu~zb)W=)i* zw6`U3qFc}>?&(mnN1cqM^zfrrhcDyqCKa3nUxi^~Xli`RT@~vSG6|! zz^gg#*>+3P$k3(TRM{!I;3F4hOteSmMT8pB9r+~ny3|msc{n3N1yXxO8EBqO-LTzh zY}O2H){Znn2s&fpldA|Ff*6SPaeDa0dm8#+T-f-)!ZQ$;CG{`V?$l$hF%2hPReBI9 zvC8q~n&D#GB`e)Huy%D{NwK2y_8e2zVH+VyEhxHj$+4#i%rV5SZ2%T>c)&Vu-Q%^> z2`qr`;E#z%)sLeTP#;-A0HD@t1QBf@jFS$mqe2+{ob=JCs9NjSBrzdFNov?Vg1rOP zkOeF`{!Dv`(RFj4R{U$Mv_F>R3=|x{p1jDXZMA9*M1J{ruXb?!a^o;8)g&{d3EYRi zYF^J#Ca&f#!YF3(_r?7bVBIN{LZ=#||7qrlaS7!g@teU5#p5p>K~7suW|F|+lcw?E zo3f)0>f1~sZ|dBs@f){F-wl#~H&!lKzjSCUZ5fjr#kCFN!OcZAIJ&<|PWq4a7I<>C zm3~pswEzGA{GP?x3iRT+~uJjw|mw?v^2;5}VkTSc2j)>9v%Z3zdi zp?}k~3ptm_NQ?>#g8_8-S^EC_l0lT1R-R$0i5QJiXBH3j}oyP0aY1|bQb+3&JJE7CSX&Eg%kADdw>Yc>z{LL= zgE0fZ>k&wM58|x=oSjnTIFokJ^ zrlcJ2v5VZ?_Oav7%8RygkHDt`Q#%u~soOR#EQ(H9i(5^!U%@2yJ60?^>ZKoq(t1TmuGzE zB26(U&nU5uX2#Ig)Yz)~;|kfi6S`cy(}o;$de&X^-_Jg6NB;g-SMynDV_3VkJEC^; zjr;Cmg#r>nU&dIKfl8=$3ix;A-$y=*lXKV!8KSo>T7M2zm4R18aD%ba-cC_y$YXt-k;*zi*`;A>$78yP;(u3W5>$7Gs0oT+!oSSw=$xIx7Rb+ zV435!Q3?G9BF=td&LFD|*@Q>c}Y_SdTsrjW0!alf%h^(nM(sZbQeG6!8=L1Yz zXr+~wziQ@rzsc1G(3=h_!NCQ=$xFdZ1fet-E~lADj8N36oSAp+D^7}7lWzMVX^t`x2^$U>~V#XBNbDLE% zw!72{CtO9M=B|2lsKcI&6>=S8Px56<&ARE%tR{g$``{4TCF6DqM_Vb64@o37TIqJ| zfKh=Xl=YA(5FOf<6O&Ps)#f&PZiYNSA0%y2o@>~tEURn78>1LeP~uEJR>2{rcCLzd zF}A}YqYTqng!fpcY^B^EK?{pt#5DJ;2=|x!PG&c}$CFfubQ zPHgd)B@nd384_WqcRJPt**g^mX2!0T3Tm$PV{1sGxgH-$vvZ=a1Tr(!6T>r^L?!^! z{Rkn-76J&u(O=;dI|2@WqPQFBCxsSkwu1Df&%?bz2HH`#O2xl_>&GkgvpH?gpl`>t z6xL|Kv4yDbev~VGDl@eC*0qGKV}QrQ@IO9VoS`$QE2`jvs4h;dV?1jeiUfg$gmH!j zCJ29|C&fmSv1a_pjeX2K`mLTA>HGdm4+ZQ%(@kmK;1r+X@W%ay^mx0Y*>v8f^vSaj z?%qtv=uO&FplJSuFi4siMZKdW?P7!|p$9Cw{?D*w2rZp2@RSLGCxDdDiItFf z7Z2$PPxSO37o45$DE_#Sj0A0c54|F=K8)T|gbMSBSUvKNinzyW+Ozt1^Z12_6-Hgi zg*0Z(#ohL^>DIIcm` z-Z;%v#A#;cn$nwqULq6_iZy1VbAJ9UVI)}Dca6D+Bo0RhB#mNxwkr9d3d?@Q&+q1H z`QhekEwm&~&-pc6&-toCiRGTSu(gBSm077bTru5je$E0xOWv!|Wy!8;E?*=uhGVQ5!z1(C?k;^`P>=1Gt?^vrFiy3sI}Uyi|A;whm7HYDV7 zY%P2ysc4FAm3sm1|G_W6g@`zkz>-3(t6)2OW}ohaepR^qVuIJ;<(Eb&EN>WlZntx2QIgZ@f2-XcQfFWY{I$nJCkwqN?T$Q;kx z#%U|V zIK@6dTLl+n1OZT@_oD1B<7^**So%xVu75fisNz?AbIGIDutiSzDZpC6go%9mzKo+CmeX< z%K!z~f>1Y7bd2MqJiW-mkoQV)mlo-C-0UPZf9dfyW44HNOuT=csO1}AfFl_AN~!4;2yw_4>i! ztpSiaYd{D)WWAk=1bS=H)$P9b+k6kFHD2@T)BOcLts(zOEr>A$WZz!C87VE;S=!Zn zCPEABL!HQk2clIR>K)~pnwF=5D2=IXih0)O;zGs zuwDCcR;NPsk1&--hTaf`#8DKL^;mLQ_GgSab=BPDhTi&WvAdMkUVkHnykK`$=eG;` zXkUwF<%btN`Tf1Uv!#eO5lm6h(}8Z$IZyrfI~KYLnz=jDvNNK$2a$_U5CT{W98S5_ zWYhvB^#Hh|EcPYJB!FZC2FM^r7b?aRKnTddtSua_io*caFlV1cyow_Vd=is;Ra&UM zR+~iXYlCZSeL;Y#J2;3^)zap9QFF^pu(!9v<@fs|5ATGm+AQhAM{pAFO!z`D>_*yH zgwQ9F%yJQvPnwBeIjhQC{1*GDARqG9kg}1!E2xZ1YP}omnVZ9iz#x%80JW~T2K3^Z zw~i-eNhDUn3FM;VeXA^Y;fWynZk!>c^A%mjhCDkb22J3oB}hz5oVa9nelZT?dOf46 zcs8}Fp@eY8_1*iYxexN=qSEboYKhT*q+t__e?Th;#wwnPcjk9J~fn~=yniLd}D7^$C_*~vs?NqQF zcMCgKxU?3rd78&b->M0hcM9F3(8fC)5xV6u zi~}lEko=f4q-wx0=vJG5VuUIl?S*|J6z2}KD;2}_dIxd47Z212K1D3igdZBlZ5Q`3 z$FMWeQTX%SCK+e)vpOw{Z==hfgWH6dZbd;Tx0&V^*3!-`BcD`Nv=`$;t9dw(GTm%} zA>lA*fE{Y3X2;GDdyLeBZ{L6(CH-3BWop!MkCxkhq9*J%pW}6Mq#Q{;n-k#xVgAyq9~z2m#&uq)5sW02y>;xPdwD| z`I_7+wxqOl14K_<5%qU%+X|DRoO*hS#Rr82Eo4d?KujfySd$}G(xjviwR6JQQS#U; zYNbEr@NqZA(2liO+JUjs44q8=>FoDBv*{deU1_|j%E*l4Ko`WSk@@cl0tmWz1N20w zlXPI93*bAh(meo@AA`d^DuUeVaJ|7(&MQrj7SMqn%|LRG;hYeGh zhR#7SuU+AA5yd%r9gjk`CU7n;k!@)t$Go$4x1@JXXB#u6}Om8+$s2t0)M zyB?vrI{KQh15nx&z5#l4UQuKFb#o55$YG6e1YzrtB@r#1d(b(X<|4$6=n(kLT z5x*lUzt<;}7WhI(MO5cYrzp}&Ab*qsa95*n~}+16UE zmk(h1aWyFU_@p#SX^u1{?yH9RFRows7Z`!@8aeDF_MaA18rS@;y+0D>oDrcpn(n#<_cd zl84fMi|3H@;MWBqRvA{PxYcYC(a|w-jv_+q`RGcwOALzce5Nn>Ml-K1oZ?Zm~-h+2Th0WI~458lsJLW3nb^;Zg7v9s7)GCOk?i zy95d_mcCRV3a*s*=74Wv?8#F55tqqiXc8?wXQCM&q)EsUU|FXP99L_0fy>_k8O*e&XsK+d9n;++0R30IYQ4tO{a6Ib?4jN3LF+RgU7Tm>_yDAuI zi-DRpo-gglhl>G2G?1E5dCuOG^xnb!C=?7I&li3FeI*S}Zx_4lR=j1GD@s~R3zjBT zCS~EN#o@muM%%#vs90tGQuZ^fs)`@(O2I3 z1K5f_r+m3CyUmO~IDk8$?QQP-tK8hMx;hubDe^+NO5=y1vhfCI=(Wpgr`z(*{c)u` zGerFh`DZO8mvlHV5W@Soj>>7&O%1l3{P^GKniQsODZZAH62}FpQl|SJycXvSar3eu z9$CjWY}Hqa;E|0Nq#ur((fv=))zsCs`5hLv8l-Tgl+cD|UzTT4@BC500X4zRjMUou zm!DY!Ru0!>#fU#`f_g;E|OGTUS0)$GH4niwklJM;xg=hoGoy z!gO~GrtX{)yFc$tN}NG-u8WR3ON(;gijIn&RUyQ5ri*1D=`+H}Y{Q+C54(y!oNpEt z?qd7?Jva1vY_zN_Gd?RKlZBl+v}!>g^Hd1+_320Wn}35yPVw#SsX69pUd+$8BRQq9 z5TQ=cKsQWJA_gHrKE6AkmsGs>rbx`@(+3%=ZFy*0vZ|x_aFrQll@L~UP#_DWmT}tk zB?57>K2G(`{1qon%8c128|_0-gah7-DTRi~STJq>IPE1pQ2NvZK+s02{%Ko4*ov2o zoQ4hQpxcTGTKrphnveb&!Aq%>0Qb}6()l;rqrN_c_IE+VIa;8CJS`R#pgzbjXpkrz zs&G|DY_&{8#MIJKhs~!%o)EbN90qF}gp0o3@jcAjclX30cEH!Z-dT3M zKCfPG_}@c|BB^^wriDY-X#%l7ZzSU{k0Bl6_R!yp!)R!n)VUWvf3&dgXiN++j^%EV z4zI_5S{c?UtWBgjg4uT^N)f*sudyN+?QWFlNh8w{4MGHg%D9X$Ab`%Ek3RP@32Lf( zIx@m8ce4YelV$f);LqeE8$^yTl@k~i@q#Rv5WVncD%kUBR#vdQ1sOKZ6JY6H$Uiq} zf8a=JvT4TIQ2K>mQ1jb^u)}IS)^cqpCPB7LK}|j;K~^MsRHOA3K0Jg&zYPhdrUol6 zRrQ7(asQ8648Rj7{1@MHhviRT75iOi3k5sG?F7IL03u*oI)rhg<4N(mERcEsg6#{4 zV=(v+1JdWzS`^7n*)vWQv$O+qeAW#*7!JP=ZC-aDxz4MIIbjAM=GZ4XU}=VAuoZd=>@vZ%OADd=@|Uw#B+19`TfTT*geR{X7Xh7NkaKu8cu4cJ?Bg zdKyDF&it<-6u05Nf1ev4cFyR+bV?V}hJgWep*vN$te|LfD*&_-cu1Q10hLu=h^FND zkvs8~CH3uM)0)BW>tPtpC73Ca<*Yu_*d^g9=&glk%OTa&=P@n~aYxeEmm-ty>L- z;nn;U{)9z?W6Ryz&7|i%;z4)23%^`xYeV2mL#`na6e-gK5OxRy*SDyQIGy4Ut3Nm!)9a5=T3?siFrT-Ny z%Oe!E!O;mgTkIu4(bj^(jaS8<@^#J+hmIejv%up=DpC=Z+3Oar zREMRBXm)1)&NR{vf8b9m*eP$aU3{;?z2x}iV6*?ZXvx~I$!7joZlv_5Abzw4V z0H7T_m>H?9Ro3P9l4gGf4YVbvY5iw11h2`%jILb?^mAo6a8(7;PxUp_Zz+HR4^H4O zRAuYOpCj&x`9wJi{OP9p*2@A+y#(k-0l75BYQ~;)X93F2*!#rKVZ`YNW=aNRHKZa) z-FY7HxvhWcJ073)F2`<{p{?wCmoMQISA8W|UfYFW$m=x#@_KB0xl-M{bp}h?z)E}E zt5NgeW$`D%p~Da5N`H^KeY`^ykRZAqHWrO8_{Pq-L|F2d#B9D8 zm6yk;JvPJJcZem>#}%AYS-p1N_h&qB=4i_iH022h`m^`AcB?cK-OWTsewSoTqSu(` z-B&EMa%!wrQH((Jq4BpRF*+wbT@yCg`Z3&@}6ED)i&=AS4-a*zsn}o@Pj@%5Gl1 zx)l#@kK1%;noZyN#&-vU$_x1_s{j7QBg|&AV{Umbc@q|bcT?ZnVdL8ot0T}Q^8c~) zl>t$<&)0OPh=_DIC`d`HsDyOLvUHa;O1E_9(kU%VcP=ThAl=>F-S7SU{_i(FEF1TA zO`J1lW?+Dgka3IGkH%;T+VQMis*pY0cJy9spByj4sA_FRRH)xHV=ysmnNMM6X{cW` z`#&oR>*amo5b@1lIv4t{F~b>v%SH~kFg@(kos^htHe#{&Ocr6$N?+<5zWij0*~El2 zk%9#oyZ>gpJh1JMT;pCu+}GOE9n5XM|0!0AyVlf`t8p!^MZsp@9JX>k*^#71sBcRp zi};&eY$*^#sQv42kZ@6v5Seh>cSe@Rk>iLbq5BJ9-x{DNB`^Lu+vluqWtz4!Wcewv z5Tk66mlzcR)eDK35Y5ZqptrFnh{G^7GXD1?JuQ|9AuVnm=~@{ zJ%K!B;ecYu``0WV%R=&9d7n+puX?2cME3+eVZkf2(AOG_RdqNGgzP7>S_TR{V@wi> z6)^UJSBdI*DV=Asn2@o%u#cq3oNT|qjF&Gzy~rP;Yf#_mq67-%$&s6z=ra>Kkv7{= zov655xFsbn$Bh&`dS3XM4feR1i;nN~8V(#=sxIHOI3Gs3o=?r6JTXMC?z^}cJPUGJ z*xe%EU++vQpp`ZRTu$mO>i)yB?vvfCK!VV-HY|S#MIx*>i(^5;;H;c`tdO$|-(z(7 z^hXUNoTY?^m{t$LgZf8Jp9zaWrLoHqm_pF0M=%IZ)G(btm|`&v3zv%Qbf;{YF@y$XD8lpZ{q`@^B5`hBOmYZm3Nkw^>3)~7V2 zc2@dSYBm~(QxQOk+HZ%@!;vX35`Q^8*+y!pTkx|d!1RmZN9GR>@#Tb0loJ;+%O$rr zt(wBs{}szJw^xq`fohqvrCHo@^u@Mx!=;21b$KDdoTgs!8dzfiC0tv--^yGED__+e zKm~e*bj2=Ycsr#2-eSfhg&u+z@_8iam%c|G@z}<(MDzHqB#IJQ0s7g6743U_m=N9A z*GVCK0J=zEBox(z_Wdghn%9lu)WCN1np*%zNUC)K%I1F(Hj8)((8$l=#Jbxz$?ULl zEF=8v_M=DD04DXik{7~mL#aWX`!*AMFyf9yKDG1M)HTU5S~3j$!EWED;@2Z~*{n(L zgfQJ^=iZ#F=Pa#DR%1n6mEFdudx%MT{A28o5^K!416Ee zdx}#*u%=)0ba;0_;aT-4=6O=+QhA?tEJ;IHZ)IHAn&dWlH-BBbwtl_To2CT!C8Ke} z5z)IN;nwx03nH8T&0UW*{x_oME)ciUVDIJs(ev5{#Yl2abd0{F-~I9d-yZJQQ(BIt zL#~SzdC~z;mQa?GStL73K+%{-{1~hBPTqpAOOVZ(La7T;H1#mY1IoJW0q=9Gt0eZ`^VKEREpqBdzDNJ7@>Huv|NiW_mX*=z~B@njbLV( zcv|cBt`7LPbgXgWcH_TK7(RBR63qZ1YJk_Pdny(moW8ma<9Gpx87WO1TusdaP0=fX z%+4Jrr}>yCCO@={TcOzN3A?{lsl%7La1GY2HY)fIqm{&HgrSY%#rw;U=pJ(HizwQu z@|f2Y{>j|BMC1Ig7D+r-531E_B9-Y{mcAcGPvV%Ey`*E9#ME#XcdX_BTIx_XC%18Z z)z$e)Zvz`qVEJo+Z= z&s;tgT0A;~uDn{wN`X!4ZFYV5_T^X;-Uftz*j2Q@Z@}&!oj#~5VQ6Y_m6~KblJkUy z>tJASgfxKBQu}zrP#VWYetk>Df_!xW(Usbun7`BxN6AHeU~PpezOcr=@>_Y`)33T8 zlL$GJ^_4AOuPBOMGsKoFZN1wK_&)!_I|Z2wyH|*j&x7ZV?l0?4(TI-&MO`)~TxMlR z-KyQ|+Sues&{hJfi9PWf|1#&&Wg9eDjlewNn)ELXW+xmg80v-Y+}%tgMHU>GSPtJd zTyWmBv)|^gH<}7LwczILx+%y>c0OwS9~Ov1Uigd*=ue8d13J{Ooc2pbUPC&BAY)!5 zct+?F0FCjhV}VNegO+1+D&EQ8SO65TkJ8+~LOj%((2!MaCgE(+P80?TZCNugvjG9L5M_pvhiY3j8RKMpNy(=oSt}Z;o1fc|JBVa z8_=grNcb2yGi#EKEFz$3&x+ZQ(ApOBgU0_va8(e2B( zBb}BeuzVe-ZJHj7tF;RIBO#R^7l$EPCZYON^-1=_upKLzyj=K~C*Ge5)0up=w=P!u zOu(MYHcmpv7V(X(EqXx~AZ4PYYa+8W`|YCopj%@)ow(TSdnRvkm6>#Z%gz(w>Rqej zrb#YfHy1Fx^hl)N`b^&Dx{vyBdpqs$JOuBJ!!HO2pPhWo#Mh&(NWuh$Zme$aGl z{E7<_EdN&!XYK$>1M)>IDh^I*X(c@p-}4{;VLskb8sJTCgNDMIu<`5ZHq#i}keT=e zIA2z39tfCF#m*MIO?UOaOo8viCL&7~McCfN7yJ$EG*Y1A5zho_&E4B47P57{_w7CK z9_z^W0((GU*AzN+GH|kE$sD#NU>NEe@7k=7)1d+H|IW4gl2M<_wN#gKBbZ!@-zYA{ zw(mde!MJuSQVs6xx6Pb%`E%ppZO76kelUeaM@gR53Z!pr60R z?|aTE#yIJ~78wPXj}hH|>UpaB$sjxNIc=@e$tb0hIfmi2l-|t0e1xDV{PUz7-eF{j zwA>3lbYp{*MxwoU6&Qp9n2?+kS$3@Q2-^S&SJN%29mm}@TA;l4k99uO-!$gGQ|njw zs-hBGY?ZPwa-u*$w#*5rdP{Y1qJ!vXWzNjoayHyxOSAoDgCVOL;qQb~DTZ^|Y895q zxStdN!EI;$h`gsxmsqe|ef**puUbQ`(X}FJDPb6CL8pRvQ1AVn^8DtbN)No>I->{# z0uJV%Yieo|T93WYgJoy9`UN`x23(!h>(G#EyDqzR~f zj1COqDuq`>j3LM4l>dC4kHSf1Pi*nqnzyUQ9?}S>CF#pT3)jtDsJ1Y`dtJA5TBv zUC#J17JQr)J#U&2Kd+*zLV@i4Ac_bqKi)_nPhPXsX%W@c_t-V1oT(#%M9H%29@_PW+B>`=`7h6 zAG5V(vwHCfHO|``NqSPDlMg}>E5jMF>TXK}K0tSD-G5k+#+c*u_O7`5zNZJyvv61O z=CjD`W~50QP_-)7;L0tJmQ>NDQT1%waY1?X#=;DYB6E6aKnw#YC_EkDFZ?$NZya$} zcUwJvYYd}Z>`{kPW51J$C^R_G9jQMiN1pzuYo7Z&YmQsQ#8rW1f{hD9MytrXgrdny z*ps3`B-%+62&z#`^C*7%>Uxim8Wo$OR6N)eGFq*tr$$A5vq@LOz_l=~=&VA9V0^{p z!Y<}qB}LWz%1rdfpB_T`ElydgihFwHrR&)E3c@j1OPeh&5kmJi+%N1zwOv`p4V^Ki z#)jQTv-t^)vk>y6Y{ky!YpR>2t__lQurOsA@aejox4%K^5x459&+-ht*7rm`2HmqC zHQl=WFVF!cHM~e4$&&$BlpG){8U=Pd1dfQtG^3VLQrR@73qde|jE|A@aWpG7mQLW4 zCke^!R(!XhvW{c5WFqS4G(idhb8wnS$%Qdf$yF&JO&a}?2PUDK^*wX@@P>Y0ln+-- zy+t25r`~Bvd-)*rsov2SSy>kBar`#SZQ?gV4yUL5Bw2;VOx2g2_h!sbksv_4Zpt4F z-ZeYE`H`oJIK4Eim%3@t3LTDpImzW;7wrG3H|^l#D?mYu3ZXR8MCJsP?CI&mYoBJC zH3%=5L-KV!u4G1DhG&K@$|Hf5A0=Bj#9k#f#9cxyeM zkUS!V@5#SOh#15ps}ciRP3)T&QB3kJj6c&N25}H$i%RIK^pPDLDFv-ca`fcL2`Qia zUIu^5IYx*5wnEZj!i~Lzia5Qks)dJo&dy3HZzLgsC=HxmZxy{#0`nH@*Ojy8={~^* zI2So1TLo(jwe-;SA4D4D_kCo-YWzYne0!cI&}NFV0{`-(XM`Lf~aq? z6Xaj1`9d#qyf~h(J9?S5to-*1meIjPJFe=CkDCCmXygz>N?^46krk^#RjnHJBy0i8 zgRwiu+z7?}CkqD*%`j4u7SL4QeZRd&-^A2-yjKx>O4j(a@!@q%8-2x>6ImoqZj9<* ziC{3`I7$Z%lC1srUZ?ZE);!`ojFu?B>aFBfO2j;pC*vI-i_M8N{_cpQTI)c+&tVzZ zV{BAxnM1_!jZ%@Ej#T5tSbWMuqWYPp79>zM7|cl4!2!R7YTScymNMgwk&7RcdtV&{ zkOqGMpVb>Of6kCDiuvGw80=k08lswYD`=lm+(ivHol*r2^H^ zv|leDc6-$?TO#p9{bra%v0C|P>D8l))rkHd%AjiJjRxS9Enz0G(cI%c$uPemD$Qs3OuFp=Dr==SBJGa+dNsh~*H}%gG`wVfn5p~^n%I(kx zXL0J-GJJJUy}TlCOE)L_ubmu#54uJxp70#z}lac;y zUYbF>?#Pa!1x~%ZZy@oUeKv{WlVhDtauMGx>M--+eB1i9^V%hq80o7hNz4AR5Or!M zQZj}2ff|gm%g(w)29Gn&NFZv_0ROqiY9)~If2WqKjLT{1WxDz4^-mf+Aeb6yW_*$X zsGX3Wb$xURf7A*}D*XR%Xjy*0u`6YO?!8)UroPX#RvRG{codDsrS^%U$dSASD#Co> zZ%QHyn~?EY#0h&#T;Ye^y&blZ55SrH<|p?1V5BlW%KvHY+(9(-dQ$P>e&}VD_?zF= z;!zjNAf^4HsH;2LQ#U#l3YOoSq{R$gM=(H%R@rc$y(g8NqCy1tI5B37(096{x*uV- zA?GE>7{q2%paEf(*duIk~~kB`Sby`VCt z1%|y*R5w}Aw^{A?fw-?aplpknPD9D!sKJCZe|?^>ef*#952}Zi)pQw_T2CHu=@p*p zA2&5(iYL<&e`{OpzO|y=8cdF&A)xAP^SVcQrI|U1*V5!A@^tOy z+B86z9icq%#T&PT2w#!7vJ995z4@4mDbC!M--vW?6ONEJv2_?c=DnCCz=q@aLJGb)bJWGDl zG!4%y?gi5R3Z1SErv1$bp-|o;=z8JD|A9CbB8>lPrTNW-bLb8lTotZJELG2st~Zl&PRe>T;M%imizQn z4~rMtEw8ztmR>fA4HCIC^2nv9$ee?Z!|V0#ZRv*o|uRRHy? zzwPv{`KX-UC^qKm~Lw z>Li7Z9$1hF;WHZ~im_N|I9;1v@Bd2(dhqo)Zq-0y+Y{Vmkt@~Eb3?zsI`Y>*e4bLC zueT#Z3SVFxCjUVoYD<{v?e3P}b{Fms+;IX(h!;jF$lN5##xH|G8N}t|I{5wrh}o!2+Nlj9ezlJE&P#)l6jGQS{ych(5S+T+Rt@03&;SZ0;f(r}3|^ zj6K)MLvLImq0#4|^iTK?%?I7R1M&s?xl3?ysi3mxkz2LQ=uTjn6Yo#26Yn5x22W0U zQW_uiRaj0`BE3zLPk6?SYf5Oe;MaD}M)8^9XvN}qtKjE{l}EgKaT!nfgS@DBG%hb5 ztyx@qe73SIs=~ZXnXyYJJV^D5i8xe!nN~^JM4CUK88H2I##LcN3U8D6H|n;nAFxUB z9H72`+!g0^oKtDZC>8PAPma6sOG|lqIob5zzfulN6^w{iWJ$>=oK;nK@aKC_0u+il z=6tjedRT6Ky*)h+h>QZE6IAufbUIkL=eV&+@xh!)+G>d-G}KT26*2Blx7+9~e_%x~ z-tIp?!k<|_PQf4N;f7bRS$Zk3p#T)5@q{hacYEI?sI`#H7RQ*5}eHg5mld<={VdfXLi zAb0b6;9zKR+yMFy*SkA#`j8=@&;3Imy}jEE&%1gAm4Lfs2415OeUYIoo%V4qCW>G#}9!yJqF>vf2==;Zdg%IZh-=Q^40-hZ;51Ttgz{J^{mBj4lpI}6dX zONq600~ROi+hiJ^-?hZHUNWc0)h}rHL{5cc{%8PL2@i>;Nj&1HXKxM*KtV!~uT*m4 zfB)>5e|UED`OQJu5{F~%1yI_ZjYI?hgt1ntwWmrz3Rk2($b8K+!5~f`wq}Ih7Y3kM z3UMmC*6Zb)4W8#bmaOhNn|Z(td9rhIBw84J zN#88!21C*W?TCH9B5{M-@3zwHPVV;0G0zeb6R{C2DB9$^HopO^OEl$* z8utyx^@0~xwAdYk?aWk=h#e?I`pNaR%aQ|8l3oj;&qJ4C4u6Rjo@wa@5^P-#04u^N z%|u!~aNbXx1Qmk|n3M5XR3V!?kiJlV(gf5B?}E58a`7ylgMtvdY*@FT`D&i++2EHc zycgf`Ew#7>B29KbN@SD@6q(>l9LprQ?2HUqP*;IVjO%8s!5WhkbE|8QH6%2s9H*6{ zDcx}X^qbeIYzuQE>gDCpK@1R@p}9K?y~4?N901AaQxCmy&E!;tNBUH!+{~PwZmgZt zGjXwAX3>xUYZy%=x2G{5AF?l1L?lYay}eGv=R$qpfFpBM@p@U#qB`?~zL;SdP@FBE z-)K-81Xg#-Dk_p7ade|_}9?#(KQBYB_##6Le+Le2BX*kU?eMB=6(S=PNLLVkSAjy>7wbQTS>9UKCw7gSuio?Xhk9c8ZU#ff3-`GLJ_i$! zRD>zM&P#?wi=P!$w6Sw?zBt*7R}v@w7_3MqPm#`UqzO$*pa=2Ls1?XdIH*+mYNFY& z+D-vE4=I|?CtJf-Nx!8<@|546DiX0m#mXogjw%ye6}$m|1~}e2bfO{WV43K8ZL0q+ zN7qW5zyu=8_lGM%c*mrMZsgj-Cmqkxo+3`J-ZN8Tq}1{BQVXj1)I!v zAs~g%Y&FP6aODh9)_zw@QRCBP{3WYiuTs680|%^hy|L6_igkKe(%h+6Ak}!^1rwz4Tyo zzF|O1uk!;x({&A7$88e|jL@Q>8^YJkMXpFqYikeZdB8n_A7ffC)sS%{9sdQMadTaw zv+>@BU5yV7Xsyxw`A=yY558$>9xANGcRrilkxtZeg_fYMem(fgUua?q==`y9z3MOg zpVwntC4I!>$FSE>qQ(0QuLAjv;2E5LJX-L2`_e%8$R9|cbO_r2^MO%B+zri54r>$~ z9H&ECjH-fup2n{g7Y=z;`|Diwfo?N?)l&zt6h^pGs}#L>9awdn{e@;JrfkyM@nH8n zA&{bP?NhUmbdkDUSKknGx1A&{-b?ioFVq!|`j&RjL(Q9(@T+N1yw<)%Qw|Yg^BY zQRx%QTcCW5%u!WEFW4Q|Nw2cpfr_d8O_>!|km>s1@GuVtHuAg|_^mvD6E8Unw|I0= zNv})jKqlUq`?(s}aQin+SxqG{W!&88Y2h}R&x5-_F@+hBUclz|+y}?UhO^$2cLhhb zk1-)Cyn)_BmqVx5?>y0{Jx?T%^ZWMp;=*|(K6^3fc^vY;+#oY}YPs!HbpTdFb}lCV zS}fPB#$b?+=pGVWjF97Lefc>xD8!Qv3?cUCP^ZMnkXc(E6D~%w>W7`bGoNDwdbqIT znbFq`0>@*KILFYpef($n;9VzMJl*Fv4*KXzTUoS~V~86YDAfM^#Z9_L0KZfH}M+26!;q zcAO@{AT2|5CEA}T4I&?=98ntg9RWu8G}uW>3Ihih7vD$bT!Ca+IWT^q;#5H=FD~tK zo8bX$;)4kNlP(o8&3L?~+48^fhK-xEcZ4kBg;cScZhAg>Ys(~|8x1F?BC)1h;397Z z8vm$}=*EnR#*K4tM&1&TYQNpeGO41cXd?~|jy*4$m7p5qa`(EPrUa+0Uk_bk28H2w z_6!5E?|x41gKWr`JI**SjFlvQIUjmR(Om4i2*eXq#Kpz+yjl4%qcU2Mq9`>%`aQJv z`zHItw$D=`lFG$$>-7Q$tWwYGvi4)@Lo{a**2aS8xB{fvED}k%e#x=K7kmci5r3w1 zo0IbDy1Tr&Uw)>RVUa6SVUX&Cri9u|>jpbnP2(iN`{Vx+Zp1zhWr+}~lagA@!$C1p zHr5k+@{?Oq(*`+ndv6RgB)tZ%H-9%4lW#|eV{#;xezZ}b!Z{1CFzk{t$!oTs2Q3Gg zA`-1k_W(#AZumLaa=8*%#TX5E&d`dcGq)cV7NhjUG!a{oYg`Ih;#9`HQ9YN_`aCF; z@upxE!`KS(5?E0;ETy`__0%Z#?;AJOs1V^_=jl7b>)xW&xRja3>{e~iB+h+ zXHcO-M!^c3U30@|VdYzXEa7W^RSx*86bHL&9JbejYAGBx$Dj?aPxLxMRs>T@X@13B zQvaK$B-6>U7#M@fnR{;l%u*`4HyAksgf^x&Ucix{R#8%UnTq%=1XB8LveNFV%22$2 zlCEZV`q3k(6B}Z8^ntz6@BO^apJNe@+N_piz{gAvD|m{2pcf|_odVb|zEiu3_}Lra zQp}nPzH(k$r{>Zu#V)y!VY(lL=Q6Ar7e*P@)%op(1dfHW-+DPOTVj-VO2A~0!S1O% zXa=#Q;AcSULZhbNbR|ahc%Q+=h@9wpw5;Ttmypl_(8W!x&I#^3Oylxj5}hUfL!jJM zcsbd}_?P(J*PVWS2!ynzCi(#4>*kyn+kmWG&wYYK6NjPH_a^&OiaF7j`_rYpHN|Q@ z*xsFo(MC#8sPX0*X|jk1K~=4SN2);Er%rcSOqHK!`U;wTqKq+^md(MC=63WEH`CcEUzbMR53)gw9HcFd^xfN$x_H|9fmG9Eq|`UT&v4v3m(TlP{jQo!ih+T*Ru{s_01sGzPZM>XmiD%|l3Ia@>3__NsxFrQk$)@- z=aKkpoN^daB5FD160dgVRWjytTBpEUgxw*sy5Kq!g!t zeoiOO8;B&kxF9Is)yGwzftUtY+zf=7;w4B^7!@)+eo8ybvosAP)qmxg=A?E^giPPQ zn3doti$db$xRxNOkRc~;JaM-|ISG4T)XVcWCgBE`@$!a+(dC&buIAp)%flEbXa_R( zsUpAn>RaIbSW1dg^x?O14AbhQFY=sVEXMa`vY0EImovH?(${Qr$$diK)+XA0A7W&o zKDpdqh-6uXKNXuYw#eeQm(bS8O1o4e$#$zs=Epb@!>1(|0?r!49fW) zOHz+8DCt#BBP)#py0AsxIS$l);eSsT&|y-)d6v!mSky%L2YEsLTB7+zLxSv+8;apb zWDF_>KzS7WH_+(q_BJb~fiSPSbZO-cb3|ca{4B-^B<#A7Z_Rj}l~o)ZEBi0ggfZPxmP}7?kL*P?L`(NHYnml@5QeznE3UQ;0276y z0+Y^UkT}Vo!^*tY6!DAfIxTmSM$pY!9&k|q;Q@7Ze4>*-K1c?{5Z;d^ipZQO>JOTc z;hT2Dgyq1vtP!M&ozy(9`k(8#vRX2leMp7$v7F`g9UagBFd8iHrv((fo*B7}*U6qq zk>a9@gUVpGtHc5s<}2SWyWL|rK1yVFjs}i;;UOCe${&W)n7P-~#!9lN#+l|GEp5MG zu`38~utr9(-Q5}@8>tIHe?L;FNIsj%h_;Sogwh2zev0h5^(M_0?KS`Z1TakbT7u7) zw5I*{YoMw;aDeuS`dQYAZsT2r$%!*g-B5==P^^sk@gj#Cc%oILk6GTl&s%A1Kpv!N zo@a}3ixF%0=CFHz!*Z19*;{%m&NyE$mreXSRwhwxf928{3|>C&)AOXvWfH%p0)FXK zZh_=yPs)ZJ^S3>08=x#DGeC(UlF|W?^A5g%&x4XC&g&Xgw1)xuYh@jIKx_I_(#Tq4 z^W~>q@fkv(t-t`^36HDd;SisZZADhLNrqsDrl#}FARROXPnjJBeSqX`%#JJ^uj(~bt;z_nk2^sjcgln2Q}l-ud^0|<%TVfKF`$O8$%_v>Be zNT9cC!Gp=Af)&#d<*1>?`XEmQj~7Y-SkCiC@WP5|t8$-gDkdAUzocuu3F{elE?iD#HLm7tKnLwOUUt{&^4($B5ODV!5og79GfP8T z%qc%i>WMWjJ8{U;!%#p)WIu+`9Jwg zAO8B&57{T5+=EVtTZziE*p|9khN}5;S z`o;*=ZzK>e#M4(X>z)F1;jIPitjaZ*ZBvif&9=v>GQ+;*9xQ6LdM$OY??jvjlivj{ z_n=~P%=H8`C%dXkx2uj0ghAdR%em<1_&SY9V46|7R#4s~0#B3GKYGHBP81wv83t)W zl|%nMbt*wx5hYf(D#sS0q5GoZtdsQjj{=lL@7LGpoRYnF$Stg2OpDr~VLIZsR60Y( zzu0*g@V297dH~7#@<49Qe<9NY;FE z?2I74enUn71(^huBwYGVtMl8B>u>Br7!Kd%&n@)*i5W~U>^T(C4cSHhy6>?KUDJff zfwS3BCI8sJf2+^KL<}2*$9`l-3O4pHPTs_ZoEOMLBXM6LwgTl$5MxYLHn*y?mF|Hs zJ$o$)S2{7&qjsEO_!-TTZI&Mt^eH)1!`=Gryk8(an5f*I3@jurBV*TPN1x{_ImhUk zJVL0U{wWb1)V+$?tk_vb2uQ7{Z+`6j>`b-M4))`Abl$!@HTMODD|VORmt$ggs;5}+ z5fz`iXZvo3LK;vx>TnU%bm>Bdv1rI8P5~#`{@Rp3S0o%y(w5WhXR;;CFo6$D#)gCz zCER=ufh@kLP+dOl&2KL0#I%1<_U^=Hw>Nd@4?d5NFmO_3*6Qizcv)J7*(T_s!w>JV zzj;f_`mJUlpky@Eo|JkZGZefUVn9^-m!D=NlZrGzSAz@LR8_@#51;a#`EwEqF*JGRwxf#?JLi_5f}kSO;abpSbW3+Mm~~qLvx7 z%IKBTVc=3-NLU&16F#fEP4hGiDp!}qos?0jc6GGCmXzfdq~mmz;8m|$JIY&A*3EL9xHkAiriR08`1s< z>N48HGP7MAogE0pS>Fu>OiOQ6%VdC_DpHn;k~jr=YB1JDNtC7^V`{D#!yGE%B1Vs} z5B#Mb9%7MCv*vFBrT)(k;E=n&jkU6ce>A3!jUxs! zJ;;^)xwqaneoyQxk7dnmj%x?SVQ%Gw_<6^-0A)8&$6vCM7|tC7%xaT4YB+e&=ylBG z*t;aRnW3S>Om?`SLZl}%OcX`9Ed=ts>WgD?%;#px(+*@3izTD(H=$Q{3Rs(g-86w(rw6&5g+sTR9?on&0AU=(e8 zK|%Q=f->nXW6J#uoqv2Aj_RGCCuAM<*4~C&iChq71X*beR1Q4wC*R6+=&ZKNdGmuN{Cg`*zg0q@Y?hH?$|i1T zUjVUnscmxp*QUyJ+vkl(4)>_Sq0%ckZ`-$ZVlX6M@VS(YMw-4x5KW*2kZKteLK*ouKDIavVS9oF9*`@iFLyRb-^G3YE(!I$c5i0v|k@qQ9k|BFX6XJqZ~zz~#=H|_j| zf!Wk^z0KjF=x=K-uNFBpZX(e8b+C|?-K{EflqJk=Fgc*VX~`k-`uN6y*QvANuZPPo zdAqm9M*jUIrdtX9yd|d|u8DPOh3}UTYNr2cig{h`-lvEdrw+;`bDx_jCXJi@vv{kv zHOxDh$!3+r8HaE_PVgv$YaO+&zG*!EYqi-bsLONBac>)Qeb}s0CS<4dpTqSR`xMfP zS?UX=qN*8&SD}D2>}cfYTU?=J6|M;}7Xtrxg@Y?--v1S_b#~H76h|Tl)l8y;u-1YH zUMKHg+HmgTwPa{jW)VM8o^D4Shw@gGnX^2S-B)*C2OlP__NAka(hrj-@!s>xIn2K4N#x0o=bOYL)=^{*^3w~(EBfmIy+>5F2 z&&%mDo!fcG+j`oem-4|eK%V-YsNruMyux(GLV+pQh1KBx3OZ>-%W1sH_%Eg^t4*!h zR>zF=R))^iJq_P_g8~%Yek={$u{bho)z^TdX6{p_1hTBAGQe3?#Z4Q zeLQ!E&$cz5*nMsv^*8N&Zkk)J3gL)-fT?*{=Xs8srm(n=hClJG9{b#DL`_dVCHXM6 zJZ(>FKT`Urk9lrp;m?C8_@9d(KN>%jOWl{lpFp?M%c^O0Y|nAeg)NDv(QwQ+r}#Da z59gQ9JRNfh(-dxr({J|g=JoZG;19d}w+Nc2Iahq(o4D^@pY@XIS+)qk<>Sk`hDw0>wV`&gCFbWt=^^Swci5|v?}H6cyt-l$o|>2&}<=s#<%+K z-1tln(|570%#`A5s|yD9cH>PqBl@e1re12kGf#zO=3kLlS^ndk6>_PwP6yS;f_Mzi zJI77r)~{FUB*Vv@PhZS7nOOQWRTYmeFI3p+<^ABcu8^tYl$~vIt+cl4w$^WI=-{2L z^b9=EsZ@0?)nYO)(_=6%)n(X*>9cIxF3=v&RDI>1Ym?*_Hg49bJOA0}IZeo98b|5_nF8BY?AaQTxs+HT79VP7VW` znTl2>gP{~*1p<*Bg|jTo$7PIXx?t*u0*uJIcVGgV3ufV`zWRX?I)BrhQ$Z<1>zDm19V~z(h35lZcapwoq98I#nTV_E^m{#9~1K!fZaZ` zbz#x~|9Qns?%3zk7b9U8YuHN=`;{T6zh;!dbZ>_kUuqyhg~8;k&oI<$?ZlARdxwqp zEMR@3yF#}emaA=e{T%%1)ULmF zhyU?3A2d(`SAVx>>b85k+>d~}tLV9IO-BM_>?5bQEZwf|L9vBxmkhW4UCZ&k)OU#w zCqJGUmT$YsHdZmk+4P&98O~BfmRV@vm)veEck>%dt<(J(WV&?qnJ#_{759{lM)L%X zCgZP!eIBKRU52!Tt!`y!YfXx+wQFdJ6TYRZ##%nMXjUoq6weOS1n^fEY|UN%Fz*YJ zTKGF|hS);?VY2>9O3zI!|X9U!>w_&lp?CJm-@pQQS0H1xZKWQ5Y)A|RZD1k zOPv2Lrpfr2DU|iHjN@B!)3+tBNz-Chr$wkEV2%B))4E*OKyhZlr>oXc-~ZmOg?m=` zvMmj;#^Yv{B_D*snO}g{*EAZz2L4UI`Ls{!YOp&C|L8@xV9$p#mwx|aw|XEXG;eIR zCcWw=8}l+7N}ZhZ;JT?aTh7%Z~MRf>1>~H~= zhB=Up3YB{1va_tQORT54dL``Cm&1Doc)-2xb<>^x&zm#3ig8^SR4G^*#s7WrZy`7+ zi8x?G80DW9^}}6mSQmz+M*!aUnWeia3CD?fg0E;WL;q#=UaC8qP+zBu9L)ZT^{B7T zn)$ycLlRvBQKpjPl@io~@DfR)gg!B+i^>ad>Cq)+-4e{Yj5tcTRGg zot67!9kjS#27(4?yn~y|pP0)Z*+?qB1&ry+zIs_K+JW;GjqURca{e!Hm4C_T_d{C8 z)}^A$yR4^J*g9aL+&(t2eWmgz&8M5Qtc}U#M?Jl}!;-VJ^YZs)yOM54#oL>+ESXUK z#~aJr&Fid~!nRvux3v;bj5Pcq#Pgm{KQ0*bBz$`oOq0OV21Llf<|Ur2rbDr_Sc;<< zLY-Enr62v!vwto+?Dd&mZ94FC>&EZBinGm5X*x9y)h)TF9gi*iR;I&$CaXMV9fgfY zjb_{I+pP79nlrZs{@zxbc3D=NL>^_Pil|KurqGp`D=9h4mS*NR7n}7pHCCH+waivI zEK$z7&QZ<+)v!0#dT*8LI7JoexH5U>lQB47#pbUe?Ts~?`S{=reb2jH$6a#sz9rq}jj+Y$&4KEF zaV7u6waaWCw40wE&NmBi|0QX2yGtu3$Oaa-_S+U$81Effl_gy3xTrfu@Yo+;PBV5+ zcnRuh5EWiP^x0(&;|Z7Cf2buleWg~G*sJq8%bBr>5YisJdQE7Ww2Xl8VkByKz}?73*p;L5f|H4e*@CR z$Lz0tPefn(D9A|HE?ttI2-G@cCEbt8_Q>aEi_Khg-LievrMp#w2x)lYnYp2%L%NXp z`a|o(&JRFldcTt!o%k8E7>l2EbESS@e#t!~UFe30+~dKJcXy+M*I~zj_h7=%ad195 z{xhMl4uSBAf$&E5XOoc*{}*G%0d91Nqk(|~=^CMnQt3Xr$VP(i6T%xS{u_tERIDsC zvnwa4n>!NEEW`k_WE~UnVf9PONV3OR1u?JX7iK+lWDe5GAZGe0z(%3*7&L4QQ6dsk zTsqwM+>H|AKYLLl2{+gwUW#ou?Vrz}(c+x?w-a4wwZq9r`_Fl@Y)Mv>%Lmt0HV|YJX-p&$cCKggp8ruLza#>lJV`^}wYGyMj!HJv^>S}{qa5zTRe#U!PFaEf z0$J|f=gGWeYd`YN=YHI(U$Ge8c1CtPFXs~rf}cp=K9=h%y2w1PO`pwYiSfX_9yD(^ zb3sXk@aq84+dkv7?$686Uh!xA+bfnfM*aH}^G%Lx?{DHh+n5_9_eZgW`qzqX%TPhY zVv-(5eHL8fD#IxUNKbVdjqVj2e~t?@+CRP$wi|L6Hb49zY&H3Pw$?Kxz0D-lTDwZQ zj$4y9jcix3(5-5>W)|P9Kd6z<g|vI^-vxNbJ=U-|NbtxN1O~o5vJFFNFAs4ppFG~R$#=el?Ecy zX@4W#Dbo4zjj+$Sd!qqDs?p-!tPv7@oYAJvEdnH_ZTk^l5}M4Sspp$N+BR;`H$MJ9 z_TKy*>i&-(y(>y&OM|jZRLBye+rC9vT8J2ivCbrJOGx%zWT$SC>}!RwjAe*HVNAxZ zjF}Na*0GOmY@N62{(jE6uJae1>-<#Lyx(SC%X57^x52I-Spm|oeXN4D2gicR)&K%x z{b6do>j(i6T4`9n^MO`U`eW40Cd++Wu2>Az{yvqX=(ve-^aG=XCe|AL4*eWv6Dgn> zCH%*;7{wH3Bg)CM9)#TdS4;52yZ9!%W1?QLbgR&v!+&39#Vy>o9l_5SEjL9!2h zEc~yV4T*=r))*Ia>ak@BQxxak_pSU;kT<||?A(l~g@R{j2OG{Rjl58~8sF=BdNz6B zzo4W+_Gi1H$OGH=jptwa(PplEkJ8g(nm-+$TU>TnK2XpnZaBXJKCmk6s~D6n?JpSE z#esJA;x_oReW%IC#Vqnd?IR`6RUm|k(Gy%5DwTs)KxU3~GLT;^x_x8&%3bcR7*T%F zC_(?|GZ&s#0*+>|1X~5o(ObMU0=b-fk{lS<)3uS*%yq^Krh?SP>sObQYZ+ z6s36zECN`ym_oH57t1_f@ITQj=mog)v)w5|j9Y-Gmar|We{!bpkCBIqo$o%k=e1=V zCw@+KEXs|R+b!h!(Ju6C`jrs=^W^z=oe4bSVmZ4X9e&)+@zpz=H6DLa5wbPX`SRn+ zeqX_QQxrHEth(N^KBo{OoD{Stx<0jXXp+5iXuSS|9dNdS-|L>pdFc?mfl@8)tMRu? zI(2v_nBGoXFU>i$$PQUoSRZ*8d`bFnpOHR#U7B!rH?!2H>9VxO_LD03{E$tl@8%t0 z>w`m_#%FNw_9^<8t`Mgfv(D;@8z1l7k__TbotE}{Dc=51`SPn>>I#%&&+`F%wx4bt zd}vP}t!{uXDAA|y=cG6YhLm`yX}lB_q`y=xZ~e+6_;N*U=SARDTh43g@t>#Zi;d&b z;8CASTJ@-jy-{M7BzNh5ttS-~f=ezh&dN~3q{KL-OEuQvm zElwX6t*ak+D-gZ5(raUUF%F~tN^WgBe)zXNPX>stfQ;$#&J;3RR5mWB1f^Pj*->yG z&Gwvr-m&-dtxu*zoz;^(tmjJ6lUdN~&c+LK=%$UiG5Z)^uVJ}iz_YWF1{}JAZz0c^ z4fcKx=|5RvRVe&B5b*7cTY*m+-Ey#QIf6sZ%Mr3###J|&f#QI|#&@l3B__Fd z_Q1_cTdzh|^nAZ3!k^?C4xL4rymvw*F$Hh*s+?6HbkR6DnX=sAzdF|VV`_U`D#v#v z;Kz)_RohJl|1&lkd?<_Bl3JS6=7O9oqMe_kay8>rnQ!fl*zp_nGIdk}4|)}d=x_}} zlGy$|=&VOeu;lmN2tUp}FXsN58{>6=Ztl_Mn-5%_jdevOVPN{sZHj|*Ukxg$k7pb_ z7f1HEHrV)`y3FZq8>v1BJ?8xN^Ho{D!K%z?xd0*|Jh}+a?7{yLjaQn@H2y2dAtwkk zQimKNPNS-O#ch|+yq5zTt>@tI!;I~9d9}o1lE>I3t-&F$DB?mUPF#xTu z!xzo$7_ahQGHoxBaKtekH!;IWoJ&2PT_KL=DyU3q4~*lf(DSyQ&Itgp!)^`iXn?zl zpwK-ZYdX8zwzn;gQF1h)X#8B1x0Zh_q~JBrt*kHxMoBFup$M!{^l7vDqX?kbL$VbN ziSIsstn?~EE+T8N)(-dXspUB|qP<J#<=pFdv937 z{C&Cf$%MGZa%^;@Z)*xBLw*|gcC=OssFs4`Dt7^EhKWC7&p#Jysu!(^7Jtrs3yLtg z$XyM%i8pY!#Hia0Qr&PgBBeX4@m@!wTG`s3ziAasd^E`3$IAYAD)4U->+U$v7SMJ& zQUZvl2!b!~@iD`CSuY9!_o`+FT>uv%_7&o>0yHWGyZP}&k}Dk zKCaHw{xI;sMe2~$5tYf==0NBa)xWDm=5W#Lo+Xz_Z9v%YY@%e0Q;?dbOPQKx!OUsV zdoQOFGsN&<4ahKNWSB^ST(j3I8Yi9(a%<*@^NN-0TC!JH(da0g>Wt*SoKPAvx|NQl ziqCMbAyoO!W~ij*)Y(_y*6{bA3~XC;m^^D{H#Si9@J~LU5Q0p7BlTc{5NqalOk%_@ z<>$<&Nj6l&BvjniuN5Q|gqt(!V*V{Ej*di`IZ)?3vpKZg8$k|RD!I+LPz1x2$0`=iE^7zF^SHg*N*j(tt)ObN93916Fyua>p zzEO4U8dRyw<8#;aEVZy%vLeL|4zGqHy{FnHB$cLr%lP?XbG<4KEt;K+` zz6Y}R$gXfP=u4bxcq-S|h4W~9s?fp)ttgF3a235ju+1H7YKqkw5WgZ~X}$)8RV!(P z@gV5ow^A(N%%+ZdrKp{Vn*_~Y-iQ{D{U6sWygF?zX6cuo5+!P@&l{3{FRMyeh_mX6 zu&MaNqCT9(S79denCO%jOP{M6t728EO}g)lm~<23EDAEdKQ6Cmd3@ z;%Ii`<$b#l>7t!o#zi)XZ}us*V%GL56(~o5k&09*u(Q^YS!TFd>xtgderc|X7Z)vz zu)HNk*m^_a1Mli`y+{K(i8neE0q(y zu2Qw$*GY&mpF-uzNee|=l%Y8>u?U{sYAY)btmWeH8}=!}K1^Cb^f(a+#5tZAc^>>I zXW+tKVQ{xpmqeVg5EC9J2b!An^~f$eV`)4FhO=~-hY4K*fvdP({a)rf)*<`cmi*SK zpLUexRBc@1y}K()A`f9;{2a}NF1J&`LX4)jDcW4u=V)NY9!~ceTgO1n{j) z1xRG}=)&=O1V{q5UMggnR@<@K|-Lb}CN?ottVe7c|jE zJmVGnfxc^=<)Tmbqj{PSroDi7_u;7)i<|aJbZR98y}3J#pgwfIJ&UIH*(ea}JjfSl z@*%8#u^-ZSb_K7WHAJr)JNEtqQX<|{s{OK5G}2t)y5Q@X5ex5N%e#+Ry{}z&;6S;Iey^J{x-=_~ zd!yv{{2%8fgL}qbuTow<>Xylpn3RY|%Xe%Z@05Eza3FU^&C9?T#&rAyGn<&!L#jWeR}i7 z%ZzyvFSx7JG;V`&HT%NdVoypFGhvBXWk1;*x=MzJDWNRkLL} z?gwJLgWCm@_?l(QlJ)&?1NY}1a+C8%UVI|0hWNfUFt53a(t#1QZ$A56p>qgbTY0UVaSGD=B180f z@@tykp~-ixurQ#}vw=O#PF$mR5fYmZ1uhV>#tbH9FJTE_zHSYg_!ZU4Cd>9%HLTh- zi?w6R4@0ge{-Ifiut_NIFlP@3;#BgHkQt z_@*rP41I%G%YBz_b}bl%WS8f4FS*BO1XSnnLAe|yPXwF87a zxZtPNRD;`ul@JZpZQid8Ng$jHX^aHV*`jc0@9RXbI__AG;`c9jF3Q3=1Y+}V8KFK8 zYsJH>t1UQ}aojuZpg>D=srI-YTkWzK7bkWb>>?vnA_G2PK`3 zfvE@@Ti$POZVG1q`Nnk34I~+Bsy$KSj6Ycx9SK-87DcWXTTYaUUFI0%iRWv4U`RSI z2ISryS$cScc4@;TC>#MjBVntbgAtLo^~0ae&`Pbl)HRxtqPi;3xzc|pQfja4Ic_S- zN;^`xCS~ApV7hV5kln`Iy^rf}#u=90ym*E|s8eEJ4c~TdM}+H{_>{-5J5!aal%BI@ z%toInR5N+8wwtAQzl@#waO$Zj)Nx7Sls{}hoXL!=z%rBL0li;;Cy6CB&TP65OYpX# zt5n7c9~TN@{B483U@KTW56doN1{G^j^ID;f@9vu&W4VPYHf? z&?`=Pl_`nUQ&BU=)=XEOaD|8A7l{|7oygBB>U>?MO@*2P`YBOvLV@(UE-I18hU^GXIgEF8COb|avx3!ap~u( zhy^S#ziEwnEA11putLw@>W5=6&m;y43E@Dw#{(&J$AQXjXDiN9_d=O%7fI5~B7~{1 z<8%^_g=UwaLQSjb+6XIPNmX2Q5z?NJ7~iHSrzwAs^R0DfB_=}VVT_U>CxW36i>p_l zy@y@=miL^&<9{{2Z3u*zEkftmQ1>2IB5qRdGoE(7sd?PhZ$h|hdvaf?YY!$tD?%`J z_{+(Nl)dJGx+hKsS|`X{V^-pwA`^gK3?z!Xy4&NCM+d7G=dNb3BTxA9b992)yCZEDdZ;_@Q}N=|x9IBME0N&eJ|_a(E%pr4j5*V#RI0favNE zc8T}yRsW#Q&bZ8wl-6lvrD|p1zQv;@3GZL-hHlsByIhJ3?!G<6-&k9_zzC;w%yiP7 zD0e*;MmFuKm9;cyeP_uHXXuONkA%d>_K0VrSCV5`<%ty4m%>cELfnxFh=Y8!uD*&( za2pSOMIA^7JZ^J(*amwogw0vnx*$sdHPY4TG*iJi9D{bezele{SVI$3$>~*=Zlh_l z6EVMzkGA4Fb`HUUlIGdVKkgteV2pU{#L(mh;#i5@zG4osuS1i+YHLQ( z?9>#ETI(mIkYkoZr2Z(s9;E;EH8V`x00xE<2q5`e2fksa zLEdFGo8b$@Pf|Mq1<{t$><7NA+8!nG_v*z3LES6$>q#sf5v3+raY2E5Iezv&HujS# z%nXMEn#&mBtmFU5BZee41b7Mw%Og+_-DzlpN4+)rs(8MdBr24is$I zEsIw=@;N4EwgTt00+pcBqfw` z*@zB<@z&LI8$>mfRN`%Jc(``08^_!yB9m!4@)h)dhz1c`z?Wmo~2__=f1 zl3L2gej`6Z0`~;aB?j@~2<}+3*jTgT(8$KhOk|`IXBSV+WWK3&KOqKg6jmx~xb_)C zOq9PlDyKc=a^RBff!tJry_w6`Wj6Y1G{Re18<<$e-K!c_^N53(jPvOir^G zhrXoK8XaXP@?m|<7uV9grRWXvqV0e~u;#~!>-aG|JJeTkV%VN03qMpI5G2}<1m0Wo z`sCH_Qs0cq$>E#*Y;#vIx3!g&2wb75>d=g*g-P7Q4H(ky(FyY&vSFW`D){INJ{Ta%$&?4bu%xBc@ zT7MPGk-irCY8KbIj-_OmW%^Uah-I&5zhr&O{+Q9?C}DlQV~^ySyXwN8NgB9mN z69m65hlPhZTq<1oPq%$~6$8yKyJm{5I>7ou&s9B`C=q+4zs*n<{=TTyq>@J)m6|rh zuvF{@rHC9i6nV;M^O@ziiBQX%F4{B!&U7+-Y8{wJ@F)8$V>cZRLRBVuA=x1<$`yUR0evafowUGp2t=`N)%K= z7#aWlo||_)KXP+Q@sTr6#d8OV>Pt`$XmH`p08)bsM z6SG7h=;2Dfk(ezMb@IBHw1<4xvdgR}#RCQ|gdGow3kpAWWqg_-c=_C^P*5OZ4Ps+) zNqX70*7fmN&I(eXCWY>9m4|CyHtb4ree5r#-Pk7!R3o4zMA~=l_^J3Ogm#wr1iG3^ zV(EKhjhRy6)Tk}xiqpHQG9AQrdG6VP#6CU;&(hB(mUk;bxME)1C{$2;;0Uw;9a9|; z4@KHwg$pbGyQK-=Nf1U2hk8ThbJ4Q^RcP@=p!Vy|5dlvhrYW&4n$xX5-VE&Kajf zIEGuOWv7@mst;?ozEe=hfPxDKs)wRLgkm(NqTJ zkv?3aQ;M`6(NL^mGv3Py%3y9b>|-)1tDUgaQM}vl+=Fm^>|3_DTh(lZH1*t=D@si3 zS2@G?9FtbbS?!auOr$;zh9=0`DB*@{1SnZ`qdT(UdXX66H!yowF;m?8fQKBB$NExr zagqTpFDAMFXFVv2-SR^~??aHg3#q>LnnI<%Un|8PPAGy38l;~zy-fSt!`{06pVQJF z;l3%SZ>q5~Kb+GY%z|q-MwMm7JI~bKT=eQ@foWd6VV7q`aPnrUYNQ=T$)tA4hNG=nYjUmU%mE4}H9{vQsnQ4-C2Upz9 zee1pVtc{j0572@cZJiK!60j9&V~= z;K*183=S=oT`TE+9RpK>bj5TYTjQk;Mfar8R4^Ri8+;vpA1H5+n;P$&uM_4B3+Fhu z+gX2wZTh^1fsZ@cqgm%w^muPpd)f!Da#A2nROdoQjMWy!MPTuD6PsgS&#_vsI-X_k zPwLE^iaOW}q$FUlyB}1&2Jeyv=eC)yxPV_oTYTbnMsBJGNb(#om7kz8@XZ8Z5ZR#8 z#rjN>S5@Iq3j3sq5q6M$*ZVby*+SdsueHQe3u~Hv2LJQtH7<)7=CR_TxuJ3a+_C1( zxsgA#r9jT^?@~dP1e|1&iAhzht5nTYpqgf*+ySXGc_V|#*zSG2Nkp*&c(&cnKs@!I z@iis6uIN6Vna>M(yrxkwEa#ns}Hzzr_S#FG2;1n;TDq2D8QC?4?n#@Tm?B(ZO!lHRF#?(!)d;5L0j{U-`x1n;uP>~u^a8kHeqe`NY zLb(b_NtmWoffTWYo@UC@7PmaN)O1^Z_AsY$WiG+FXIL`U=%4snxMBS|avGG)- zU-{szGMB75cj}4zPbEmjCL^ilVab@v;zhk8bL=xwwky< zSvcOsq5d%*E;@cs7{l=CN_?5(mzvti^azhtI{_YveMORzh1|1?51m8DDQn7$lqYMP z0m~M-D=$kqS1TaWmva>#YV*}NU;^0?&JV-2S4aG+l_BU>B5k2S8l2?0*Nz~#czI%- zS6%epui#(-s50*F>%sA#lm>%Gx9=S~q)n1heTVy9yXq4snuVC>9{u%K=wG*QX__o? zt#_RGAKbhVpen??CkPXL!3=Al5tf??9pbI9ur8n&>7Db&t%NP~aVQ8)N^80RsuanE zA#dfjJ7{0HaUlN|%CdG#u%dR&v?d%QbN|b*1G>rwFrPYRmsXLhb(ToZL_o8_znDR_IFuHDQ@>HPK*yr5$*I)brkrmE~J;*Zz zRiDbi7>h{Dgr{7QewbGeVmN=lze?-1u36A%k-?HOWYliA#!Cqz!t~&3X@V7aYne&& z*rk5b1zrbgp#sjZt+R8eF35rZam|uN)dzj7!~I=yI%3%Az`TVHU{=^e!}}TxdA_#V zC(a3BxoK!NK=ybcn|7@wiR+UxZ@Z)9Rdn19YRHiALsF)7ko0gh-f1Xi4RGeG{Gs&o zJ7J>~wU7W3GE7xiZZQbkk#cEj6y4)|FrMMi+O~#)^1e^Z zi1@*?FK@iK4HuZjrLCW$aBE+@E4*IgG)+V4MaW(ExO#H8I@6t%{OzB6MwP7>AXUTp zk9*Swy3)hLgT=ItW>eI^ZT>jLc*KGPyHl%hmWE9my`4XJ+ z-UMY8-`VokThL8F(0*;Mjh7$Zh@(_muiVIs-Ov@YRZ<87L?M%q+f&2tsz!{+y|mPw@evgzo48WiuV0u(Oxcj*@?8q-d6u-Js6zww7f)S zQ4sd_=+CcQ!3z(h+*2l|{V}{lXrzwx>--y`Q?dvxh6f_|zLs&8n!P3kqAegQ;lt0i zc&!D?%OvGz@cw965=k|$yetUGQY0C{rJHtSuW9Yu4+9% zMET;r?bn}c?PvRRn1l|v4n`AN`c9qwqY0h^g>MO9jp{4)?YCYlx5oF>EoG92{74mq ze_q3~(gY58%{DDk=;yGvdthG*9di^vRVz5c|6=y4+(Zz>;s!Qnkc7w*lGi2PDVr0` zrc)i|l7TW#QKa6Kv?hTKx}}=YJAtj?K;`>pGt5d>ol7h2#YezSEwc88 zWH}4fmqZcL0Kp7vZtsaTlj^@qbo_Aj)99Eab)h}b4d$7YuGwy5)Uzquu90e0YMUj0 z#bYe~i<_{?LbN#aumK{}8@K5KeKq}%y+k));CcHK*92uRijb*vR%v~)pGdF^kdb5!td2JW61fQj<23Xvb=g zv}aSPqo^)xw{mb-!bVvSMO5E1qs2&y$s*hES*}`wRP0SUY&-|Ib12s%hft-g*Tx3L zpKgW)dh6GhKh3mxCcRqrPau^2ey84n#*9v{!sGeq!9Hf3f zbqOH-EY?Fou;XtUV>$+O<%4s;#+ZCn@^+cOdC7a-abtm@t?n=NbIB>6`nC!DL80fs zIC&=^Fjw=p%faIZ(Iw>31ka&QUZU9*P;G1}X z>ipIJ{b;*gN4y;4%g7DEFYjE%zPG+FG?HEKC>??8ASvdS zZfI@GKm`*2|NhQfeJcwNbG;Ravj`)q`7e!&0Ju1RZ*_b7#-AuobQ>V>ScF;TtyY1h zsRQ+NzzcyptPxlLu+h=agoqfxjO)#>G_kbAyZ}}LW`_Nr$0G4LRva+B6(B>3(%K_F zZ?&Tz0ql&v%Ex5<#}QDB7f>ntby5rGm|=T-!CXQBz^NV>8o>OA*rEms-koFM9&Egq z(NOMQea9cXpL+|qlWN|T{bj-EKiB91T#1XOtx!|f#y?aRh0?<9^K!B5PedbL7}$T+ z3qD~N`scXYqB#qgj{|#p)JrlvS~vUeb@QlyRQq!!dJN}|7X9m3LVtZnZzQ{W-ye7P z?0@%g4RG+TeyjXMQg?h{1T~wstYG?+PTET_$eNMsfBD`M|c;G);Fvz z8NL(gFiB_xip^H{vn#sC1X?KWV`;3OC(?N0a2E2{Ql}<*!lt}kMmGxpG(<*TN0Mzx zQKw`dg7AZ=3_i9T-SK{J%!MrJ82uEW;Tzm%_Gl&1##Pa+`}v1s-ElaC)KO4*b>^do z3TAnCz|=d4m+umHls7-u5f8rDQv5h(Nl{OPbkLwUa$1_ya~_@!dslOf_@;Cc{z7&S z1_H#(7kOjomCde5TUHb}Zf(+4znev!&sg-@j;r&Mb+!UVUb>>2yTjf)BdOLU&Nf(b ztRqsr1Hrc2pMciHKS|Wd5V!;Z6YE^h zpu#qh5Nm8%jNc~*LR>ihAqZcXs6N4$JD zx)$LlFUswJL|}NWEqPzp+8@YlIU&H#zVag-A1RKPehHrG%eqW!&$}Dnlr)&PWyrw4 z#Nj=l{1lWlaeHRFBMq)&ZpAl+Go3b z{m_<~m$;t=#iQE;)8Zgw7AP(Xi@0+CQDeL z@JeIE`@+%LJ*DRhP;BANuAD>H4D@oPlH z0dJgC_!fyo)Xv~>pe@y-%6XE!H-unqTTS#P$V{q{>2QZH8tV63tfrqpC>W2CMEoK4 zXnT@eZeK_H3`;OSk_`jN(Cv1ksiD~SV4{!eq<~ye`F5I};3UqrTmU&vkrCx~LlRu< zy&&&^EFt)CX##)*rLp7FkOz>Qgijt&$=xP&4-G*;bX7Xv$VrIl;n`R0;CDgFC#8+g z1i-*sXoK#@@b+rFOZ04;YJ1!#OO=l1S~~-P1YVH|3kU-;?-HimjL+5H0|HKj;CGSg ze9xvzU>gC*j9J_(T&mr0s5&24hBSa1Dv>%|1R*Uw+tGBaGNjS<^pOHNseJ0|2anj% z_!L}0Plqrh1og-qTh|Q3o+|$!$rGgLCfQ4~ySCMYHX8<98}u~_7IGGdJdP;xtxV_j zz>#mpPk2gZk5}Ww;-qL~UQ5x$0l`2tv4aA^@J``?KrP$uz$4_#G!4^g$uYQ%29mLOT*r80%5b}`nF-tL{WE3g?v*el?!FZ=0@wrHx5R>4JN2AL&Qg zez8CnyG5OnQNDNHQzJzN2g<`?!+ZsjZy&SXg<|WrmP6$hz9x~W99`N0zDxaM*U5kjwJV;6VW^wE{Wl!QUnun#m?n1}Vr+@_N*|;R~GigJR+Z2|! zZ-(BaRMrw-MGr`?QgT0lqOH#)Qu|YY7OHXs%U04IFhU^I_k-6A>cq@cJs}ZT$g}MW z!&kV$)u(K7#m74QAlW@M{7kz?qqikr$1h6+`||4I$Jj6hBgZ&gDgY%ZeEi_??R8CK zs`pf**8QG=A!Vx`W2|K#k#Dh&od^2!nv@qpQoh+KJ58XNZ{(-&xJ&J_U8CTF*vP!bc$LY``b?evB!ng+*sWo z(=Xt0C|)-+awvQFec<&<%yRE&Z%fWtZg0!gzP^y3g~oGT+qZmXAJ2~8cQc$Fe>GdN zyPc$DmrVj>8q#@t!B_4V=k2OA2?GK5*wqt^LMM0*_eAv;)r>^$nDcF+6KnDNzkdG! z$b2u9#|!vae$rt&&$~LVA(Zt@)P>ya(01YX3klX-K)q(0flc2y{OgBuWe9gX-ovUP zeOt%=VvAr<&{B|Eh?~)D!$LbuMiB2c?=;4j61MNZv01ylx$pJsKW}pcwVcz3-Js;X0*H}Q| zve))gOMwP>X(K&IUxm6Ij9CizgH9Rbj&4H+NB0jSd=j$D>eeFOr$vKkztrM}!xNQC zgu+9pLW$$BM6QL__W`23es&2^?+-q&kzHB=1bV13`3J+9<77#o=OV)ImwQeMK@*anLtQ zRt=H7_Q)-&997mGb?A*4u-@K99*(s(HY+=e#r^Zn;A68+be+y3yktgKr8gls33ji0 znNG>N&e7%k?)l*3K#-U+?x?Ad(@@VZbvOS|Jc%Q96ieZQy13pm2gBpa-0;~=k~~Nc z7aC!8!S9e%U*6a83g<^%D{stFM%RCDOM?ZTw{EU`EZtFkiFXC(M?;`q4_||wn8nE< zs5oI@`=uq*xaYwF8XXf}wm`;d`Sp0U0P|~r-#wEuF+|%(dsyWpT#cguNbybvCr zq9EuUS!|%&C?FJcWya!YGdP%Zg;nLr-Z}CD!=)6Lsy(p@``uc%xHhg=tV?U6-ibDgZ540KssOiH1?P} z^bw6An%Uzo@FsZ>SI9`;;F^g{OcDfEdIq4k?ng_QTIY{g*_K-9w4e8ep9iTfc*76E z-MxtzSed3MZrEkwI$(T>O~Fu?H{cN%RyP_g_rlh#Zqw;I3{EYrLbAr=6{*{c5LFF| zyTJ&a7X>}p0mMP8y+; z#4+7Tu99Py+DRAmDo2Pj0b8<^n6l%HSI-rxP7wHh)14XHdr!~lQQpa(?5Nqcz&`E{ zN1BrzmM3a$Om&VnIq-M{26hE9jeO}qL&ABHzdzIz)n5astNX-XUm0OWLc>k6D@#xoE5AnCqD>I2a}+Nq3L z+N3HxO~v*go0a;CE;C*o387#u01C3hDzNWjce4c!tXo7K%|e+cQ$Zixe`%0G@IOl* z*B_7d&*GqT#Fi{Jv&8GWh1$YSDZ-z{ZLC4Q&>%jccFoK4rsb$_p*VO6x@IjI?k#Xi zh8S0ok1|~iIFN;_MC_M%`6@w5_Msk-fb-UgwYdFk0c8L4!;-YI){MGx)?zLs(lv1O z8;6;KU@<{A0E*>_%eBHEi{G3q6)OepTeox**@Rl01gs6>#Y3Q$-PX@vBV8da4tU<0 zycUCdl4H~n-ijqw#PJkSTO8t-P*hGK)^T(^{#ZGl@v4W5J6=AXHaB1I{T^QZ*ir@U zHPvu;)Ni4~>r__3sGk%#sh4Zg708Pc4-p^`7szUGpO~R|azJvGQqwRq9^$Xu8^<0ra?+i@ zdZ_5$Q!Nhw@Q)?`a2O_ot0gGrxxXPjTe5b#CEg{fr;DS}z)U+SwP>bx$ zS^e55#aJFpd>>1DvT&rTsYfP6KwJsEWPfQed6VFjLSJ|=tH#^bMRPfbtQr=6BwZl> z&P5$%1e%@xdZd|$ucU&jx4EG-D1D^p9kn)Y%#s|;JCacWvotF{Tj0*a{TuJt(4}x! zV)+hB`1W5s3wGm=(^hTiiK`{yAsqqgDrP9t6n3hghrO3-#;|`xV0>-a>m-l4YH#Vc z1}@|a?u%psG5QtGx0$3o60=s$@(ByWnz78bs#7@PHx~lrQ3;1ts?uyh(X(}aXzo45 z4&Oe9+1R0ybvrfba#W%N%_8YV5*o9)4q*!-F5|w&NWo7es=>(@URLq;@xUEaAY)!a zfMd4pG+{~7soE9aTgKbZ;-hMu^2K;BdJn2(gvh(>2@d#HaLZ>F2ZCF7`D*Vtxlj96pB( za;|F+gncQcPTK~W3wGFz^A!lp;w{EV)d4{@c9vwUd`H}o!p6elV|v2m5Z)+P>enpx zPw8X4&USGh8|da*I6@sYKeYKo1{hH~Rk@NdkVr#H zxh;~L)G0FMKRA@vn)4`l2cAek5~JBO=tu34I!!B zTB9$qwvBfR0T_zH-3c^!W4;2+vAX$tox(%;KFSD=*`)ppfvf5_AF;%QMk?5hv1Saf zob&h8M-LZDY~0GK+B~xD6qA;Jc*|xzu~PexSYiPUPAdPgA>Z`jZB>Zd(jb=?fyh;T z$!kirA$g?pDZy*=hjNJ%l&;qB@0XE{nRIN38_{$+E>FP*vy#xr918`!lHXGQ)RW_> z!)%ucOAgQPS<+Z{YUezXY(om`jO@!r~9-6V79} z`-s=Rh5f4KIQ#=TzBuT9A$0Rj()meNxKFO(uV)I!{|h7k1wt<-mU=TtO219iv-hz! zBK^vp4gtzYkCvea_5d2p^8hUsYgcE=&fI@d1teZ4{C>8}_4`W(IU}O7wt1d5`LZtM z_qB_w+#!KDB{;a=q1-`nzxVR@Z-lh){y@P~(QM!RO#g*q*{5^;!OzOg7%zgVSJNp% zTZY@q%rGXL_z{+|;qd1#`uaz85A^G`o*ww0lI_9nrfl&34w3aM1kazG zJ3=-qx4hc*T3Y&>qbsH6Hn)_;WnhfdV;t3neMsGVk!1P}m`ePRTxBn%lO&i$a_G%` z!w>3jrU1dF7aRALrq7YFex8FZz`PRsAD>^|wwWEAVytHi+G+=ypa1K12CQx=az9%V zsBV>LH-CHYjWEy{UxIX`eyV=<|7n;OgAnA1>*%CD1u=kXD0 zW_6`cl@^b(YBYV+ohAg#zWOPpak!Q=9cQzj|LsYa)RU4} zEv>uE&)<%>bn@E}(0d@-rC|#w-vuF#Sg$I?aDsvHV%!+t+|PNNg9WqcyePqcZzqd@ z5IPALuIz0s-R%zuoB#5zYZ4citPxlo0-TF1u*brRZCRgDuh)UA&%m#Iny6MWuE5K; zZ3gIH--bN=LIOJ2b(UK-J_JTJRXOx!7gmIP{jvwLjMCN?!xEJl)__8m`6kxHXRL0^ zCD8)l!n9xXZZH$da;^SG@a~r!k=DdzM8i5kVwx*w=a#|8LB3MAz$v~e1df?L!5$(8 zrhnEw%cie0|r(g6Vd5?&H5xnsec`iiKADpjJQya3) zVF(Un7Jc~gzE5#!|0X&q=pN?rX!^Ii-}h51+pty}!J?s)DWFQ15vy=p?TOeURyhbe zVN&?O?vC5)#%EhnLXkp(=EuQ|tD|8cZ(yDYkVl!X5andH*2N6Fn+g;}8_cswjOG;` zfDh($J8kZ6>KOh^Ki~ghwl^!|t3{=4*wJXD+dtdDhwj2J{uy77lnxa7;P)k?T{>v~ zZfCkW?M>fh&(go1D@6L=)5JkW&AAPQ4BQ?;QjeC>#Llb{9jn(6aA$?Zd0W<_VCLw~z%Z2jX&#jsS zEw>-ZL#Fv#Y`*hFug^~0c3Uv{xC?CLqRr3U;bbfG274Q~!>7*8W8L#TBXYx*K;i7h zTsE^_L+KqK1X%z^8AgVQbI-Gtb6(Q=K|bhNmrk1*H*B;9^1mB9mT+mb2bchuI}xnh2uPo52(VD@hsd(hm?+pbHc zH==&2?D-(W9nJ92qCU)5E2uwsy=f&#`opP8j|P>yD|RNY24~%!P|Vij2g^Rmdr_=> z@|QitU7EI=R`i$cH^y{Uq#yNVXYm_--Mes5kQxj1moC`W;IVpYB#ihcdztdUqckzp zYrRvHr@WR;%pyhLYI}xKA9tIItRCmDdIo@4Hl$OxW^Vgf&)Z0Bep&>2+iq><6*^>j znGT*jc9$i>H)yVLG_0sEb1*||RI^C;@af%VL9;WSS>BX?Vpi?l#%fa48@0epUP!avz5iDQ9H#**tu{BN;~H{|Xh zjq+~)OxpwoCyKiI@~Y%FHg2-RO}`BWoRPNn@o<);sMVB*V@RI$$Ng=>hb>O6Fy)Eb z4uQ%V{siTp3ZMGU`jrpVbUx#{Lt=M^g0vms)z$x`%v0U%;&<5=9HG0{8=NgGSSod z5t3G=>e1G2ZyWqw`t!8}nawn@3sOQ|T$QSPzZ9bAf7LT#%by=W-nZmZan5t%K(V$k zP+Gz?_QM>J|7x2b1(W>swvE=Gl;orV0U!hpg9@A07nhzztE&F_oa?^?a{Q|pGspzc z2(_FE_NN43{^_5P?gj*^QVG;PHsw_xl!x{;=jZ;`C;vrP!CVX|Sx%P7(&cE=bEQX` z?>}RNV-Ww9vz)?-4)57j&5P~(U6U3v5lWA%BfObyGB$N>vJ~kii&f98{5#E8o+{P2 z^2&-Q*s!;0pX zt_P<99dsM``gf+;^j|yZ)@e3Y=`t_Qa;8nrR@u}BI`+(UK@1P60=fD~jgAKF3%pU(P7^>9B1BwKM{~B|l3g&QbTF?Nggf{hORsGvj3a z>zrATQ}xyoV9?x&eG}b9+k7_R?zZG1|2|-|Z4-aVGC00w*AJ?jsrV1s*zv6sHmXJVvU|32qB~q$Tsv*Na{ek;L*?}cp(2JRr zB{^rmZs)7j--o}~b))k)IjyJ7fHmQ|xY<9I{(h};I)5rpFOD`mc%hV$%+GH0)ny8G z)jy}2NJ^Hc`urW3En-1$g2#mR|Lk|9_%HS3LZQW2VjA16YCB4!2am)m#K=brw%+lS z2r}um<6gB)@XtbLO#`A3174_ewdr$BhhQuFK6D+Y)M=%YIsKiSjTP(HbKEW&dmsx?c~gneqgyKw`t)s1JCh9cosoC#sNs>nipi-o zV6|8PvvF*`Q==j5P7RT-YV7u5QuQb6aJ|y}W72TJ1AaTzYLP`5^RnAJdZIEu^l5Qo zQ20@6*$>NqUUXdx4fcf3J9u_Tb$HNi6Uka%qZ>U`Ihpw0{O|l0sND;%!Da*nk=Lf1 z`^@t`Sq(B}F>-;2>$?zsOvbG(xdfmOS7m9wmmLVo{gX6g!jlE0KiygumSF7tbadw>!iIE#K5y&{zLC{@U#uk+C=M zsV@^h&!c%)2G*6jC)4|9Hb3V>8aE#H%71jPABaAmqA=Z4#g`>Qo{z47S0^<~H)+bl z4k7F#e?CodVg8w|_nl#f(jU7E2OibBN7K#BeS@t2nGz=hTMZHbygTI=G+?^zZjc}GA#3y|Ks zAsd=wxmlT6#hZz5C)qg^VnKgs_e6?L(>p0P49hfE$j-7Sy_WAqCdKWqMHS|G8R2uh zY*sf$y(jH1H6J}X&-o9BGjrq~FP0?GRD7oSniBYS8+S|}IUJN2*M}v)df&I<2 zR@i)wUY6j*hvs0}ELuAOSGzCx?hmm6%e5=QKRssOl)obTyl>`_YF@tiMFz*ZxGu?2 zy1)8+Z4Omq5Mdl$b>C8=-$+@<)2tJTUZI{51)GwFp$Ls9gC!=_oxya{^rHmI*Xg66 z9Tn=b%~?jldHq;YF)hKFf$G)=`r^gGH`97i^510?9)Hg~7nIZbPUWr?Lp%6Q)sXqF zdUAeL4P)m`p7&4sVapL=oqHBQSykZp)E>>Po*O>?Dd3t0b(+^4;a*?#nRi9c%q$-& z`E&B>m%Uw`MS1(rUSJ^Z@wU~}sq`DRy~5KDz~p5h`m{8@o%Ds+WkT>b#HYqk7lw4u z5Sa2dO)MBvVqt1&ztHu+v$oikFPG~jc^>R~#3mejEYgbl*6>oL4Mo5uXxW9Cb}!-{ z$58NxnP{pl_yPHLjZ!^=>?V-npL5xh)GAc}grx$?VO||#Y=?oGG$vntK-!f$kMD{U zegQ-z*H`E@cc9;9dk9ZPj9?MVVHqLN&$RYE! zl>VzygopPAAUe9BYUJWsC5)@CD{93Gv+xPO@|80KDipK3I~Y`mbPR5w(FLNs`ty0j zM&Kq_vt)WOc81!@)cqgeZgnHFv(2m7?Zv_xW^beVB={!9>A_3}HlljtQ^`4N z)W;N)phY0#L{)>igi7^wsZYHz?ADd3iM?vuu?bpwRBp*aeiQHra8+CR5PWT{K0!*# zX#8Qkj)4TaD%AesQaq8GrgFHSSPk*Pl(61Gm8`VB%4c8b)MtC-d+nH6oss_x13#3`&ibbTCLlMla3q&ZR%Rw2la;fWyFNEAv>8 zAl$9AEJk{=-XW&_U%^ozi|m}gxS|9vu+eTmdu01^dJC1y0=2s;HLEC*l6Q11JdOBr z%gJ3e;?3)4v*>ocJmFtbT>WXDKaMZ)l~6?F^)t=_D}Q^}tWae-PzIInMie$V1>zyx z=R9f)2{TUom64y41T(VLkjQf5&nsfC@w12YB8lboe4+UVM<&VgI^*>pq9O7o_>q=L z8W}Qa9D8kydCE^(b|E#j3+(U-| zGK5WzUm1*poeDFx#YxQ?L6hsGvQ>s*&xHOdBh!&Pz-%H93I3KgAcds>Mqh@e{_b-U z54HrGf|7I=)TNH!KmEV6`jlMkd`hpk(1Tvo60kyIju$KbY3{eY42vSYpi_)O)t4<& zJSCynt&O+D&8-xxfo3$+)H5d2?L(A9r~`5T%8nbON>`mo+*AG7JMHBsxUH5xZhg{o zyARY>nNL)+Pl$~BSxC07czBZU$92=9cvrN=1N(qvE_e! zAU>(3B%#eDZu8`oYKNKV4uWwIG61UJK82@M*r}HIc|yUK`g$1DOFZeJ1Vm-knrFTS zV6`Uz^6)D2mupL5@zT;ncOe~uh6oe2!Kg9iMYxe}Va-8kTmJbsERALpiHG3PzrP#5 z2wT7B0|oK8Wxx{=Gm&LsW8lYAoXNGyhUqvdkRppMO=K1d&3c!dP=st#26u&0tHHh| zAnFytC>i!2DJ|-g+ENy_eaL1-RbW_3J(3)N81`k?lLX1L`*tM4@A*E5YI)`3cnYK8 zFOm=q>1X%JK#J^mfT_VqBE)PoxIfiLy=4fn9Hw)2Icba$yH2k;dp&K+(9iW z$#d$H2m_BkIZobIy$nTiJ*4w<#-i#E-3+%jc<6bFzH%ToZrk-nw z=}4(1`E?d={r?SPRkX7Pb1^kz{y4qE4hoG0qFzSwS7W*jx?V~_*>oQtq7Z3Gu2bBL zBm$y-^O~&ACJIZNPzE$CMRrX{|HV1=O0+~8Xxo_l@BDH!9e=VKNX{TaPz&~_;>>&a z6`S!+bA#;&o-M6-E*K!~zxG-@2DR)CV{gG+LDd3IaXEE1QB*G$Rzps!(f!glLTm5u zKt5)}>H$H0c9nW{cthGtA*UQ2bh<{X{r1Zpg6aS~iGI57$$eey+g5sx><6`##pvpJ zUK@$`grEnOaRE1?!2XqYhNI6nl9EW;9C^FjXPB0<2XPHOw~&-c>cA41W+E!zBjv-6 zV-ac#I~7vhgjzVT`KZ8uO?iAAqhpNd#qlvyX_Daa#wjpSfehaC=ZS|us5wiU;B)im z)}sMBRK7)cl~P8Zpda6*7!EKFk`o}G=&=+ynCc5J6K=dpDNNiZr69SWS74>o)x-Cp z{K8j*)I9gAYf}$HW*j9B;Xo(gLjj79+kq$Q z=}Ax9K*0#krB7Kuf(xC*kF=!s-Kz2H6&`7&?O2y5W?6X|_VEh~0PYUh!+S1mj@&5XfX zKPXwoW%$U;hFAmBV%J*~uYdA3ePL9a)@lh?s2E8CUe_h}zF)aH_k5VX<2J}FD6D~* z(6F!R(Bu+u*asIKM}q#C>JCAgvs7h|HD=`5L>W-!W7c?(kebiVQbzbOTgc%5o^SuK z$*cVK!haEszB3!)yWeCX&hnvdRUctwx1|=(bDY~V!oN9Q##0fGEX=o$FkckAx)-SQ z(h0#$3&MR-V-Sa_pOLu7X`5%$3TI+>ceQ`M{R=O;9{TkIjhl$t=FW0jj3ZsP#alf2 zv}^pHmdjxYujUsGjJ;A;`|wqiEGJWuC%I5n@}9^oEpuFF-V_(iMM{fwq30FY8}cewPJ(;rg&mcRBN8fK?xFz7VP` zu}r9!UPva7PHCZ$^c4A_4(HQN+fISjfXEzmzi6wwvK7hevkf7qkc>6gw(5u(!g*(e z_B{K=BpeJ^AOU7|-~p@bu1|R+hxYD0+C4_|Ps!S)f#EQSnl3#)3tT(B7s>7>LrKE` zkPi@2xn~v2R|FYWVMkWEan`{sV(T{D(xLbq><=14L}63YG@Id&QoZ-RExDTpZ$UB1`z6qPdsy#gNMzRSmN zL@&+TE(Bak*XyT+pZxcP)PzHCR{lND3Ls6?6pY-v6p}d+51U)A`!)9-uf}1ZXDBYr z<;pS4_(;&pDz|?nsZMA2WjH^W?pp}v!TAtElW7!&tGyB(PLsO!zLj6+VeQ$H`B!TD zRMAJLyR=>FXh$E%a_WHrkzc}wCo(#}#8-cXyPiPZvL%|AgTPVt0)_^3TaXwZFI zM`!lMmiR8;%*WQ`m$v&0h#2E50({6J^T`gaj`qZ$BQHyg`10G#LbAZ9ebyQda;(Fy z5tElkak9RC)CcI~arKm9yh?Vs-%GuLvap0ZqpNB1H5lR5*TLO>zMFKkvbb7&?rj1n zjyzEc9hM-9<(R%C^#cnQ-NvzMqy$O4-~WuO=S*<>nZQ)M1hmkb;^{W1E^{V(K*hjs zoH3YMm^5@3+#c;*12zIjw8gKQ& zy3$;2CVY;fG;#_(JK-U0{#b+pm9GRR+#`{g$+r)OG!oQ84)O&RlBpP$6%bCi#StU; z{JubH>VLi0$ryjCih1N zUrT=;et(M|(CI9C0!Wey`g2kkG6vbj=&F?+o-;`8fv^DQ!0TV;P0$YdPfMz@McQg)LX)MkYLU}?8V(H6B$geJEs zs_>AIv2nAin4WGKg@yPRxVVfit2MF!idva|TSM)hcPh6SCwT#R_5*==aJG^>VfLH+ zDIz3RIUA7Q7YdLAyKL=jnDvTECF)%X&JPv)!%$P}uQ018d>CCd&Dk0jem>MIZhs0- zd3r|O5ZpH5tYAB(yb<-s&~_X1fF(9jsl%W8j#fN|8buZ#*GU&6A4ky$#hATxWf~%;4E@ zc!C_Jcr2ubex~)yj~df=!h`&;;5oBIYm3!CR&o9%r!I-v%#tGsJ9QJA z3Ex&gY>x92MZ8#yiB4{KbyD`Bb5&dP@8yNh{dSeliaAU7_1gl|BjE+>)pzQ)H0s{F zrl^BABQ)vK=B}h>J&Ytr?Kq}6jifr5FYWkeP~C(BSmS}6+R8JElNwLp<+vIpX8PX1 zWcxJkyJS@t`>52ZCfxeXoBctJ zc-2cLN!y*nFWVT)pyvm#TAdbVG*3!7e5am4lt#e})iM)`;OhEwI39#MV=VwnK}B<5 z$RfCi%vu|i0JK{e;#M+?7y7xEHISnnqvz@%+wEu@<6u^?LTm~O z9XrbPcS=vWn1GQ`c?bXzs72+gm21gPQ`k!;Ur_)onEGo=YB%Yb=)m+%#wNFYLZfO4 zSk_d!Q3k=>(U3Zyx_EvUCvHy%U`1mib9$442I|6$M!`bCSDx_7Fql%+_W9m|{XfSB zWiaO2qmLCG7kF}HEXc=^8hsqvb#T%W=Xsd5%YpbmuKc&1j>o?OPM>>_O7C_(BZEJc z(c;~&iBAS?=(9%xjsu?xG)P1PTZvzZhed>H%w_x2d=n8lYd;k+y?urY(X|UN0@HQ@ zTD4qI#yG9p;984Xv7;kx^L-v%QJ;TQ*mn-S1Hk};99!A%D=>$pdi+s`%kKn6XLw2? zp;3Pc1bJ?l^)fTnyy;1qK>UK^t}i*R!V^Cye2j2(inve0;NaUeDJ=VBWY@DgfDY{( zO(P+t$j2&dZ5Dp!uM8;iZn(+WrIvt%mH+;GP9jzg89=ZCMG}itLg6tg5~5(Sh33}( zahK?km^SdEe@rCDD;;_svExWjcj$y_n$f&^uU>T;oa!#q5}9Xc1xn?^`&Nil)Eh4( zQ$`!G!|GGzKi*?spY#o3Ge~ga`L<#yZJj*-oOVRBxEmHH*}6 zn(=<>y3Zi79`t1espGoQ?DjABrH1=BxbZn0g`)wwcFlRjx>z~b8YQ;Nins$Ta8!@zrBrx)L=vyzw-lS>=~(m+<6--F^Z$dg({+1!r_Gz=yUWDwokZhz zpK1phaJbr%!Vm%{;T8JgqV0CIVqfTj^EB|5C9w{fy^chptc|aG+QFy&01;e>yASb= z>i(ApsyUI$Zn1y;L__oU8z3*8b}Pa*gV}W(`==|N0oY2@>Ax^^DFMb2P`}72*q=)O zckK-ktx(w6wXmZ0%Qa2@yC+5Fuc{n-VDq`rrH=X}@?xbPz0+yTD32|z(u$%kM&E`n zUGPO)4U>T+JMsGSsGCl89PR#ZiuGhA7rkWo*l?UgMfzsOBwgWH%=)3rP*Ms-tXPAI zd@`lmR)?BoXbL195^*J`9YcrCC*vvj%D_7)K$$2mAVj=B6fd`1VlAnz21fn<5z=rA zk7uLuMGfegL}HW6(uHd* z?2N}>7_0f1q$h4<7!xPlMAPL~DT~fw@9YK@$?~A*kt-s8|4Q4&^vraNQUApgj6)T- z*r_>97`_$r`!KSgJLH3*AU`zy!9kl-gW@mGn=Zy?=;StTydHJ`|LGVN*5fz1XJ({a z48YoFlC9yWzA7xPs>OJU+2ZwWC0x{e!SkG8N4yAX>AC7;Ocf&-n76K-;U)(oB%&;d zu77uW4b^(g!{;;(>}sDJ9i8-SY)|11(SlF)!<4urB2%M$+WZ@y^s^k0(2{(j6TV$r z=aBT_VZ~P-n1+=}1Q#5)f3{x@fBodFNp$5yPk1~7M;!@+q$J*%m(1r948hm<#(?-_ z`_oz#C!UA56f0fcSo+(5_twhcC4(aIUg~JG3}2WwH%|<~ytsO<95RxFwK7%m=#A?I1t1L15)UVXqcPY_ay2 zxYE@4zXzh6c%_Qbe+>C43coP0;5Ve>mo9aZ;@x>hc|kebFd? zjkWb1cb~~Zp-mi(S|4*G6VkF^cprLM8>USxKh|7TtrgPNUhM$*$&`Irn6$#f7@a8J zYj^fGk*p_ThJ|9nI#ab2ddRQQpdXJb8o2fpTl$hd?)6T598CVbZ&Og`yut`_*6wp@7hft-XVl2DpXHF_;K%)DYzVLcg>72f6u! z=fG<`mGC@~n9UdZ5p%cB--@45d6p8&zR`}7Nnca!m!vko32JMlW@!Pt=7$&0d&5`3 z%Wu=dQ(OuPUrS;o0}P>Uh#5hVmGNRJ@$xkrrXqByqzJx><Sc z3{*XpV#sX7;UvH7+v7ihLADT7KCrLDo zwei=FpFs+6Q~yWYyzS2~$+_t-h!-VTEyW5gjO!k*1H^GceJsrdj204N39CUaXO15c zE_7J=%p{p!l&u%WVRwy+qQ8Iex->b1QY%qCJgrESF(%B_j@ExqcT(%#B{oF8wuSg2L zJp5r%gH}fiB*DaVETKNaj5dc>*uH{jTWjoAXUPw*IljKs8Bgkpx^~?@$FO2eZR$7} zISCdNHKTxsS%t-*V~|`b=5Bf?k5F=JMgF-Sct?hzi=;lbHMJ z|W7sr5 z{73%;qj5o>*c%^Vwr)kgrrGX<=VpbUd>Q)4fr(P0j_9{j%gn7I%de`*fw<}8`pmFr zF6ItUw=cLoH1fd?x?c!Zb7aWHQ~-tBwzWqO3hy+&8P%s9%Qb4WC*XV}UsDkaThqrw;QSS4jKId`Suz$l-Z0K@=P#G|1^^0* z`oSapP+8jRk_ym1qRiT>?v`)tTnp73VfmAYzYi>AD9Xjo&r(U$1;)YLqMjZd)J*|% zl}ibKMJBfcU+xFe>rQ{@=EK@2F$Horw~V5E7Jd)6rr*|16+?*_5> zb}j6W{+)Yq)%SPq-D@mxCIQ5;1taAxcmiu8-fNktok#s4xYD#ZC&4W<^_N!WDd+LZ zgYZ*@4Va3OB{%ob?W?6^%}0sZ<;&8&I3j9PIu8hCwWY}%`(tu*YdV`S*jPvJ0ZtP( zI6~PHNU?%|9LcB_BK$*Z6It<8^7lqpRNHrRJ+8d9A~5MM6(8#%y3%G}G99rD66==* zA|H~)cCs{wmC7T7KX@k(%tfdM)x=S;48 zxyhla`I;U`I+N44R|4$cZKP{$3nds(aq6VboVYNPQml%8G;S)gexf@W21m<+(H7|# z+FJfu4yQVX*s-t;MY2kgs_y4$8%0{3!R4t2IM}@_EoK#l=Z3d!q8^RYZ;^o#r^cU# zwK1|;POlEa^#aBIb04{B-(ZxJPu7jgf(@`Jutv(<4CP94MK)7i$NWs#DzLVs;z)vX zSII_eVt?`ZB>L^UWvX5|OHMBPqq55+>_u*d0Yy-W2OT`*fmfPC@a@DW_kv>|&-y1d zah@5Nq+29!%p}vXppts@vGgfv;9C!e79xNq+%}JK+UNF50^&co>uEwVq7k4&5DCGE z#v)bWMi*Yb?JMV8r0h4zmgC3y2)NJJvDzK!)@+Q*{om7}OYZ2UVA&}s7TvJYN}MZ! zFY)hbQ}gV%@#bfo`ma$OO%#h#ck3s!gx0y7K4Ec;4ST|Xn-`|bPlN71Jbb*Iv-5`- zw_y*ZNrY~DVLVFFX`4BgUOMOikbWcJrUotd;YOI+3EopR6!MDZI2577nsfQ9-`q&e zhglHE$-kUrSvW@eq38a^@(Y!jwYSb+HJB(W_&M>neL*M{fcU{cL!dBUF#M5&Ldd3_+L?3wl@ z-)HA6t=vMQ4d^EjeCWmXXP`i60g?JC*ls}?5Ip#ljYRr9YVbRZN7an^eJjDn4ug2t zaWz9T4;|dj`h8N!5|CBM;?vHyWBs8eV2=Bg{8m&i2@C(iQ-7r*8p}TipK9YFn-Z7^ zV;&fKxpCiUQj$9)D#+xNnXKgX$0;Lxcy7IJK&J9-ts3-aX5`sIsVT3SsMeIFhhmZ$ zkd}>7POP(>cjLD|Y`d}@sr#xF+@)jA=Dft|XN-}O)v08=KU&}+&C^NY=&p>zlJhqT zGQ6JSs)jE(YhkLTjL`+fXzVucq^F!Rnu_fyic0HjR|OGZT_at*N+Jbcke`3#7IM$A zh(>-)PcKji%f6$KqN-q5Y19ymf@F+j?jZdEY^(rzGi+#4S{hcT+@v=QYs_GQ?TtvDHHDaRgkI8AWD{4#5(h=a_WT@^6e@KYG{wY zhn>+HWbO484fMn?WnDP@nLabhl33_#bhN(XcV#FqtlhgG^k%1OznJ(h85*(|2^I^6 zn!*33}g zMnF5{9G}&)^O0EmuAwwB;!V_tFVZgV6=BKtgiGy<#KZ#F|9+|YI7nczoD%swC1en~ zV+UN*^~v_Tv|YCMpWQ!zO@ciEJ+3(M{BW_etESaLK`}yP zdNlW_@i?lFcg6H~unN}uz1(O0hR}%WQ)%cfFvE_@#jEsb&_890_ZQ>zBPvsy@61@G z+L1inZ*n>C&gXuDv_Gd2=ojO$4e>}p%}DraGCTgjv9%#~JftqH@q-maUs}6AbxknW z@(qBAkkscZh-T41&n8CFY)eWTj)m~=S<9uvF}s!qDINLfZ}l)b&Kels(Ly67w|HoQ zl3AePNfgcE-fx06>n8xNl!I|dG?Ut94e{w|w>Zv7z%nP3BDu5gyi)C$C?M&eXa)u3<$3bjnQieQUVvs#UO%D}6a3d>IC`r~dpa266b9ear#B z8ZowrXLU#8Bsx!k)uq18R($W+!k|T_SnZmrjlHTbiUQQ+gA=E|ToOA!8qtuR`jQPW zhnvB`H81z`j0H*^XR66`rcw;?AbL)(0a^_Lzt6E#C$BJ=$JhG3YX~Z zc_HDD5p+;iqByZ})=&5KW9m>p{nGOC*@Oa@E(e9^!{y|!i;FrvLjTwfH5SJI2w;OqX zU8(Nm^S07>*TGX%_yxapZu(!5$%s(C(1^2@RRLzIWsYA%Wd9d~olJ_`f5wL;+} zua@xM#=`|$5#NR{h}-U4*J=3hYPuwwZs~$mez0!vaGG2Hd6{Lff!dFx>pEK}^D!Cl zMjdtZqXPOubgXtC`G@=avaN6Q5$V)+KgQ&>u+bCVYe)N%SskLmG`QCrWUF|U7t0~T zi|XsIv!i1s1X8Bs8A`qodU|^LJPZ=QzuDKlzuXa|Qn+Cd7^8W76mOr?bw1aNf8n~L zu3&7!7IBHxHgWa6vc#_>HZJ4>qBL!b$h7qGFcyb4YjRV#2^&^L)f;5miy7*OO^lY( zkuR>S$t;&-Ix7GGzMc#GPceDA#(I0R!zr+XCJUQuIaUm0C&kV9cYwj0xC> zFtLFO9*iDkT3!W6t|I$vBV+^6*&Lo?UBoaQiFioOcp%0RNTrFLs%>CfgbV|Y!yrQG zmJIcO>H!Kuoe9k3>fvu~5mdfI7?#)rAUPq2Cu9UDgH!2ZK8`IUd_M3T6uTq6^7k4i zbz*iX>m#7OC`IPw6>i1O*k!GeAM<6v0g^}g52t3z_x+7l(|)T-mhenft%Pm~OW2BQ z@Y}+ea#o9+{T9u#A~Jm`lk7bXYt7F<@-!a9R z|5kc)|J_>$VB(bl%f(8WzuQVmSPTpeNk~Y7N5$`+OZ@)!;`co!tQYm4z~7gDfA@3$ z;&=YNs#!li9{v|D#?K#S{P#S~#?f*60uzLTdU-YWHHU{0?~^q#p%=g1BJF5H zqXC$hn)6w>#Qo#9PD>x6qX{~R02b$0|D1RGD2(fgBaCq_9};?#(niA})#LyjbW;my zuw}F}+=fQfXA1siK-C#?;9a!Lg&_c=L6mAIa_90!ED5AK;Y4i1o4eAdRR6mWJ?{`F zhxT5rwZ^xHvb=3(fK=f;4!)Y((8jaAQ5S5U?wYP3Gm?CQ7n9L@{R2O=cf`zjf9`xM`Iq03xabLrdbRc+XX-o{%Ra3A2{~8oE|&dml$Ot0;vEUuMwEF0f0L&> z7HIpfb{dTL_pd(*?dMOwBOXeJD`ls@y$4!&(hC>Rwil58zEyEri_bOaicFNA%O#F_ zcikU|VkxS584N7|JZ*N&K$xUYB9gi$NVItf@GEKFpTM4-N%|>1a`VL2MnK6abhPuM z2sjQcfi-yJz1e;yYWR7?I^pPK&0w+uCKQIgc)}<)&%Z$5ojk~~ue(nw^g`{qMr1k> z8kMw7hEHGhYN9&+j3E*#6;+r@c`N7_>hG9AaZ8EU&2I*O0hLN;IOC(sb2?OXQQNj^ zj=^&^j3)kLahk}H;%HneA9|;^*pwK6CP#c_LMb+}@x;KNmjRK38t$7|YKeeYY2C;@ zcKO{W1Tj+-W^H9JHL8wY+>cQG^w18;a8YSYarfn)G3Zv6^{oS;1Ov;vHh6j*PpWu zjS#Z8m%(htFA^s)hTga<)qfl~cBMi2@j&g6^SGG$&7V4NM^vc4_wBzo5aW(HWRY{- zyi_xg;El7#R?4O7;cq-S`1y!aiROFQfK!{W?5xyov9;9c;{g~{JKfJC@NqDR{;b|{ zQ6Tiwr;YZTmCYfT$-{2YUlv(e**AiM5&QeLoJBAbvAd(XxjJi1!fx$}L9176bk)P% z&F1ZHuAH>=6HcSH2uxme9n+n9F_|n+oSBhqkuywxy7>3a9!FbK^QE7^zw5yiTieBm zh=Iwt=jGLvuHnr;FIEN+7t>yPVpC$8*v*o=0q{TJJOk?Sn?fbT`1xtjzdP-I|DAM< zg?JeAN?l@ldHLImHqKAaJ9x5)sKf$~BVl5S>0lJx5z zj;{yv-EC?lQ}t7R0%qUgbNB}Re?|%t`4FGqkyk$VMZl; z9aT>{@|f^exI@NzH|LN6RJNc~`i67nk67+&w?8%TeEi6A44bKg%)KR2IgDdLUcf49 zltrXiDyQy1F`{R^<8H0~TAmMavJ;3}n4^30_(VM7TuDaVMOfYJx`4TYsE8~i;>Sst zzL{85Cd=9Ps;|FhJA-gf4PVO|p3%zqwlMZC;{@x!r8ha$E2?dc=E?uk(4`K?BMaVk z)5ii&IVJ;95DF+2Crr zfbV_CcO)<=i^%P~>hd2GBpCl7h^3}pN4`RYSZ7@{8}#K0%S#!90;{%flpbnIy(tKv zCA9NC!l>k`X(Zt@_w9n+EB)&&Se!M*i!dXtbsYpvn$F~LN;iAIPn~0M-yLmPk!`3@ zprtZLIzR{GP9#%fgie<*p?-JlWnW2)oUMfNN0Ax548f8G=VvQ0 zKc(U6@iWcaq6k5?jgrDj<1RC>A>Asn5eb&?yHrcbU$;^!asP!=|R*T)YBlc9Tm=c2MXF>2~_$S-dC0#j53{ zn*4Sc-zbi@VGhy-)t9UyKCpjs^1Z9;5rw?3udnDa5PRn5&*#i6EX}F_tfApyLQ+yv z7#zOQ9~m3lx3|a2$i$?khS|S^s4>HY`F(Ddy-6r2O28?7Mf5RQit> z8ln|s?7`|mM`Sq3TUOrUGF9Qku1S=%_Rjj=_z zhKn_`{-eB6Nk8TtXBfBHlJ?DB^QxZwe-#W%wV!|SMeplzJ8nYKNXQV_xnp*fi)}An zXP>W~Oyd0;WB4tnjN!Q;j5pbm>VI&6$j*>ut*^wins}XQxzgPW)4z1uUk24pJ@%Sv z3hWEiX*2^J9Z~yGMT^_cd(#=lHobDrqCS1+ERAzd(>_Oc$Q=%Q_=L~Xz}-QN$%QP35n?W4zt4WP=>+b*OED}*LH{BOWt_Me2!*u{#hL( z!-}0+#e8BF4CR4?D}UG5{{*7vt^@Q8~>s@UO`@wMKEwrMa3fTUqpF{6*YZNhtb2Ss#sU`e5tv-8k}{{AD5vRVohlD!%YDbWPvH8M5J{{TS+)oz*Wsyt ztt5l;PXDt1CXEo!%Qvxol?!eCH78z?RhAYaPb4?|*U)BUIhOXCmS}p%ysh>n?=ezv zT&ZAq`pp3cMy$pfLWho-)r%j5f$%AH|77huo8`s|Dlv_z75wVK6cRYL)|u4#!KF!E z5^a7UjJ1sLds%JML}9z~v1d_XwU0`Lmz3kkiWl*uqh(f^_O^TR1AUyQ_L>hxtfCD$ z0vHMjn_zfvB=%c4_Q%9CP*Gu0l7W>)A_zM*A<%75fgFMEO(L0f`KXj@GI|2^_i~p$ znpZE~Lx!K$XmWi|{nj|Uy9#0bYo||_NNH90ZP;t;eqYAJ1AKOoBdgh^Pm?|6 zy~00NHmjdq)70J6NB3HC7Yi%Q-x$Qr=eSXq4b=jO8k;;1$=_cV(CNDFjWHM*!6u{? z{QQJZ2l)8-dPy}jWnuru`M5RrJo51?sWCs5I2SsGO>C+HH|DmF+DJDyjXfCHNQA#92oMzh#-jf ze4Vh_^wd^m-gG~y&%lHP^Kaj3RUEHx{K0COqYEeG2f28jhZZOZVtMZ{0=MbS6yi;c z7rB9air*wED9Wb$x!vx?+V1{Z|GrOi-mFr1u=y!3h0!gf0tCK|+LK~6MY!!mvL@+x zW1Prs03Apg4tbBdi7yieJ8`qCDeH23$U|-J4;*cM`KQ7|yyN;vdxjb(TyZQ@Eh4&Y zN7LZ#*g|^mqx?@hZDmbYHtxl0yD%5EvK+$vfVYdljOzw~#@Fx(ot33sxD|_e_*e4S z9~((S!qb-D(JZN!ZZYb5GZRC=PDMB85d85y1KW=skp(QZFVCR)3gpW948o2j^cb7+ zy{dvBg^ux~x9;g*pab+2I?o0hSg{nk{2d$(qq7$U7=(V1?I()=hcr3U_ zBG@ts(e8QQ5}D4aG+^S7!#vlipjWI{COQGBu@V_)^V4@g*%n z9nQZ0*{+j?Cf$;w@~6_qu+r%j_f`IcuH5KPJxsvN44$Zj1yBX%!(gs#{NrH+Sx#Z{ zjWLrU3Nf?AM4N+}T-D0g8$6k_&o}@E9&reKVLC1q2Z7~LTfgc{gWng$-o+VWx$tXF z&EP_6M}JpE5}jGrU{5FNubjhc$6%JT6Z;ZM>t81gya9iX!R`*ru5GTS~z+#{j0 z@_<-?$z_0iQet724R`~~{u8$LTVxDv@4DVl;bcI9Luq;W#zYkM6cUVR+M-W@PXcZo78?3FPC;o_UNrKSltr1Ii77;7^558K zu7tDjEM{N~%hc4=XE+|dFs?l0`TQNlAIhNiKh{wqbX%GYnHu*c=TNXET*s9IN|{#@v}Dbq)6O zkO<5RaO$3?lI|>}H=sJ7!#ZAvGf=vCEa6##6+M>9zR=A|_dmnaZ!6stZ7&=NgV&$< zR|6kQj?d#oJAWH`ePfz!&YAUfrfahE_51Zrhg)i|Vk0TV9g#WR00Lhm0>xC8_P|q1 zhI4rAy0_i=Eo6vX7azjT@)B^^p#?s>k5>88Ci?n{aC>fRBep~U=Nq@c3w?F=bz||+ zLX6{Jkvn=0&2UsB5msFL;*Hn3M!@A+|L<+NU6(cqy7@Csyz8Y$#@+}AZ*Q|8AC0oK zi67ZOBrC)HAkK_7)CBa@*W9>J+XVE5+xo=<{JP-6gxQbXy%Kv`3NIM?fO$f-GBL5B z?$9@NUC#svDrv+s9XAhq8}kkuzX`}K{+?j{WR}t+5)$3u$Y=INoNsWIla5y;5N4vr z6MZ5_b*0h`>8|v*Vf#3wSDN0NK@odk9SJp4BGWD#GO8c<3&a)sl=G86q)ACmlNb>f3ev+5Cszch*PIzcw&=ngf$SE772v(iG38 zj)a@0jQv8s=aH|WL^OwG{k7E?AgVe4Qis%Wa4)bCWBB;7fg!8OIE(kFLfh2kAbfdI zTvcru$CWz~MhL%iJ2Wy06XpS&NA*6%WE>A7LIUdBnBd0jVnQIUH0}Z6tBwXNh1>d< zI`I9hmYQNAQOV))s=}8P8dfq~>|($70?bo44n&JeLqBiqmpO6fa4KE8ka(ttPNj4g z*diVc% z?)!M&?=v6fn7#J8u63U0Z)F;4C42?E2r#*MH7}dxHeday;E<5j_9s1N>+A~)3kyNN z`-aIIG~Tt$nWW&zIt)_DE|z!ie$b>sH_kyYSJC#{$qEn8)$40P2YO|xuqjpSqMRI5 zLqo$B;&_TabxzL8M}KTDl)+!WFh)m5UweI~_m*cG6-E5b*_IlKNE#KvqCvoFj*=nB zbA-0n4y&kBUf4ZO2DMiatLNihFi1I}A82!bZ5!GMPV8v71G8E_)BdBd5=UsRz53$v z@_)j2Mq-gX#h+J6wq;6vu05~O^1(cLsCx#dNIykd{w7V+NNrXTR1AVwqS1x9)tDn5 zl%qESDk@IoC*;*0OWd#TjPwJRqMtA-L~3N>H4z=zqnOq=t#~EJ8)mU@=qwoLC|Fl_ zw}Kd_K6jtdlEd2TN%dIeDoggzE-zk7n;yIxqZoeEzV|T!_Yrfu!td+y{ThRxYYuv} z>{9r#A-*`-7qljIhY~l209oI1d9B|$1jCHTnp2jU#9M+NkR;7_Ss@+S>FS>X602E> zA-^jNm6T=7E~#rs3vz3L7J0N-j6{rBl;`I+~ZSpGz31zB*o zIS7*GVZ_XVw7F?2;-`Qk|NNIz)6CCJ;YCqQAdL8Qs0)V-V0${SA+*AV#-KPCoje!y zV^Ly-nfY~0wD|+9=}o57@(SFlJo3|gOS+$=Sdj@pQnn>UT@mAABasccA(LdaRlcZ{ zi~Iu`j7nel7HdhWGjYCz>kwCN-NE4n`{AV%ZRM>47#!)#C+H`8i>UQe#=?uqHC2Xm zo!#p2wPTrE+)IsC8(sjwMIzU<$npJ|@qu?tLvHcIBi@#^tS^^6Q_2Z7w3z5gFF5FC zT~p9V=O1?~pD&1r!@n2`N7F1fMP;;jql!PRxZU5s7dXLM-=5c4_1 zUTStCbuf50eEFl};#;>!r<-5tPf>y03b`Cm60=3{Pl&#`Dn-dQ9vbPxiL&W-w7}BJ zSU5nAQSgU>I6nz7-Ah)2N?D8^aX*#SvImR^?r)kKc1RiOmehRuOT$nn?{! zB1PN7<-8W)9VOt@Z|JzQnw*|?c`gT_5H9?S%gQ!4-4b5pi0Mx-Mu=^?_@|BnJ~&Af z1!3h=d0|e3`l+9hhVgGU`ig(aO~UcoJp#-n|1(;}Jxq|ruvzLP&9E!=y0)-8p9%P0 z!y#y2*5kDuG_#_H4j_yhZZ5inJum}C)iLM2Ukc-VepA2emP>5Vt7vGA>Ho+*QK5%* z#hCO1E$Lqn1dVhRX$NWh^7IgneJtT^kA>p%~Wv99NcYB7O09R%>(c=Q!n64;6nd ztp&4l>lr50q??<_H;+eCwNHM> zey)7dZV79@ySYm<@;!b2biZG4wDv7_xog?a1Ba&dff%v9<250kfIFvEACIk=0>Hcp9 zT#M8~qZQ*Q4!hLT6*Ya9ICv(C+T(@0X|*0If77H%Z!U(Cw!-5fd z{l!nutTC2*w!&FFO6LO;$l79u@E>Vd17z21eye#8J2xkKYy@De)ZOSzkQRW&gwRIB z+6k8zS7Non_-~M|1Vya{Djw%3YPto4n*0I%W6bmd>AzO~>|I~~tUr!zZwbb);LoWP z1gSn(I{q>n{$@K`pGg&aFA|dtp&odHMry=~QyTuv{0LXl2?0h@R3S$7k${DgC3?Yy z9X*M@#=Pd`!jXot^|udGf^~JX3x;OuA)A~h( z66xjCI9|&%&74bSzzJDGpcqt&FW}rbL6=KHOVM1352XENN#*t;xR!Kd$U#a8?rWRY z&>!gpFny3)3c!8H>qwa(gynxaq<}-v@Mvh2-|PRNsJxn3dxgcJX?kLtg^;VWt9!rW z)~iUVU^rUq#&ilLgh3lK^IFur+&-#zd+HcoXr#X3hR7h~CI0hnoHE{ORgMHS&4XYr zVd&7)ePXy&z}z!KZ>8r)_Oi^Znp!8WB+=&u{08F6Yc^50qHgPxIihI*0lR@K%h9Q7 zIsrL`%?j1|p{|*bzN;NVg2e<<3u^E)#S~DAVoKBSFyIo1pmgc>ct{YNR(`q4_W~=| z)+J(PO@UpAaedB}hLbOMOm^2zR3NH<8!1h@8+pd#HM`H_ z8UD$<(IamA-34RXvi~E_Au- zxn_IwX7t4qnbk)4FAwWT0N{o}(Rm8bb;iiJviQ&@W!`cd%fHvbK8H7Py@_$!buy%I z7Ew3^rz|9H5c6e##s3DzEmXaFn=!+!JAz_`*Wk%MNY*p1Y*0*R_Y+r|$o$H{rY0+Y zqdfNq?;6vh(vEBfo$29}^Q#Ywy%acO`5`+>dR*SOtRAqfPc~xn& zJN1T@9oM=!=VYRqb0sTz@z~B7+!cAJ!s|-t=HdWu-RA95lp`?Y4NMz8`!05dx8%Fd zet$8Zdi~4j&+4@V@T**<<9>Y#Zfv6MSyTnVwgC5rp$=e=Q^-v3SPN7XwwE@BprxQ| znW*uyT=iyguws2Y!(_u_ua-1QRFh&t)3Su8cVP2jl`hiiHFnHxzCZmn%YgOBfvY|L z55TZ=Ak=m0Umi3A&=aiZ!}8|zc8oP(TO4Ie=DR(*NH(t*y73mZhSfhC^+%%=Y)-`V zb$L$*2GbU*I7I3Bx#aPfVFRTOa>mS{$nt>lA)m5{7H4Uj?~GMu52`J~uif^kY=@R3 z4KEL)Cy9--;SaRShMm1}MKTT&H@U>bM*(@4$=PEfOJ@B z2U2v=J-`Jg^=lQeS`x}2kME>$<%6|)W0p`8;7-%mWroBBTN6uvL#ipFkxx7g&{xRK zz1z0R?NDXu&1qBP-KDvx+~rd!i6jbhvOdKGM6=G#A~F4Rty@jz9hPb&PvW!m3Cxmj z3B?p^rV)chjf4wnl$wHkp#n8&ViBp9Gq-PZJ`JZdI(^2SCZCAibz7TYA~T*=#&!Ap z+HzZnA2`OS(s|fWJJ?)`O$A4e8#H+Op^1Av@cNysr(O?@_(v^2?GoMJ)VFsTJssQL zuhYOsZq76OuUPL_>oZorWIUm?KLRB&IpPd4t>^~>7Uu14myZmpNaP+ zv96_Am3Vj`J|q;A`42nT>!>3#)(2m4f8V%%f%+297U{YJWz&If2C*VNeo(cU)uZ9z zv7YeW<*{+{fpmUUdYpzNAOAZ$oLOl{#o|M?5_UrM-CmMhijTx(p_a4jWzzk{xiaQ< z`Myt2`y}#% z0KKXwMlZDzhlE+RDxZ>?XZKi^j*1Q zE)WwScnS2wnVJNJY8;v_b2G==IY9r@mNJCfYJ4-*ueq2iG%bsXjbOa0-P}JbJ2?<~;^#^sc3%|GY5rP^ox+J)q?KhCrTbWA`5qX@o{1DKvdRJC(aO0$5C@vdy zDyFHC?%}zG$!VXf_I~%LEcl>o5PG|tEbdFze%IXIYvgxzb-gYAfcm&u(Y}4ZC;k|4 z#_9h+^|&+A-YfpNBXIrTAlB>PfARMIp@3#>Jfk%_qs5=<^G=;lTx(I zWT#9^jh`s>P3H?c*X5XoV!xW#-l(Dl;u4>qG-WiDS0wh(@`v@ihV;ms&fNMYDX;%6 zemOb8AmegvAn*pa66_oXa$T`wIu)p54q2DX*z;m%;ecBNN>B!|R`sX|<%-z(d`ULy z$e$llz6&^nHnAiSZdDNya-yoqT`D_~?6MFN zKk^&$DzBD4-lB1-Wfs`e#L2CRM%xnOn8K1^x}k=m z>tfyJRDm6XIPWWc(Vw_N9_cj&);zW!J!RSjA6qVVahF=GLbsOJ21%Ag#CsdvV!m%I zhzS24@mxP=;^b@b%BD#!0+>gV3xfW{M+V{{8UBu_8UCkc_p4{hC$aw5F9DyFe@FYn zIL*n?(>)^*ud>u$#?z_r{Y7khUxwe6;{BsQ#>$zIU(|@-C7$2ul3R=a8Ol$g5a!1-PDQ4QYs~owwu6g1&6WPk_u-M1}gSfKktQ4mcWQ6j6(Poq|jhRPV zdW($SaZZfWcuZ;cNm}M7P@pN}D!E|4A|}gGIH?V4fBeZN_M^jY`n z7V7b(>o2-ku}HG%&jIgENyaE+vofDpF5T0mrPc*)Li3$YPRUzt`aJ*qY!57l3vheh zO8eX|vA6h^<6PXtW1i(9+FoLw%>*+!Fa~?tOMM?<=s{}$4=le_ZBt5h%HQlZ29*Hkk zZd_nj{c&CmznH30)M=0Vo1$#D7~PMsnEDCEDdBtxHNf)h^^+^K7S5}Rd!J z#^owDR>_a&vbyo5Lj1XytkI=S-0$Hmc?rt&nSYpB;t^`O2}$*aKf6-N3fMjN#-iZ$ zoHW%di-W&ThDk!|If({N>p7_E1E*NWs~dWUrLD`RN5=SKR&Hli7n($(@s}IEj)*md z_+M`-A8-3#lRR#6ws-sApJkk6Jl$&FZ?`{?JZ1b3|JEtpd){#Qs*QWn7?j*ox!xlN zXU)=%WN0cx5WJDVRFE&cS`r5Bwq_c}t4J4uvE1NG-WcP}KR0}y9@@73K8;LS)ySUE zvZk45)RyyA7aYu{9=sl^^}F&F_je^zrd~+Ott?+VEK|Hbp~$O@S-t=LS*-S0-codq zBEn;5z0GvDon-LIK!hC^0~3SKW{KX}^MVJ?_q{(`{LoO-5MHQ=FA{ySWGSXMW9--CmKnwye`#OwnbOO}~ymN zqIJb3{IPzsv9P9L8(d1XdoA&neix=1#Nw#RH=YISPSZVm_Vt;9jHJfC!rv6p0B-6* zOMEbL>%+PN2M9)4yVWJ*O?a8$96%op$1z+FPTmi*k1HC)q2eWzN4wR`6`-0wGv0uiuNa22Id*#pTqFI^SiikV%*aL)0-KD7IgjauU90{}#z0 zF0@+VNQ9k+?oK2FADtv8g#P2ZZ~)N;XjZDn=?3BgmjQ1tbyZ<<=Luu9+rrY)XYXm6lMGDY>t1 zZK^l;?_n$Jih4Wa`}g zbIHXiD>A1Zwv@EEf3{V1#6s1q)@4%ddGKsCQ*J1A1F%A=GFNE8*&1sQjOB*f#=lh~ z+4yWG{wt56`F`OT!foUIzh9ZFKXUJ`J8;`pGJjYc$g0a zX!Lb6buiOm9!>En=ol&(X76|Ly>>2)$})P=mg?lf|3QZUb`;(5Pc?_z=Nc22=7btp z93K7j<^1kioKC#wSB_Y~)OlsU{BcNQBZ=6(kBHdydi}LmD96@k*PtwahL*Q1@eL&? zninKipE+bDt(ntuSh$w+NSnmi``N5|8xOr|rh91VjftYpNlm(;FJG0W!P)2bJN30u zllHc{(>7ubMf%vj+t_xPLm=*-jL*h)W@42E|8ev12}`_6$!>(9^dO&12t zKl#K{#Ih`k68j;tD3MSS0gj)j>ytRQSZw~bL64AN`n-FpyGWMGG!=Au<@U|{e#w|$k??WM0!8u1X9N}-N4P2RDa!x` zdORxOtvc4GFOaAVRG{r>K+92+hPSK{;TIigdiZ-zG9s;-(&&9I{E)kfIrsWKue2 zzZk5f{jm~cjeyFlCtfNP_o=xGBw_8(5ACd?K)>P?ePZ@@%*>;}xYS->d2AJ&(CvQr zp@y&)+lum_!u(f~OXEcM<5O4XB{WUwZ@6NCx8vD>^}^i=HkrC|#zMDvx_GDmlZ?pb zUt5lini*RAdh(@_Q$FoUuV zPoH;5MyCkC^$iu!lSDi(!11#F3#}0yh|3lPBXR;o5ojU*70Vg_X^g=&vz?nwZ)tCg z$5BoN*9nG!of~sNy6W>ScICc(2ppE%N~C!1Qt7eI!S=Sa>(ejyrH;k7C%AUfdR*@X zo{f{unzTAGF?>u3SnYn#6T1E|dStQ@Zu073$@|sW5)&@vnOJD+)pIe*3+|*3_c+dL zzN<$EvEn{_sAghMFP1+}nID;96@uCu!{8OgPL!V_M5JDI{Z|r$wM6sWjixSbD=5Dlu*8X+6*tt_!-chg#r=Ghh;Ub z2xtm#0%~o<*rqwda+j zO$NZMrtrGR?=~a;v}0yiH?=RC4^!nH4Z+3cNxQxeAxSJnkR(W3%pU|}%?l#k?0&W0 zlH3}@V0~yS-uY5O3)s^ltDXSw#o%hKJ$vB(OM*?47;|x9^WX;O=d$B>P>_^L`s*LoUc*8oJjkJFJZzYWWq!V8tI@YUee@3(QHla`GFRyf$ymt`UX95r;%DkS9c9 zK3E}e03Jv_>Qnqi^#}QUyG9&H+f!-{%0@)&rHl1Ynxg2A?OV!Zowsi^sZGk1^!$`s zlTS9vz^Y_1+J>8%T!x)e*LD z8)w^fU?lO)mp5Vbe*gnd!Sm_sFF|cYw`u2|o6DVp9z>^54y0dEKZ54}oXGxfIUUDn z&NzMdb~h_hdM4+8&))X41ueh4_b=aYXDI~hFYFcmkf!zbc76;+{zTJ61*-XF)cF-U z$5>&kik9i=>q>!`*){F*I0w`%No~9owN$ny}D`b4*i zTc@86czab+l{s^%b-ReA0W_M)PN^TtV7II2eJL)%nsFdi`BwO4jbvH{6`6Vs@w8De zSAYrutdg1s7!#`)|JdW$SPSck)_*~$reKj@ZLDHQU#&q)X3Qz&cW68ve?&z7;Zv*C zvV@@_f@wQhp3U>es>F*3_M#OpLg%atA(hhst6sLHtAWq!JPi($vR@D6f*U`Zw7;Xw z#dt@{xbUr@2nq^pY$^T_EupE4My4$SOqS=ZPmKe?zJQg8cpPJMGbjj)P4yKVrQ|CP zV1C!Q+@8hX)s*$Ek>^)sHhoeEkkXA<@vX>i3EA3T1qG07g{E<7=k*}4OP`NpKz2%! zfp43_cS_p)v{5%T?X^mg<{Fm0#`wRPLOP1&3xIrgDOeSP%}OYy8W&@^ZP9nSq}8R- z+2g0c3ewK5K_p?;C0S&Zfm7qh1x_kbf;H2#wG;nVL|mm5FAwdMa!OlDlQ&Tej84J= z4t)~^|IYmCd?9C+h(I0k{@dK1()~>XThgttObZK(h55bE?z{KGSdzL_M@t37S_NLI zo@SSCG4$S9;@7V&nCSAa?`M(Lm5~?V^RJw*%B2an(IgLFuH9~aYw+Cz0q+i}>w3mm z5`daCr3`(%E7-oC9~n6rS5`hrJMe$pC-n0>jl24jeG0I{9@onT8{7`qKI;pHE+tW* zc?+6OO<P_)gzzD*q2@7BBP)h+k38tc@=}kcHw>g^uP}@2+s&A5P~SpA^Pl zJ6=~D>w#c2e$UQ+WMqlXV#x}Buc@h9^|2(kx!RXflX)ifI*Q_ zj}E7F!Uaf1kE09k3?1`rYOKn)8_cC_xI~WUF?TwSL(Yw(fbKKxZiwSt3-09$R^w)C z2-|d7aM3W&t1?~OAd9oCb`O4FBFq!XK(WjAJ?28uvhpFjV=R;rASg>3hcw$sCxnrh zwxYvHwrvOD{zW~`5`p!i!XtRx>005=wG!WhxHAaIj4PiT>RqhZHDJ3_))?2ibN`u+ z^8v?8ONEW8N=Zf3{n&}C@$&trpMB)zTf_?bc)GsHWB2BC9Rpf!1gtSxg^swFXL1LK47O5PGD%6!RNT z5{T^*N62t=Qa|gGtASNZ`XD-S&{WYrXV*7_c7NUC@MIcnNO((696gz^(vJ?c{*tr< z6kmXr0AZ%dwLNXq^YeYVp?Tg8V*W^KPWll$VSshlR`aLiX~dWofcEZZm5W9J?lrmc zDynnEQt?d)Y}TTh;@=VL`$PFWodFMJ9{&xnp|`rVNjPi8tvnb9nvMTfm`kK;CNXPR zZ?&*|i-{p$qe%jhYVsx2fyws=odNlxf;A5KcvTnOA14JTz>;ha-;(YXAe!${W88SL zT_g6pozQ(+ZE2J)dDmSXaE4#c#8!vRIUYI+bG+W^2+4^uqiXQ@05cREsH3rXYWB|! zX@p?8D94Pbbnykr+j}g zGLpfa&g5mj*j@ep%gJ#k`$DTPx&TLpq`LjP(xE!z(}trLm>8OIj&XxgPiRbV$PBP*ErG}!>&7~TXdCIB)h57HBW%l z+Dhp)cW6?_VHUCbR*CO_J zYtGQsh?^Ot45}^Ja1RC0@=W=0Ysnk~Hth;=9L8T_@(Rd=w-R=x)q@ARQ7V_F!q2j- zgXt?|HpZYR!buFBz238q0VF$B(Kw}V=7;v%_`A9_@RjJ1{2W1(LXyTnRrdVAQ9tl} z?e$S*F7z_;?_OuzA=wC7#d{P*ub}{y_Db1^ysu0Z8VBDF{mGphFL*{F$*^LJq!tCA zC%I!zA{gg4SP(Z?0H4a|3oJHCo0lR+e$fHU>`u%{cw-L~W$CDAZjsjxzkb}k9lgo+Uy-6Buwpd0pPk?0ASnKu&9USBi6=g1Oqy@I(iXvGgwmAB2a_l zJ4sOMEO+5hjO<4xHX}wGCWS=8?xH2~Awr`g+D2IfD=XgQtdp-btE`!OQ481!pcnSm zXugA#Igc7DY-HuI(EOZ~c^-7DljzuF106M}rWCEU_*cgI-oY2$3;0KfwM}D-liH{? zeSM2=1;=PHSuL`QOH_Zu%Y6k$Tk#pm3z!ThV?W8^D8)Aj%|y5WwfhLvF7-iAubDxE zPqw!T;2qKiLL|F@hfmanV48!vcWBSj>53zfaH#_*$K(4Q-~01>TEE*J!t|%};DU0$ zY&9tbipb0aQb{;FNM~fW5&!TZd@y;Kj*$@u2yk`uoK!F%<=OgW`}|Q7kU)KcpRD1$ zgb2ygqcz$7%|sR_Sv6>r2Bhj=tng0L>&9HQNmRv2r~j#0U}R{s25l!a1 zg;y`#_>g!Xd(W-MxgYP2Dy=#_UhQ&rgle8~+jlWu`|V@=)vtLrbtt?7ijV%7PX5=m zzxTs05St6@*Do^EHY_Eh6Jx=mn-={su@W|4(RuEtXve>xS3S7KALT^*jBNIw!6HPi zWc!`;zOrqH^tjh@jeBgl+L%6HJ_9@G-_CN_X zn{AI5jOD*^{XH878BEOyLh?~9-~!BcP70(CooDlQQ&1~f!|B3{#dILprH^+;%EqnX zoia)KhDAxRVi~O`87+VK#g@#J1TDnE(G#-F@ZPJ9spnsMl=e_3e=9n2zUDQx-t?Oe zFCrRTiT3KB0ZRSYXEL9O`Q!@BRRsse4AqTgfpJap@ozLzs`ntp2&O9R?3Q4J7|YfC zYAHSAAL`lpgZS#7GNcM@+UY$51?#hJH?<@v(Ai@HHc4E|qbFcAl3<+OGADZqO|W&6 z%JG1jz!lhrZ81xqGnpqcA$#0Fdi2O#(Q=P9s45FgJ1)>Gg$b4xA;;~cnFQBjAhNwr{T{mG`x0Cx{(7Ob~X-YDEIlPN)-_f=B*pc7)SU z{szj&*Vs{B|HRCzv7^ar74x&9XtZ!W=i2Int;g*#KPSZJasPR`xPP$ah=Qr;r#)rQ zQ)ry_1exN$XvpUF_7%|hsL}+Th&ww2zE`{>Q)i5(eDhj^`+En4usd5{EX@Nku4BFg_teivQ+SY5aqG_>`!P2=42#MXE?P*~c?_5Va>a2(U`wM0>szlEbdqiEL z5<|;*kK2iH^wM(hipy)J`4x{3uUxzM3!JA@>ao|Zs_pd@k2{-xVJ#GZRx$lb_)z&f z{|OFo4}HnM8x>a4%_9@+^#;O<&;731gtUeT#}2_g$%8r`wT2vKz~fffEUfq}VPNqR zTFnzrG(@e{{W6}WIA}4;R)st_a-buT2_F_w^;MSX!YF*v&u*ugxY?&xWuqY4^r@B! zdm*^%4bcWhDjjFfi^k5&eq8spJWVH{V>!N+Ms|~4>+W_>%3xfEmKfJsLrMk8zYg^! zA_ZVC>)CBr?2GaJaZu6bKFby6aFfAIQA)(!gL2}uvpXUj`Mce{>ClP^U{ia^jwkdH z42>`_t?b{Pcd9BcUx#)Gt{g zamkoKqJpRML)M2lgtm9pddLPzUYUp4r7JJ#L66w3gJ#Na>wK(0l8LCF6qVa&4Et*} z5-9{Tn(a7?FCqWRmZMRlQCja<-eIH^doX9Jpfr$$DQFxps%nOH+g}KF3C=Bb5Gp>! zxT~qVLDk?NCsXfe&r5AOt);*P!_?VJni_b8E107(XV~((KgH)l&VDsHo&ZV6pZmR= z>KKlj=aRIVZimO23xZ!T1%|84hF`DzGW;}Oh(Gl+b^Byxm_(%M3#u{=_RGZ#QO~cI z$~0@U)foEb4-YqH_d(L4Rly1&6B`CA%#WAjs0*!Mh%R38ad9sN{!nK$+sZvb4Gv<_ zz$yjST}!H~pCyj|{rk!>x}K`GgQ7nb1Pg+*-taf}+~yU2`+tYe#4oSuI6C;xdH?9| zahs&j`rYjaT9wuX!KDdF%ayuO4t%WaXCRntMlm*tnCo$Pmtu(`7p&L@AwjXgc^TB0 zv=SO_QC?3-)|c6?4reAL9o4t{06 zjN?@R)f&nb|2;dGRB|tfmQ2^#gik{ELf9XUc;r!pT^@WpqG2jC#AxjI(#*P8)0kS2 z1iBXR9rIQ^R9R90-TV!-!MwEs=EqQ^Z?i!1EnG9T3^Fe0y#5d03> zA1>F|6lue+Zzgg@^%;;|uj6YM@pNeGa6vi=ea>?H!VIbA$!o2*xAqr#<<1QapdHTt zw7y`bb`1qKRbys#({u8Fk4CD-qY09p*pVBF5=Jy^ZAzk5RqLub-&q<2II;L{eiyRl z)@TY{CYon@ej(LmsUm-e?Ib&ndN!IRuje*Fnx)6hjBE}VKpAw(tVF?}WOcGKB6-h- zK}@72)l{7HaKxHp@K4iCW3(W`JW&k>AA`~sDV-2c`avuOBR=f`D|GPcU4~iJG}Sm* z)U~CxXO(LqkwS5D)#zq9?|v5 z9Qi`C+jIQSM!jYsJzkI39O+_hv5eU9y?17!zQOI{bZGIwDdXw!hS~3NN37gXG&VRG z#%5UaY@9Lr*ZGMVAR}uQf?(qJ$3bdJ?0R*$zyk8l(3g}*$5kmSYwMHgy{WQ2#>$Op zkN?yB?yJ$JB7r3>o_RK@`f5civ>N|A+4P+E_{G1^Rw_N*wNQ;dzO4($!hI%VV7l+k ziBgK3IFYW{NDY57E%L)Yp+Q}{Dx2URE&}_3vE8(5f_7kGZu>HEv6SLyc*(~Vk|xUe zg|(BLYaKv9lQVmj45RbdS@~=9vNK$@y)Q1ly|1918vUCEg?uz#po0|4)SZm!keu}Q zA3r)4`U!+ZN}X!>@M0a3)&@pjOia{*^O1OaEg>gdYtfIMWOJ)n(RP;Xd>hFYQfj(ae02pc?es|ONfOC}BOhKFY;C_$q!#u#YbEEbHLISH%n%{xl>Yp13BU*S22K}Yu zIX(d)jc6!Fw`jcb8Ur(NvwC-91L(gk8W4DvzTrUxj*LlZd-gU7-^VMJ2v)+P4n)#g z{I!>FfJN9J6$A{=E)}QQNMQ4hX&hJrRJ%wuJHI%irX^NL00YyvGSxy7VFND?E2Vzt zXqdtQAraK3V(bJ5-oMt^io`GtaQ`5h=Ul`spkw=%7yiU=rfR-1JD#A)MhaEb7Kj?l!hq;Gcngq#W+}GDCsfQtJ<`u!H zuMwI(vTNs(`a&+4$s^Q&^WeRp_6SXHEzU2;_0to{M$em9pSeHlgR|VwrblQ#?J+vt z?UFCF`r%!DHrN2|VI{-rk2glC`b5+FZ{a6r-|nt&fJ@xLEb9Hkjr9F`!Tal@44U;L zaq+Hij9>oF&*KRT+x|%tBN6}bBY4Nm-xHs$sAFJwSWZC!OHEzf#KtD#{@&+O%>6(5 z29F{;^3nG?1Dj1%?KdPzL+iKEVEof)0k-BE^ilVJ)ViE4`xUB^xN#(&D28H&(jT3* zs8~ON=gT(#I{Ul@wEk^72Gm-;yzBOI!2%k5mcuya+bcuC;Pg=S9;}(rFUG}n_+qc? zUoVeLhvhkll?GLx4B4@_-0j73oA%2`y%qv>FWGoiu3Q?#7<)CTV?1d}qtFMnQILAm8z0tqjB?d7ERy(W79W%7HW z+n8x1FEk5d^@2iWqYkrmco;m2&Y`VvNXLX3l;m528pRPNL{5sMxH= zSY*45`+)zXAXcZ37H1XV{`P(F9{+Oz^uzxI2AQa2l5CQe@{a7i2o%=8HbnP-F7B|{ zQkWPA7=h;;n*pH@cD9DdruTahp1R0N=0P&fLPUN= z4@e|^DMB5ylxf!hl0X3UHa-CXR>ds$e%$;I|XxItg8-S3eCo}8IgD@?kVZ`|k2v(hPw}Pk*hn;Z@p^08AS2$&fWlg4$Bs0V$pErB zFq_lhbNH$}O*p1xJ9d38gs8#&gua|8S!s1Ek%)7}gC;pg??$>nA2(Q?N(jQZp2ReQ0lIFODwA$?Ut4@hcco(MDR!u|Eho75o@Q%j$PU3)F_h6eZa;JsT?wNDdi(zL?$hMOH3CQ-B-98 z#Z3b!AyxTj&<7rmu>Xg@;#c6wfKidf*M=FfG*EI#XZ*OJ2;YbuE?gQRSb|Tl6 zxR$X8@0}(I8|e8>>MYpArg^%P#Y;P2(TU&d{$QU)nIWgzL0XTK;md}R!)dx{Ohca( zl_xB9Gnp4(voq&gLFWSdWPB$W%O#~zvVIv>bhi=H@#d%GFn1HO>nzP=5CuMXs#-D2 zOW=4T7c!EA`}WZ$Ec#3wym$v@x_wOS-gy7Ll$1lVy1x*jn_Lb^Hj4+;9&v<5b^|DD z8co?m^<7r1z4!)7WIn!}I_ei7C2T%Dh?WFfV@&?=-*_Zf3OXq^Sc~H933;6Z`KIx( znRvlT3Pa7Cj3m-U1s;2UHEgzn8|W=s5>v$%3!%5^#YHbDrCE`(MKK=AWRj}yd;#YG z^dV}88dK6Jat2mQv%TVX`%7CL8mak;5$AcofG3}^^4cvKd(V|!D5mWT86DNNo}JA1 zMbaMRvU)^@D35eeMgrMs(T61EDV%lR@`e`EJ%~b9OKw~buvm2s2BlRy9Y|)ZK=YIZ z|JEeXHo@LNQB)Nw{9vqrMk>yLKtp81y&I|n+o)lHxNta2t}{P-Xa7a|lekXa8;uCo z`K`d$A^jlW2B_;p*-Dd0gq;`etH4H+UYBsWlReToNK+KdrBDlaq2r*X{hbgkr4|s> z5U!3+8KG8LL637caQ0UtK6YyWWq(;cxNa8^(*aOsadlRd^jd@>D^!;miW<_lCpGRS zsXMvKl=z~KRZXj9w8<3wCRu9;k*;a~5KMBU*xTS(n(A^WgFl?H-y5Qi@xt-PAd4i- zKved1SM7M1De1dP`r4hVgN_blQ4 zUY8pjF;sh!5?{&uu1zTNqiDirzcHE&2Lmc#5Q`xLvb3zMu?4E2&>4u16Zic)rntDc zhlfWYI#8MpP-BJ7M5eO;Ja+f7t;w|Pv>G`7e=U&I4`YSEm(*QYNos@%E5iqHaGLC+ zyb{beE3+U>+TApTyOSD~^OOa*NsI0W;&(#sMb?RPP{)(st$i`#?D?XuB{?sMyY+bU zy=H+pN9>MNIg8^avKQ`K^l#|%(6E>l z3&N?6;muO#6Ku*1wIfZCw6k!#(WlqOi zkdg&i#AYW~n#ouXsk)R68>A= z0o(pOvUZHngC+>nZi++8wCw#AGnoY^)azooqF5YIcDn*iiUu#a*<82GD7*Fbh(48& z*JynBOkY>d;KUauy{D&LwHYz{+AQWxlAykzwWGY?Z`vYW6%S^L&TkE4x6k_qXBr0; zG%Bxj_{j20wwaIMhlz)&ZIqOu?04yy!XYB`aQTebm^^Pj!y*Ek{ghA*p$1omc88{z z?of+k-qH2EAVMWQPaCdpw}v6={~uFl6;);2b$g{dHr=)9mX?ra)7?mSNJMDUhT#od`K<9@bItjiRL%y81MvSw{P*TNzRKywwa6fdIQ~Fz z9fZy2<&GuO1*&9xE;fFnUW>by@OLXn)*#OYWX57{`&Y10L;=e)OEvbaOjsUza$RDq zER($iv@1w%{$w;Rp>bUVqR(C@nu$M&q{pi#8ke|wK6);-ycptM@!JGlzXgZ8YGaA}~(Sq&Mt<5m&-`j(Z{BGkL zaFXCbV>00GV=@B(c3~(;AzpIVhUJoZah)-iG7p>G^V-#${t@ZXP@sf!AHv^K`f7_^KcCe1e`T zIQAg|kI$$VN>?tk4$8p$_Uz~N+pi9Js1sJ-M`T>Zw8+Y9&aD~;`liX5fm1}ROPn>9 zFL&7^CrA~FLXYBw9fWemod}O)US+YPWxb34YqhrCpxI!*whU7Jqs=RoJxp_L`{S-y z`eC=dbr~?~pt|l&ug0P?uiG-2RdCYx(;Rr$pbH{}OmjG_`an&piMGs>lD$e`nG{zJ zmC1|LpfL@-$bWlySUY;?o`1Lg-Hy*^3zk$StDq3OI{(d%&%WLK@DhMt`{UdIV}vxa z-`FWGBQdC@?=!e4k@B+uyqQ^2i)URjE$ntgOb=xn!IxCnZB==@AM7TWU1^<2Sej{K zbCggg{&$8pavV&qYE&HEm|t&idFy!a1Pia0vrl4@ZE1t4b?U}zeTz}=iurQ5CXgzR zPQQQFHDAu<8pE;k5VB-Mkyxv;Y^ZnUcP-AzXNsEBPm508Hs#zO&QE??JB$yqT~%U9tbX;VuphO8u3iDQ7R(5-D2CQGjLQ=^S`1zkp&+K1=lXw!%uPcfP(r9W)B!Jk>P=T{}atLg9;^ zY$oiBa~wjxSN?O+lE&%1@WE4Rl^DYFt9WZFP_cIBnl^M0wXNlQM}#Knp+c9UB~G9H z2@95 zOGcu^SlDZ0-8oe%~}mL<>@`G#~gCH0C|hSu|yf7 z3%EHT+9Y<>stDz9A{xqV;f~=TjmSAY9j={mzvQ>5MV#5=JQbbW%h@kkMS0i@M`A6K z6Z7;E-;Gb&MW*-*_YU$U%-+?3HN8nj`Y-ZWnh|zR-zf%|J@Ur{alP8YLEUl*;!xVRI z5!3hOH+)*X#pTdh8WxS=+dx>VpwS<|6ON<~W%F-$1p4A3jo}CgooVi0zj**C)y^(Bc&O;(!F#>CF3h5TSVGO3A)|HF z1ZJHm(PTs;#(45A4K5u!TkokO7F@>l)b@AS|D5tbnyetLZ8Fz@%5Id_f%pr}|JBJJ zHLoW%QoJ2x1<_f9B=TR*xt>7-ERC z6xq5@@sMAH_Qw1DW7n_B0O?h3En7U)owGuRk;9*wuCz{NUehb9!6p+pyh@pVciWZ? zxDUC^*)T~|pXW(NlUac8M5o9$CpFw+RTnI@x4)RuT6j}W}H2=bt$nhy~C+fK>XgBa$67J5(p z%PfW$q@!nz7{*BPow^5h2^m17_({xt*xQz2s6OPyEFF(GX%>l9mjOdXj4?O)I_Q&+ zEZ!GZKNZ&8zzlei$obrgRO6sfc07%+fy``h9V=Y$oW$b>v9#NuRKf}aO@VW$3`Cku zm-;+`Ls#11D3`AKkPETSgY9eO2$qqC4eq}SKXDv9wRFvY^nNV54O>GFJhOfwwJaS4 z_(%WjNNuHur>|V91Yg&V6I}H2UNW{DzoKeh*Qp-oO1{pQ{Nb`_4~gvpv@~sFgwc4> zmfv|aXVl=TZOhRdax=syLDeu)JWUY=2)c{7&QIv}WI5u#YnTdc+AEnffKa636 zL*^rwFm2+e2qn2EY;f{4IwNbJgdu!k1$Jje$*E$ro?$5+0Wk{uULm#?|Dhmkm^#K@ zDYn*NI5t5cP>ZxJUey3a(G85qNjXZ)?AelQQrT2_ZOnd70s!-DsyNtI0nT}=#W>g4AG=F z#lcgLtQRnABs)M;o|OT{#B3QBUi6Kkj`C=D%G=eE?>0!FYR22GgS>V{ccYh*gam{Ivk%nu6Edb`vTwNdY+EU ztJ(a%1^^mODz77D*Q@L0O=8pnrlpNkzp*YY6SHTnl^6xT4=6=j#oP+NXSM_HdjA)C z%g~pAW)Yy{#hR-zXs`qJA)_b#d$rTwlzjpxXOXNwm;j_h68B27z{dSZYe?h?l{M3u+P+GX{euI&e&60d(}uf`gMSNG7j~i%7hh=K z4WHYER}#e+ohsx#jmL?M-5B`fpAmph9-m|A4eeueFa!<31ij}m^!H(qq6^;mpOdZh z8oaaTQOCAMLVh>0KxZd@+%<{6V~?H>KaMGXaOmPCxSZ7t2*KgzwqwNleuzu5P~LFF z35hWnIO-QX{8l2&?**~l#EFUC#&E%X%BkgQ;O=$2u)}ejT(~+@(Sr-CtyePj2Bcqlq9hkR-h}Dbm&4W`cgmKk)KX^ znVH$$4@{Et6u|LPtxRD`ccDQp>vsm8Ro)pzbOzm3f8|on`;SLWt1d7+Y@QMv0WQlzo}{dJXxAd8$w0GndG=cthlEH-m9x93@V+ZFIdshKx@X zI9g>e+SxsM@dE&;6fxiDlPpUIT%3XN=dgT5#9ARfS|9x_4&>~ytazDi$MEZd3)#(I zO2KrTJ$PogB74CqE7UZtE#&dw_JSi8Om)%76u4vN-3#ga{=uYPnU*?VDa9SGOYX18 zn|3E#CROML5vV^_!I(Kc*>>p5MN?*pWc-s$wt|Wp9={G9S0qFu!1##FS$~X|Tsibm zS?_dnH>`~ABtspWl@OTRu*IJYHT6EY(!w~GBr0KR&L4ymRvet?NSlrugxo&RfVM~hJQ6ij#HNi3o1*@ig7>eUaFL|t0zsaS zjgQhLj7m4H3<_eZR@`ZB2Xw{AO&9dS2OE?w3)uPPK0N<%9ItET=E=plt>^4@IR1 zF{iJ*Pr0_DI@i0px2y*Qtn)3eWoaOuUH@~ByxM_Nbm^pjTY$1T<=J%bX#BQc@$tF9 zHjNA3&YZhrT&e3q{u=oBSt`}S82Oy6fL`Zt_qZBD+xGuvXMmttcf6a%kwp(f4v_+8 ziqY1_&+1{Tt@~`n0qcHpt*48Ssz-fG`%=^Dv6>klvL;yKpAvsDQy)nJ>@FSMCCLJd zqKSN-gW!rLW`kP4g9Q5Sdp?z5TrcXF>`G-DEni~dv;P1GqY(vcQArxlhi>6Nma{)N z%nzpu-C@D398;{VlN`Mrg)Xn4RR?}ceL4%U7$t4s!P(XuW&!-JJth|L8oZKQV~;jh zk2i%6-@1f~DxLd8pYc;+llr_Ycw7@nrOehOGI%{uQzrEW{Gz`#Xx5%29^~h9qGh)C zO@AGyLz0p*Lb$_&$ra32#)xdnJF{es7WP6+LI>&y#h%Z>EH$fcSVxx3@;gvAzP04F zX-HTe(nj9jn5^sbSD zG=*jOkqQVpa$tKZl+=oa8dSG;uFld@vn<2Jp?<+{SOSqkFHyeY z>4=EMqoy7X|%YUs~wOH9xKkx zj+yVH^2YD5OYF3U5aoIo&5cclg-ta2E?0@R?dO6?eqt$`x{p+NFjpDywWBQy{0LPa1}iaMO~Mjr&2Wd6zYl%oFvTqu(F zB2eXY8;ULV5}W0po-X*AiE%nil`Q8ss*Su{neKLnOceDgt&!rDbyNMHwmCV^We!Ri z)0log>#5`1CLt{*FGPXQCJ7 zYwqLGCug?7nF|_nnU^Hy(PR;isx;0Xg?vT=oI`+@O3OZ60-40fRt=iuOsl0`@aLim zE0dPtz39!7g~{tv#m6PjxtDU-mJQIKcrA$1T(~lZQ z`zB-^aQ_+C+$8Dfm;N_`ZM`A6F{4L_1|6aU+}Hy0eQAfLv|_%zI0|S~TnB$QByy=d z&M_HfD+MBRxT#OKJp%_H>#;s0n5voKJmem=bdik1lW!*6!y z2=={^LLuOW>JLU8j@<&T1eg~_H=%Cq|1|TjdP`#1uTC~8f19$0XI5e!V1|(#J!2#; zeoUW+dniuH&8J4jYe!aATSuLWbY-eX@5j5oxf~o%N-Z#pB!D|lwZ{vP_Zf76l!$4$ zQk7Y+Ih^)T=<)etO2vE?w@^j@e6N;YFM#~D@am8`OiWW6YSnGf@VyG50Y@UYk~h3F z8pt09!f3>kS3``Git;PLQJD#Sd+NwuY<4U%+aMbQ5q}j^bqmQHCkx(D`pP)`aafU$ zh1z|B?ud(%h89^G(iUTCk}^u!<1%?x!Ebkv#DaRdFdPZc*aAwf!jJ%fOBl1!H2_77 z(FQf-+MVm(@`Bqsnksinnf(cSB0|?JzlaP!r5^R$FzWJXBcq!LMz_xpwh$ioS#eNz zX|QYb`Cw6`XnTX?S?X+W)xpJJNMRDEhy>;2ibGOCfdaffjg9;9Z!gAn1J$kTu+VI2 z#5GA!h$$M0qJPLFbqTiO%Q@s`B*7{g3F032LU{zTA_3ewQ zQoPtR?-PPV;XAk97( z5s>EmQn*h!y&oFnu2C``h~RWEE&Gzyr;zhQs7P(v~_Ud3=5a>B7FbxsvU8R$D4&xrrktJZivLdiXzG^Yw) zRqGjAMH9t5?rfp~#C*RdZdyYt#}8}ctGVS^&oaw8WJC^?JQLkIhI@xZqQ3j5AJ^1H z=qs3BC!m|Utu_LC2${lwJeN8>)6gqyI0~fv0wKaELdI1n1=?)&gQSmGwN!;|kD^Tn4NL~2u-rHv)?Qfd8~P99I|``dlgEiO6u5?q~^la~FUbfq8Mvhco((?bnO`>Cxf$b=gF zHGLe&+*f80x+>9=F6)f5s^P+VDaVI-SeIr}F}JT+o@L=Px>@03W+R6zvIj?H$+Nr- zDFe=Qxzyq1lb`%O4H1E>y!h_~&35eBGGP&;JQc$;pyXXFi!v;!7CNbvf=&@l*vg;P zmu@P;L2A;KR!EsS0O7lYX9==vUC3JlM!dEthpm60#wSE(8Ouk+iOs>VKqJ5@#;Kw} z4gMve`#JcDSMPPfl%`Y#WzC!l4BEL(~gLD zqv&MoTOK?fi?_>GhlEs*5|ILmRR4mW?T9Q^l9_k-P2wjJ>O6>eSQtByAs-^J>5l@b z(X?H1F6mKM09b8VteNO-l@5# z-WrsB9$&mJz-B$7;sc8?U0@|B1>)g_KyB=wZZNM1F}h}O@o$)8HLVdjmx}v`k3Jc9 zR>b|a3lJwu)3O>{+F9YIoa_hHo~BwZ*@ZfCi&dlt#pClhcL|2u#W-&_{e4ZR$pEPyberykC zq>NY5+4ak*kSSCISW^-~{$7>2reIrUv0j3qnb>08yV6g>>s$bR5be740u+D> z%tXl24yq-kR)FTzBb~wJfr$$X&ciG5qcDnppMnxb2a-6=s1srDs4K;vW>pzXv8Bs& zml9)RSlzX)6p*s&xJHUUmb46xI;S2 zN$Z?Rr#*Na-`~EwMxDs`Q8QB{$^sB*aP@%rVjQ&HrBi)>qw9uJ=Q#Wn3KDc(*_eMIdsOpV}wgxzTkiTtK>Ndlj0&|4o^JksM&bjxQ z2K7gFd#JXmn|B#mS$N|AsuFL`?iPKV7M7J$L1DV+8DeP0bwxNn&(B}POlk=#Ueaq8 zs|ajtb!s+T$(lS}`v%IfJYD6r>^J=?H{iE$9Y4q}JsRB%n*dFC(LwvRVwU4PgS_(4 za@uW(WbaqHSv`b&rudS;ViG47vh$jIVSE#-{BZjl{c10ye~aycUv0%!`~{a5W*C>E zs{t>rlq7U&HDGdIPVbn0;5?1xq2OXzr5xkMXXEpa++4uoJI-boKva|lYmzIAWV^rFiiRsoh@$h%-6tmm)G6~2VeGYMmH|3N|3-3I0D#65PlxR-=jZd zP~01vtTUC27u7G!vBN8@0th&F`+cSotKo5YF*HpZY8X>Z?Eg$=V)3HdPDx5ekovPS zdrRbyg|+K=!gtn{F(k}n=ADQAcw#0IoQ+yO{Yf=!Tr7xl1zLcrTYk3idFiGhwZwboinFsD%LAe z?elkbiHZ=|Z2@V774o3hb`>#~w0$YnSCxQ_SjmLf?sf9ZHtIMvbP1xRyf;Vz?KFA5n-HDEd!k z@D_tR+($^WUzViUl59(Gq`R8)fH8Ub$(Gcth@?D>){PP$g z*Of&2CqqZ&BBBt;=;VRUqKJJ7qw$l?n~e+G>`3&f>~jK0^J+Og;b)p2To@zVZEG2; z++NhGv_7Kzs`Io)Qu*O`_0YSgPYpa8IrXI=K>=HW?|2qzY)o$7vq4)~m0djB12h1MSPm#)K|jt5TMw}$BQOw_ ztJWQFG>&Bel$%?T(lR1&3ClGn4t0@xnM~~@?1G)O4-2^DJRwj;xEfJL4K-LzOR&W^ zUA8;~{roQ`o|@a$=@yBAw*x?uQUY8cdNbTznU!CB9;gmxpecUcUJ4b~Epy>e2hRd7 znwro9bo;G?Vz-AUv7z-fO{FGAJkM2~)Q49CHVgl}`vu@~!s8=g(1i*mYq|xc%VdC? z^Fz?F??>dTPugyydH2$t>jAvpj{J2su9limi~H<6@ZQPg@?gkTq1*hQIYo`988E^K z_~WRncGq@0!gD;6Og7+v?c2=M^m6CDxMQRMpt8`Z-%yJ4fj6s=9&Zg`Msk)!7)pIg zd-8T(fPld5;pUFnW}%MZe^)B{iyu5AXxEw+h5=^KwovVC5@X0@K6lhK6B{4ebG+Fu zPXn`58E?Mo)GoAR6=jiV*?fh!yY^SM%d#L8jlisjk6*4hz^UVN~uvM zWO{Aw3cb8a^1b;~;<_o2iCpwDT3QSFO&*&QmoZ4$tD||vjtfhDMe`~dmsB)EqaymM zu6Ejd0biFu&5BRwrT(Td+F5rNa7mgqZg?;=4Usgnwl}7xQOQ$wroY z??UofIIz9k;Br1K5Vd3JDG~4VkhYNkPO?yeyBfJVa<32~-^+c$5Xz23)3ZxS4Sad_ z8_|7N#e$#~3a(|G5x+?Yk^^84p~^PJKQSrK(8J%62kLS#E=*#?5$D zF!rt;Da^E!b8s`H$pV<-+W}yN6r*UG<#WqOC3vd9<%DsH)_TM@4WhqN@gwnR(f6#1 ziOFoUjd%7#?)^SJr9@b!+W2K6=zZLEbSh2mfsaxG%KO`D z)-K}@S{DItSL=Ai5pMrc&eBc%uxf;O0~jy)wfsZ;&&j<+XZ81m^VrgKZRk%MdDzBE zI1Mq;TL+=DqnlYg5>qISTZM(3dogL{2_Nz{R5@p2JY~Ynei(m_k@@hvr8xJ2z~^R# zu9F(vjG$9&H)2ahl1?DAgtM!zkV@;+C-@kze|?Wa<+s4oA!JO-~QAfkg#d@c<4% z_K17%^B3A7Jdg0KuWC%{R zrNYq-Xwij*^Doq|YKVoAmeaVEP#8-+WWTZ>Uv-y)U zCL+7}f=-6)S9?W@Hko#|V0pj>gU7Ob{ zh*YoJKZK`ho7C}|@O<-FR#{n8CQ-ftdr|r=wC{+8^h;ZROR@0s-KWFl;+PBcQAGgi z_1N$A{>AHpfMhVK(e8QpIWml!gH&p0hwTnuj*S3Ij(g=NI~yKAjKWdWa&5n{pd7pEGv3k9P2ali&dGsBdsQfrFHaa7PZq2<=Dy@71d@hF z8*<|ukp8?(+M2W{13Sgx40ZO@MoLoI=8S=+{^F~%zWj%!Zn%8KDbfe0QxrL39vtU` zaU);x>VX^)Z;!b<7Lv9cn_2Hm$L+PbzJ-2=_5>ZSK!iGCrGo}$*8EDpS3?sJJy z`%f9KliR7yP*=*yEm_v^5^A6C+6%W&n1`=s8iEdmjA`BkU4@<|^h37B&ApCKW{?F`6d$c*ny##t~PIx1w2XO?r5za;;yhP_=SaIjPn0sNT2rD}o^gi7H^e3hMYVB;V62Bm z-sgxXY6rZsoTy$VxcjE&KXeVFy03r~J(cpUpC}a!e)9!ia+;(P_Vv543PfM*iHI}_^`%i-iqg7`iI-^U3GTh25 zRMeTtY;?Et<8kt`h6U1e%Ke@Rc8o2;lpf+v(oEI)*qC4QJGUfROf%5F?ca+`T=BVF zxWu?@p7Mo-J|DL5CZA_M#Wl%D>%Iz>Od2_^T)|c8p`AJPKsw()E4ylc?Q4 z>kFN(Y`{|Ev(&%#&{_Z$Vba;11msytaYIL#_<%%zRl-0W=WaL0P5YdvAqh2o$yC;` zXOpe2u@&s%)x;%xVFS)93yA-(S(7Y8U;BJ-X><(!ELwQWFw$XZC)71x$Zb*2klLM( za%KuP>|<3%Ah~=uY0Lr8)L;$g!dPIBnLf`J`Loxan9O?27-IQ2g-Jhm72P_lBzgygJf`I>- zOG+*V5It!NEbIhLHA1a;ub8p&xhS5CA@+wX9(yZEaRilMGy8VPH2GxMbBUOfUxcK`BOCqtmr};7d65 z9Dmp9sqgn4XoT_uKD)-Ufi4F)T6$@=u)ZSYy2 z;F4vz$p^WKN&Si)d3lLz*>PJEO@neuIEfu-{l24+Dg26Q4w37X%HPl37@wi0wx2bypxX?n0B}csNO}lJJ=8%wlalU#T?%LwBt5rK zp7T6{nXS^n8m=vjb-OFgHEH%G zFVj`bs2PW15kLlT3jbU&e@M6U%U;oVNWb{mJ;(x6!@Bc!Gq~|YzJu}XT>_RmvxS#Q^W9K=k{|H z-BBa*WJr?}#jg9$f@D9MPB2XhT`6@z^uPe7G;{4%i&oR`+%pX&prwsPWi$*ZCG*iK zH$olfI-)tgmzX#yy~mRVgCL3Lxi(ZH+oOBfg`uu}3F{o|A)zl_ovSVOox0$(>!Bn&b&-J-BcCR|hZ9pcipPfr zVkUK-ZN(3-*|PqaxbL0HP>~=UN7*uwkzXifO)Bb8Oq6p$lTnf;M;wyCC+dgA>4u9> zCEOZ}rL7i-f|Zt(RW@y%0Yj@vmSAf2od&2WK&G-xGrP=bL_uLEkMT`b-Pa<}Z+tf^ zE-Y=XZM44D)05O1{2-a+4r}U4&I>D!&cVwWpockVPolG?0m=p%Pm9GC(BUL7{x zdlFgjfu{h*i;`=cs1!4j&bMF~hLVZ}K^u|cw*pFkX`(}hd_>>ljn-sPB(L5mNETMr zA=6VYvvB|PSIc*WRQbzufMx2thYdgsCa^S(!^o*C16|bXOGc^A4J6)PZRp&E^`wj@ zQJMdBX>cawEH9NY-DiiPwG75c4!`%X&$mN*3ae<$079QBG7h^A3(OKYuu@fglji75WbFA>*9sm zrHd70g$&KMH%$JcofCB8Mzd3FwtqP11rvOC5;3yVHBj^R%I39AXRFLp33}oC^)i9K^4myZuwz-%!`zR$=p>-G+0yRBPNGZBt)rpjL|f5YYIbcP{A$ z2DNuo;<;X^RBG4wFcX%}hucjob}~g0rkzjG@dfM|yQVn?cPsT%YiUtr2l1OVm4cjPM+94`Tq*#g$r4ITbq{dp2@U zC)=I=++KABGfh<#+DyfQ#>HPm1bV&3pU3B(%x4rz?{5ENAdJK4+8HxqlvW$LoLy zDO<}z+o`fLTK}%X(I=#*2A7-8hR^D!)owrF#>*u7Y8WAf8y zoa6b%$TW@FV-FY&Z+YtDGDcozQ(Q%JoGZyw#r#SaT;=j{F;p?_JGij=eYctodm^)H^nbUeq_scVGB=}UoV}@?_V`K==>Ive*@2!8M5zoXU~ca z)RjK0za(bGp7J&zDu|SLTK{%jq7N{&x^W-Bza&G+`sjt<-0DUUKXymGT<@yLJjF*R zA=5qac#iv4GudV3#~z3>%)&c2)Luelm#x9UPSe>silg6`@)x$upy z#yt!4bA-}3;~Q-8&u%t1+Bim#%Q}c+J$N#D@;9tl&G>2Nsc<;wCh+9Di0*7Y-k-W< za=Dj^s8wglF6n&*`}VZdoo6x}?cOQ|?{avF=W;fW`L(ShJi59gc(U4M2r#ajJlC<- zTC9r_>oSHa?clF!ROE;CF^QIvD04Fs3-ss_#HhS9e z-bk?%3fEywQ@4twKk-+7lO@S8PTzQULjPrNn0gC}KjkRT+_5o6Q$bnO zn1)osc}k4Pm54^^2#F%uQ%fsaeVfN@P)x8dt#bSW)w+RqVZ+|c(p?Bv?ZUcu7vF3K z_Na%`hNiVVr#`Zbq`|J}yQiOGrd8XR;sR)HDGo%C08mVpBKgA#6Zp-&odLijl0-c? z=N>YhA0du|$b7smQOc-28Zi`}Ee0B!>d;ncTo{(Y*0vjA5_$u=w17Mz9xFArIn7O; z4+&G=AMRvdS+XRxy$o z(Jff+7=((xPTS^?{2XUwUx)!JOlnDBQu*pxmD} zCn&e7Ov%YgWOv~|0x{1#Q(HhSHW0W46D3TfOw=REU}?_BzJly~6uc{Rl0PC@mEj(h zg$&qX?`>>hM{vOHH)crG?4ADPqhrl0Ism&OwR8Z;n&UDR{bO1gMj7?6(()lV9I=U# zIZ7bHZrq5gIuUwcjSkY9i2ZHN!U*2vxv^gMN3SX^ekV{NBY1#jJGUmDcF0L33ek6dsWe}iNn z-{w4twq9OEZ%!8UoE~+rHW8Sf_^cK68fj~Gf4~1tph{7jJ=+umkS5ZUcw$qO(JoLY z%_2Tu|A9nW-Q&9omhPCQ6rO9b98Od072dydAqsl3_D(B@upQgrjqBkC z8W}JR8?@JdS?<<>dhI_&H|$r{>e`{iB{bdQ?}W%@orJO1cd)reqvKY^^im3H{&-9PSyt8Y|i=CY~XEv81 z&q%!=*gK1De@`;~wCqTuO#DU=6y-#87~+B-5)+h64a9`Sxv|lDA&qwfR(R+csCR>{ zmSh>bW&u#NlqK&;L_p>(4)gTqjj)Wt3{yZ6-Gn&ak~lrtA=lEbLc%LD>b99L^1~Vx!tVAlo&RYJ zlB{G6bHKWDENU3Li20*#EDV3oGP=QBr+>+IDbuf>JQL7>llY?$`#LqVW+Ihub`1Sm zvAn-B{jRHsrLu~wMiE^>hj>_H%6)l!IDKVDJXM_b4XK^en5S<#0D)V#RsnXUz;K;qSsf#%T2v9eu5ERtRo#r;4|g+k(CKB|_wytEX1DKubQX|Srx*H=VniR?yO-O| z(QCHFI+4(eZiRsxA{Om8+wZ3m|D=#A!l2=)Oa?#OX7DBzSHaz$2Mp#9UkPbZMo30U zyz6&9TnWyZJGF8d_2g(Ac*Y4-_Z)9@dX>+s>jIL2nio{WTa6d42Q{Tk`KGR3*vkgs zBR2CnE3Z6xX#8C*{ofZ$IB{!+^-2A%$>BYGee|nan=76VTPf zKc&dWQBpD5HIqv%X-6W2AT{7r@S>qx&P zejCc78s?A$b@(v*emlSRdd6!!2A|yqS(5ovf6I4LEf-$m_VxTN0=%Hz8w^t#cnYD< zaDK`JmkM1d7qLt*D?t>K<5*UA=e#6`0dwqK9dZ0z4qpfq3Io3VMswafDsLe7Du7+4 z7+ivq)~5+|`w|F~(i!UfCz{s_8oXM4FtA){vi1aV;1rIZa|QEXh=-4{41H@-I5mED zBi}IMFt)t~i1(@XKl|j!w)TlIzqO)8-cfI5RvY1lUdC4#oEQ!0@MiDi{)b;%9HEX;&hBOX!6z#)oCAe~{2T@Ta= z#v6$`h0V%K`p3>f(lst;rA78()`+gbI-xu4fuGZA4vh1X)G-zICwO)14h+|~-?H#N z!{?GOKlbATfBS?o&0A$lVyf)x>2l*5iG6KM6W<+;p4Qd#yztr!L5&4wUzSL!U}v@< zw6eK2@+ZdWa6#XQ*GsCaf;cUh%7kUm9`?nT!6E5fC!tkVQmkex0Yrve^rer?iErCl zv)vaWZ>?`PJ`)xR0{LCK^S%-He`X;}`gM>n=BR<~SvjhLxBMRC2Q7$rGF`1HJ(C?P zQ!N>8W{S*v%fRYnl|5reB+qpgfMnc;I_c5j{Ujc?CqmD(6D8n1_-y#=?C(+e2O_b% zXGa9Uw-9>WEP*6{jByZEU)tN^^a+V)igtUk(dAFO7ichONl85py0H!a_I9tNTr;mK zn)zf@shA~5M;%Jtj@_Ez`}aaiOQpOnXpcNOYpCDqJ(pJYEr$5b-x#?K_Y@)$l9%p5MAP(>0?@3gm~O)(Xgls=c?98C$lEnP|>R)}~%T^5}tz;lfWthIh2 zx4lAI9{*KMZ9c+q`fQ!-IzHbk=J+k@qi^?125a~Mj+T=nwY)I^1k$q{p?-(u~0ej@VtIVtvGlL#}8V!kFDZbNTk@D9Tb=Fs12p+T3FQKhKn_ z?hqiPH8lfNd=MP6E1~BXuNd!dv&m&1g)VK9MaICP4aV5mSu~HqM0*F1&f6*1zC~2~q7E{S73$-1icksg#B9 zSlwdnfY&IVWX(5OVmVwr`wlEYIM6~*@UE3lXd#Q0eX#_aTWd*84!qkj?#+f7GKjs8 zE{eP@w1)jxU^#79d_mgx$c?$B{P*T(Hq$U1^K+ygb4FMJ>^O+@m6T^15hd1-zoSiO zef1dF&L15y4=|47VHB^)AKHV-xq0ykwz_zU&Vo)M=%x}aR2<`|+7zc_*0IpD&`fdr z7XE5e`4HFj7#Nn^8%&#K!mB1(O#4n4M-ACH+gi}bVtK4}H=$MZN$hb&4Cg_mZEFCt z8%6(j9+j_d6f=(e#-BAXY}uWl&)XQ$Q86R)Bc$VHiCss5zs)ua;!C<5~Zwz7+Z;J{Cut5uM;Cs zbHy{ZSY+wFgQ7SU5HFz$Ba0VJM)+R$*O+DCm*KFu-uTL`*1zvMGPyRm7+`hYTuf*1 z5#{=k{@FuY3rX%u@w#H))L_xzl>@pi-JeR{t@FiD!?n0m0!jDPOYd!GB#UgKULlUz zpeVDYQp0y{qe+@mpXl0Wz9EZ3EW;B45*i2tMUsRp=xd)df+MHJ)JmeDiE5MS&a&ro zs)GmKHhB*$-bI8YC>D$>Eq2^ZeK!n}`OtVoKPTA1ClG~LBhWL5hiAALLLmp5=2n|M zw2;6;_+2A35KXp!QG6YDm^bC{MY0pF6{yIdsmT{71*eH}gtbs^;pt}fNDO}xK-CSO>^ zFT?!HpLzOSp+v%ES6$d?bF@Dc;XpOf8_qJUS=G=74?Ie&p}j9&#VBPifkVnuc6q2K z@`IEozbuM{$XV}KJ7$zdBP38lHT@~x2_e+TY7@k< zTV5*H^9v>@XuxSK=bT%ZK@A5bXSe5jBIOkmbaXIuu(z9*6?fEHy88;IyL8#TpW5cK z7sK*U*B`nwDY%@hz#Z0D|C=J1L+FDK4o?bw*&f@LVE0ReqPX*$(Dmr1c{GqSZxNoix z!kiUV*b5glwMGrU^Fip2F~W|_orPt22d2w)mQ|B)_DTPr>`6rvKYJ(A7WLzasMrOt zk*Nq*{7&v#X}3DIrVW&PF*$-w`)_-Gn0T%J@F2b0na~Za31Q-}i-s$nLhozn_GJ0qqBen+8P{(b4ZY_2A`T2y8$urEgqN|81Rinr{OY4=7oozJOp1XQdiAx>6wAKo0Akcco016F)uPzkM3XzJohn?) zkpN6U6)x4X69e>gpJLvYWG0J`OV;E}Qc%VG%@?usRCS@&etH zL!y++|1+ono>9buTc$LH0MFBO^0b2$ml!TeU}Xv}tyPuuSaC{8)?W_Gm^(b3Lmi!) z4vU4lo<3>tt6tNby+Wca3t@-7p8*uIU8t%MB6S^wLQljv;XuS_?|}XuWHd=1zzfFm zBV8S_X7&((W-xyvZ2Ma8eH^pz)PR;l7_~n^vp~vPEo(NdE}MAvT^q%>2vdj9cYo{` z2uxoqYZL`g__nZox2nE;6!fT9YhTa3$G{4OC}nTH;J1et=x@6&eaMNp6)=jhyebR7{Ax*5E6htI zah4X=GEfKA%>d}ZmZjwy`QZQ+Xle(kYlviTbibw}m*>1qX~oVQ7GYVDmNu}c{7aSm z2)%QNywnjF4I57CXnFXvUA)16^A}iIBP1x8+!QwZC*k<)qae@SMgA0xtyc8$F+fr# z!gP|4i~X`*g~Lr&EC)i!XY-4^s(%k`^)^Kg@p~WzDLs4tX`W(de&xWR3ZLpbt(ov) zV}8lt7Zcy-veM5f&~bs6||Ze zATYrOg9$3c{Gf!Aw>iF(h$Q0%!H1YFUnuuMPejS6F}*8Uf%%Cn(2)X9t2@1e5~@_m z-S4wHPgi0vPdrH-6s4#M7HBjXl6h2t(=Ug&F96R>Z+%^q+s!zCH~buX24S%Lh+=lR1L+=*U?PvieYy%U|e?F8Oz9*Z9)BeowchfH7CUK9rp|ouMKgsT; znze;?YqEu)9t>ka&o97RpF(Ib`tF^)UqQN5`7bZ9FheOu;a049Z@wC0L}d z%X+STrxp^SUS<`~KZBvx500R&Xq9bv#l8AlpY%H|s%evI`JJwizgqgoEN!8H^Daz` ztk*^loL1}vElA(#OX(9K=tq@Q>iM5J4U!LB+5Fk^#Hl2gDtISWn5NgPku3R;1 zLAi6M0GEZ!db%VaO!D)}j&`B1%`jhtdATveopODA$({Y+EtXP*MF81b-W-$Hz#yp* z0GoyeT)IKA8Uileh1FS;4vH#lpMemK@gyHx$;UU*kd663wSjr3gc3{shi??A3vN6T z{Gsal$kwxe)g`SJ?$_w2X)0qlW5(D31|1%1H>A=Tv#u0LMRI0p^$%82l3YZ*D9nyu zy}0sx{ZK-RD87y5++)ZKuYw+S^RLwy+17^k6C+@Eb18>*a&L=nIBfJ$lcAKW6_VW`B+v zWZ4KdqwZ#!2V#FET9;iLXZV79kJ?;k-GQfz?7k+78CmzTT*}lQQ(O)sT*lDPc5EhG z#x_7D{ne0xbP>!kdeu^fsY3c67d7E>j7{ZoFMY`8b&QHdWo0L7*qr6H)8Xk*jq3R1 zL{&{cM%a?(95;R2uMEJaP~lQgiQKG^+VWK^L?22%s@i513d+6umh@FU1c7G1WoV-$ z%yE-Wer!3zZ7(gALPddr6qhfh@BV7H$daCsNg}fj6-*7`uK!#oU9<6r^yMjWoZaWDu>mlm97D49L|J*$ ztoF`nc&|U>lE88@DDy{L4TH3+E$e3@0<%X*2>whB-yrIF!t~p->mWMeQhC57RG7MQ zEMsem$$l?!jQQN$H^w4iEkO2{ak(($k7lj$|4uYo@2Z#|CBveUi6Z>u6S47r4eleO zfRr-3%>3>N2!y&1zXU?)Ev4etNdCV4B9RHKVeWn+offOv87eD#DVF>CRJ)vuesGYK z`yzD-Ev2epao>cYULQ$a8p9H?(>=-)-AAfDoIEU@s+zK@bb7~}eVQ|}JMNVi1Av|i zmJ(&Rw26q4sGPB2NYVf7$5wWWf;$wV%0>>Kmd#K}8xhQ*ZQ_csH)?JJ()z|x%*Wlo z<~`Ed<9bI4QJa1y{n+}bKW#!dzMiuCHqmv>##s66W+x05yaXS$bVz|UbhYLyhC?=se zmM=fL(bNMIs77wc0c&1V%dTAN4vXZ|&(_pBlQPKz&9b$Rgd=~sk}P;X)mmX;S_|MH z@zy6g@R60pk0t$W$f*UV0{~IV`XEvrUT%~;(cbYz*AN^#TI9+z)g@#Yrr!D3l5jIw z6JMbQsQsj>WrkddOU_cYz5{@z+R(7u0MHdqvV7ODA&xts3Dn3hk&{v*WSlWfi=Uw` zgtaK+@Lew0Gt!Hx=7miI@v9Ii$Cfmv>99fH)5&XP^}^bJ+C#p7k3)ZGvOKv*d>|*r z=nuXX{^0!p} zd#=GCqXHN?8-Xv|PDo)t2|@#ND&SP+rRuDuZMhj09Ml%d81m*s&8_RTU=)5p!MV(} zAc*A?Irtb_Ce7%XJx80raR2a68p)G>riL5_coHR zA8f^X9quXT{Mdk%XqXmKfj!)1%z$94mo3vSvLG)6%mee-o2dBVPVA85h=V_>X)!Wj zd0{opZ8<|6(#4byYWcOb$VwXUk1d~-(3EWK9C{0iX@!Gc5fgGT9NzHq(R}Y>_`^Yq zY(CeZeod|fGBK+IC!kc|C(?y-*MbiC^f5cvGJ}cIzI`{GYI@BUoxDM~LCc~aj*HvS z2$6!y&&{JYx-s^a^NwzvmGDr6fWAvbs+vJhtD$<>s--psG!AZcdimG3-fV38KIVp8-Uw(X!L_^her;@iQb2LrVk`)3P>2gaI)t>WDFcSW^ z51d(DN7&6Ji|-o}Imr8W0FN&+js5knzu71stm4NBx<1W7N zIli(yUQ+@~j!KHrK2%FsT&ri@XN=j5*G* zeDvVaoKMz>a!=-0U4HL-Y*u5z2%^QB?epwaAD4e0-AMPgoRmMGi?k#NIc&zAq`N-7 zB4te~0a33b-&io{}@sG)d-Etvd!PbHE@E$fhU*`eFO0DbeyDtE2El}5JXl; ztR4z8MbvyOc}+j;LiOKU@STy@+r$x*nh{c+Jb8a!ris7c1}aV6>lrGhNjF(ge8g5? zPBnkWWbd9<4V673M47uzEFX0blx}*I%Tnp6p+-xeLPlvS z9@`ow83}VVLej-uHFFY)i7=FOwz=8phsN^RR8-!^9Xzyu5C7itm5iqA1j6P)ql41I zl@&u1@;ucVbK7Q8pI9+Q;hT&S>cMDP?hczz(b8GkqP+ukv?14iSxnk|Uuj*^*fd)- z^u}5ZDAhw_Vig7?Sy&-~4S|i4vVrR?HN7I1IHZhBR}lGuks6J>Z-)AL;rYls@)h&+ zHJSzaO`qpaSM2f2p9SaU%LMKKgiG&(gYfrjgv;*sW`F83Wt7lt>?#*0t?0oz-(&xC zDucTKP_&*yIMhtVk{Xzny7xQj&D;F7a2kKD8*dPe092cM_a#au^uvd5ALJy(HTppB zZvt2d=zpW2i$lA$#E>(~Nr*qzqoD~?)E{RRg+A0Zc>8AqczYPstQ(XVH7Qc zW6wSIi0_wSsmJABc^cYrA1=#K>D2ShopX5H7sOTEgrwoNwjle8o8e4B8+z8t<^Pek ze_AFYEP?YmLi0YI&1$;oQMTZ-h8PGFO0>m zjZHjHe|C&gmlLgKSvk?2$Gu&ixe-IZB~4bKyxygp+0Z)^;cJ6GQefQv-xl&{qWLB7 zrJd^XU8eqz_m*C4jt}-M?#uRS7^%<2?ugGz%6mqe4bk7DC$l{deN;kckoa!ATL{l? z`v+!&++hX8%~uodji8snfX9oEK5u8iyK&wxJ5=`wcbCh4k20InhmWJ1e_Ekd?bAP) z*+SjpG+GhqLV5P-i+@@b@H*a`Co_Z|&6kK!2R?R|Ep__S040cBSo@%>ZzKM#q60;Z(J(r}+OCJ+AcEmc)pXLNmk})882B7A_ifCCP;z~1# z#nEGW86}L8klKE!(Dfa3D4B(bvQz)r3RZ}GeG}I<$V&D`06Nz1l=a#S$1XvWZ8Q#% zJb{yiWQ9tO9m&>Z#8TfxK@SRkB*=Upfc1)nT`(wIVgvptAf3s+OF9R3LU^gBr@x_8 z`n*&{LQx)w3ZFokUjg=?uyI-bn|BGAl|^77Rq~D^G}3_Ts8cj7pgU*bY#Ojw{x|^h zMY$1agnc7MURE#ano<7i4Bqb994oLjxA;kzLcyX@)>sap)7t{|sJ%KQAv(*jM#-us z(dS!&_=v{tWu678W~Ok|LP#UguB3pH?CR#dNu*>EvHh@FNhf8}Ytp|3?A;hNQbqJkYWevc$zS!VC83kxO5%Zmf#I>h$QN(t z-Gw;&7PoC`JQG_a%t(|Q@j|h7_a_K8zU<@!Yj^nn5RY5fUl)^j&t^~`niYhXCcBqqu;akd9?DA~Vc~?#V z(*11dz;~QEyeyf(ZQVJXoY3-HWDT&lnz8=y7;^4hI#;UCjA{s79N1@0QdQ!?PS{Bu zNtklZr}uH+l_X*m(N`~~e}OG^IKQr!R@iUu+sdFHcG-N3aZ&GCIlMuQQ}6sJtwEX1 z7VrdU`AGsp*P4;gRc{&el~9?H$hEG6lrFLkUYev%;e^1>0$l1M-#4-h zMWK(oz+Uds1|hVLsc@|>gg=n;03#>fw)LiI6D-Qx2{ez{yK0y9ev%FX6Nd5Fr7o1K z7ONMiR{^W!zYM6R442nHrTi1&&(dv?kxHo30kEeDt(!B7lhe?f(!1;!Af;1UG(re> z`;0?irjlB%V4QF?vdHaEFQ%_s;`l>wX@72@k+u^yO~EoDcLT$4RrfK>M#Rz61)v-i z*a>M_%di-{FtdVp7G^#CSQ;@Ypz}OZmvhRy;q3`ubi&!yNQq7tGg2tLvV*4)ro8Ff zGOX5fG#dU=yLZJKG>+{QsT)oKVm_*kzf{4O7E2HTvh-sCXuB$C*T0!_6sj0Is03U!YvS8B=qY$dky)M-S=*8zJ93bykXcN;U}Q_ zTiJsUN|*n&neR{8SM841bm;xbtnr`LG2@os$8%*wf}ZEmPQhp22|72Weoy9I3SN@j zpBcyfCfCnW@|Nd1<-%;69u11%s z_H~_K?W0p9(zWFGUIYfU5ZMGYDL)`AXNs9CB@cmheZ9-msenOu08Vqwde1u1gUiGD zCt;t&n6(ZVY;4?u(o$?1ntghd^AyoM{7~=GOwC zrY2hIC}V0GgPMW*=z9j!?>GMkm%D44`&NQs`FLqJiw|Zn>lo+eQ~nN(GA%!8UIZXt zKukQLc+e&@Noa)nBvjb22&}_hL8gyP6Z+z77BvXFN-PaIGX*V??q9y^Ry`Z>^zGxP z8&qNXo4m<{6v>&Y5yp%nh{Soz_JcJ{kglVDw5BxVOP_aSwo96*AyFVPb2#GsH36y0 zeAJ`E{*2(eY{E_h$y(ydmwq`tklH?gmx71^sd_Pc-q{o6#w6E9P-HuNh@$vz65UF$ zGX-e)UFq;jCXIWK=5(@RuKOEp?DuFh^4TYl;WAn2N4CDwzAOV zrchXpth|P|NW=6TrmvFmlOvIcYcS(ck2$6;O;TS{bPGY2d*X@Jqdw5&vcqqLR_AQL z0_6+YXSgl)G|9jAAq|!V&`j>7@0ytkRI7JayV0C$YfyIA5$?~=t8y~h*{SO4$Jp__ zWS5zD%b=mzm~cmNBaaQj1E6s@lq8we{!lZz4eD-RR2? z6Mytu;84tN!xCfrJk(Ol)UYcPpOv6QbaA~mUk=vI_?InH;V%EQ$p}GY#PfIxqL@5( z?3D-=(V?;5>3ScNYiV|+Q$BG7&3cQ~x!>D*eijJE4S})_)I;V;uf^_j2Fa2-0JaKH zZY((guz?ODYZu9R;0ucj4QRb`6u$s>mHM^?#13CDsO22I2eGgLPaA295uZ>)Zw-pR z%fCA_2RHry+%+d=)#s|B&}om?_ysf&+e99HEVU9$;&J9ixT{0?wNfz1fvD%lBe z6^0x^#aPmcO@o(mfARVHFu8&edjW6MucZfZi~pVkHhgYaUUzdvuAYCAZC$MUZ}q)@ zWxrlUd$f7f_IbK+-r1ityu2PG`BQ6-;BmZ$3EhoKN5mU0KQkTPFKTn#%`ReedBW~Y zbPsKOIx*efj!P~4k~I?B$MG*k$N6V$Xj%_M^c=OMz{;f=5?&KSv?lUeJ4*v2bV>!8 zriDK-P_G^0L93p09Y&Px&%R~HHbm_0oW+z?Q4;qV^aNS1OBnzM_w>e>ngiuFWehAyg1?gUV$;hU_R+hm$vx?$Z zk?D8gklc~}){kYpNDV2qh~Jefa_0@W7fGUT5{r(@%e>ZcuM3Y938PSG$#0@@ANgIA@|6!3q7Y8n%hXd zpxi=q_HA|h%tfRDjTJ%8$}uzobK(pAc>JNS!I#5XnlvFox6-4I=GJfIHK>hotD%mv zsb_}iZmFh>=T<1qK^qD;u}K;iI|jDqmBQ4Em^VxcYWe2E@UtTRpr zR43vL%75p#4CFqsg2j5`qNNQOss{&FTlrJK(Us)>7J|+LNUN6ojxSh~ORur+u`%&X zu6+t*4?r&}u?>7F0$zIIvzXrc5PDIv=;Sd>`tG!E(L!aVzKL*}=LB=OM&ad;jK}gd z1zoSSgp5uFwa2W4_M~4l^?wJYMK4b&6Z{}#@^P+u4reSqVazLM5HI2+E20^oXV#=_ zj{Q-uy%pq2DZgeaR=?;YRwGZx}jBpDb? zl}eZ;eF5gRWy0X>+-O9OX;RQOBy5Hw)n3 zU#N#Gq#J+m#gv3!bR4yp6WaXA zC-;{4Beo&7Q|8xKQ5z1?=ff%O3 zo$%Gl>f6=BqOr_Fv;S5c-{#QC#VZjRT1IrzrW0`L%Kb{rxic!g-Ag(`+3-)E1YOr@ zsqO(%rPDfl-T@Qh0#Tesy)$Ie1V@YXI>guqo7H-tkAWWr!GLq?92+hyh3~uL*_Mq} zT*1(K?GQ5tN>x5&gz~dKadPdX2$DbX&Xxl~=!bS{>M-jqKQF*F8>7n!kU3e|@Ehd` z?hBbU@=V_vTnNs1R|mXqJzMSHVPtmcveZy3x|CWJIp`^nb2kYGuRf+@ zCk|%XDyA|Q#>%OM@!$i+%rZX5c~j(rn|NijyZceLG^gv6Wd86frmN^Z%*K5rP2T=8 zbG=z99kvkeMA`~07TdnNbY%kk#FPGT<-ZRj49Oaj#5{uO4lyrsqwfwF;xiMANNVq_sM?YUZB)E-C|AhA)RN)kG`z&NNNUikuy3S6 zGHXhHAS{KT#p8;w+Mp|hXz^le@(jVpMGU&VsemL{lvz5;$(7RSxVk=jImO{^O@WTKjeynWS(?&;J3?A#2q#aCqE_*+`Kh<}UdRYL-;8?dd_al>JyDoXMpQ)`C zYa#SzYS|AGD)5~|2}71s9$O)n{DcazSo)+%`tpDaq0aNA0Fkn_@0X{a%1K>M8V%^W zOPl)>#Rxm=plqTpDTr-C(xxjRhF(oEsq|X74TV%%XgkOP!FWcL4C{D$U~pQeH?Bz2zLDVVsaA+OVbwFzFfT zT%GFnm2;!})Z!NoCyN%v*`+}tfwIhVwVdn*Cnke_F@^h-g9X_;DcwZyZ{79*{tE~) z94XrH=Ctk{uA!voHjM_3p}6I_t;U*2&!Bhjv6OFmd9{yhP^^pNX*g> zkAPSRP?&Zt1)ofZ*J=L*UMU^!U2k$iAYrgq$b3$J^1nPf8P?*x>*EJSGZ7_|q|!$f z=;gv-3_#dzgc6S-7@O_*Jty42WF+BVv+9m~j*I=t{K9F(|EXQ?SKlu0#loR_y17-q z4WA*nNPvRI$r0?y4Ef^dy4@^H* z?6T@OAI3cS134~qsCjj%%}W&En|w;P6U~_o;v@RreDDp{0GL=mqlNI2ll-|*4p-J9<$@Lsr9Nhu$K+1O_jddR7TsyI3P{T(|4wu$A%y^3AWh8a!qIC%dII8$YB&a2lfZX@#e+=#P-1CMEBmU#M>!bk2J8UHa@ymYfkj4}AK{={@* zKmN-N71JCqRUZ`Fa(XeoepnxJ)?t*Z9#L6~f7K&NJ+g6VGJZg8&XipjPLU`&bJi@u z5T=8v-RJ!=Xv!Dk`C3c-OS6;hv&Q;CemQwJ?10q1fd<1^#WLQeUO3_WsRGAHxgO(7 zg`}1`z24(2vSIh8Iggn~VXevE3 zz2xNjYK!X=%%nvzISVVX9I{vrbBxIpOK<3p4t?OZJQv^xRqt}L1Siv4$S6`Arh`gd z)UzImI25l4T=vUYR|C1(4&2vUMuu|GEr~DD71n|>UrKAR^M40*W;$9f~4aLgQ-?CguW69LwI9c?eTSHCPrBW9%yB+1B5w3abq!It)Tux2yPJVPderQD zF~4aS>@tEirTY|hp#xDuMq>d+>oJOCC2446<1R+E*hfr#T1v0g^jM_GWxaW{3~pVg-MOlto%*sNB0dWgh2yp&$UKr{~9`DZmVP)obY8dg5+4sdP#aAVVV(gKKIc=q1De*U6V zebSY)doWHgG9LKWpOBozKZ-odz`{mr>?cyB#fPOoO}*F&xMq}8rgE@L*CF|e_=bG4 zdc{)OM`x_cL`4Y!{dSwe!PJ@Y@Zzan*5qW>1@l{I4lh}!ndhp78~T;SD(NBdmJR4^ zGA7r`GxQ%@QKa#qKolp_Yh`h7!j=l@_tV_%Fj;NkT1xhJGu6JSXnpJgd|ZA4?d@SD zrK@-ZeRPEjE8I^{)YSnxsUi7F4XiOFZyXFrVWUK88UZz>2s||{x#u(*D3r9*zb>XJ z(^J+QpD`KGzO}}%;0v2^bs7;#)bPP`zSOfYKQAQ8ksY!7R*QZWRibFOI=C+7R&f4{e-(mMCFx_2^8%egU6 zS4Mn^m00$iNZ?wj&d92jxrpU?sd;pnq{RRC&4e?BQZ@>ON@qK)S8AC36Y#77sc}BJ zMKR-yrq^K-;N+W(abph3Af=wO5bKd{N90@*hxFhAQTedkJPWv4Fc`v#E*JGxZWL zkb>E~zrP71p=)5^5X&m+AR17_QxvmhUsArN!al^5(KZg3%S2Vmj4*?tKd1>7 zZ(Ce9g+eLMFOpW8+KZ}cY7`>zlx}sLa!Sh7qMV9dbQ`Q*EqXt5c47UQ{{Yutgj`d%wQ50bNQr3s$s9L{VkcuP^f zNJ+icEXchv!}Mz8?;WMhjVjfKGq*qN>EArwN4T}sv>F^)2d};3ej=~j4t?<{buSahH5*DJMUJ_=`R6Z z6lxSfpiEMlol|79_({5ee~JOkNsfPMML5@n!U0Q{w{uXT(oG&kN-9o~y!nZM-kFWGhpRVz`cS-*K#cM$0M`>-7!=lnjVuc1XJ8}xxH95YnV$h$R7%1|m~q>Rf7=lk~N*^nwD z*(BPiNX%5yJVOHnF=_f_695`eODuA;8pa66)6=SH@$Y4B)- z+%|{9SZw!%@)wK6S3SRZVsm}tr8e8@Op2Jk9uTnGEYTXh3{mFJKENNh`ic zYUAq6it z`bYrnmbEy)y5WL5(da$G##gAP5C~5xe%o}%c5jP9l~Fr5-2g>FmYFTv&_~|q@O<#? z_@gjt!me$=N3ySm9g>n72xYe)(qO1MXaXu@uWEUFw0o!i5_V~67g_o}>JSdAk10el zp>R~KEzWkJp->UH5)*K+ko3(S|KK+2(WHDd4*7Ytf6B^?Y zy~0+H9x{YQFnu&S2O)~%Y{_Uqz7yq%uSFu#u<}NO9(9tjuw*-ZQ({-kEJ{%1z*0{4 zB5i3Mb?|c+7iYC7nmNAbezs}A+%q4~Ns}v2*Ov0s5YwKEC*YJR( z6d?bycX3^7x$}>ralDZ`drNHRyA-h}n@R8;b3DAYYZoJbL=33n_f`it3(Kt7Y<$Xw zt!?gCH|&&B92&|-jbTh}H&|_=^otSZpJNfVT^^;KHva7nc6~rr;u>sqD{Dy#FUvyk zQKpC^{ee^=_=~_gZ?F->c$r1*JcAx1>;T=21*97hA4-`#E`3nRTt{4!(|^_GK~}i< zD$xx?K zo0nBI<>_g5SAF!|wf6Y_2TBbOe72{IXYO@AAU5Dr95mh6(KT9ThGNI-Ty+AuK8}IS zA&*)+Kc{sRX1yxtwjf@V%Jy_yEq28B6=MCaXZTs&WC>&8S1te8k#b39uQo+Ozmb&y zTI`X<+e_pXXuWBmwr~XrveG)@r#iOh!%Z>*q#1Ar7YpZJ{1gm9dX_Y3?DM~ZB4s)`g6~rVs1eM4Y=94AGn`+Pwa_D9ZSebzn z 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

al27;}+$X}DJP@;G~!A?XZ18yj43yQbd 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 B5|01? literal 0 HcmV?d00001 From a72cadfdbb47a24d56442a22a86ae37e68629432 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:09:20 +0900 Subject: [PATCH 138/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20my=5Fstudy=20i?= =?UTF-8?q?d=EB=A1=9C=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20api=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/my_studies.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/app/api/my_studies.py b/app/api/my_studies.py index 6879c2c..c3fcd54 100644 --- a/app/api/my_studies.py +++ b/app/api/my_studies.py @@ -60,3 +60,41 @@ def get_my_studies(date: str, user_id: int, db: Session = Depends(get_db)): finally: db.close() + + +@router.get( + '/{my_study_id}', + responses = { + 200: { + "model": GetMyStudiesResponse, + "description": "마이스터디 조회 성공" + }, + 500: { + "model": ErrorResponseBase, + "description": "서버에서 잡지 못한 에러" + } + } +) +def get_my_studies(my_study_id: int, db: Session = Depends(get_db)): + try: + data = my_studies.get_by_id(db, my_study_id) + return JSONResponse( + status_code = status.HTTP_200_OK, + content = {'data': data} + ) + + except NoSuchElementException: + return JSONResponse( + status_code = status.HTTP_200_OK, + content = {'data': []} + ) + + except Exception as error: + print(traceback.print_exc()) + return JSONResponse( + status_code = status.HTTP_500_INTERNAL_SERVER_ERROR, + content = {'detail': f'server error: {error}'} + ) + + finally: + db.close() From bb86e77881fdbe26f0777f79b294b3cbf84df028 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:10:00 +0900 Subject: [PATCH 139/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20my=5Fstudy=20i?= =?UTF-8?q?d=EB=A1=9C=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20repo=20meth?= =?UTF-8?q?od=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/my_studies.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/crud/my_studies.py b/app/crud/my_studies.py index eee6bed..7fe8c10 100644 --- a/app/crud/my_studies.py +++ b/app/crud/my_studies.py @@ -52,11 +52,37 @@ def get(self, db: Session, date: str, user_id: int): else: raise NoSuchElementException(message='not found') + def get_by_id(self, db: Session, my_study_id: int): + try: + data = db.query(self.model).filter( + self.model.id == my_study_id + ).outerjoin( + Reports, + Reports.id == self.model.report_id + ).with_entities( + self.model.id, + Reports.date.label('date'), + self.model.total_time + ).first() + + return jsonable_encoder(data) + + except ValueError: + raise NoSuchElementException(message='not found') + + + def create(self, db: Session, room_id: str, report_id: int): try: if not room_id: raise NoSuchElementException(message='not found') + study_room = db.query(StudyRooms).filter( + StudyRooms.id == UUID(room_id) + ).first() + + study_room.current_join_counts += 1 + instance = self.model( study_room_id = UUID(room_id), report_id = report_id, From 9db01674be300743e1ebdcdfc201fe1c8dcde08c Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:10:21 +0900 Subject: [PATCH 140/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20redis=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20=EC=84=A4=EC=A0=95=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/core/config.py b/app/core/config.py index f668a32..66d05ad 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -76,7 +76,7 @@ class TimeSettings(BaseSettings): KST = timedelta(hours=9) class RedisSettings(BaseSettings): - HOST = "https://api.studeep.com" + HOST = "27.96.131.49" PORT = 6000 From 8713e9994773fad2ab348f1a0e92cd97974532e7 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:12:11 +0900 Subject: [PATCH 141/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20study=5Froom?= =?UTF-8?q?=20join=20check=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 방 주인은 비밀번호 입력 안해도 됨 --- app/api/study_rooms.py | 16 ++++++++-- app/crud/study_rooms.py | 49 ++++++++++++++++++----------- app/schemas/__init__.py | 3 +- app/schemas/study_rooms/__init__.py | 3 +- app/schemas/study_rooms/crud.py | 2 +- app/schemas/study_rooms/handling.py | 19 ++++++++++- 6 files changed, 67 insertions(+), 25 deletions(-) diff --git a/app/api/study_rooms.py b/app/api/study_rooms.py index caad65f..596457e 100644 --- a/app/api/study_rooms.py +++ b/app/api/study_rooms.py @@ -27,13 +27,15 @@ MethodNotAllowedHandling, NoEmptyRoomHandling, ForbiddenUserHandling, - ForbiddenPasswordHandling + ForbiddenPasswordHandling, + AlreadyJoinedHandling ) from app.errors import ( get_detail, NoSuchElementException, InvalidArgumentException, RequestConflictException, + RequestInvalidException, ForbiddenException ) @@ -98,7 +100,6 @@ def get_study_room(room_id: str, db: Session = Depends(get_db)): "description": "서버에서 잡지 못한 에러" } } - ) def update_study_room(room_id: str, room_info: StudyRoomsUpdate, db: Session = Depends(get_db)): try: @@ -254,6 +255,10 @@ def create_study_room(room_info: StudyRoomsCreate, db: Session = Depends(get_db) "model": SuccessResponseBase, "description": "스터디룸 생성 성공" }, + 400: { + "model": AlreadyJoinedHandling, + "description": "이미 스터디룸에 접속했는데 접속 시도하는 경우" + }, 403: { "model": ForbiddenPasswordHandling, "description": "비공개 방의 비밀번호 오입력 한 경우" @@ -282,6 +287,11 @@ def join_study_room(room_id: str, room_info: StudyRoomJoin, db: Session = Depend study_rooms.join(db, room_id, room_info) return JSONResponse(status_code=status.HTTP_200_OK, content={'data': ''}) + except RequestInvalidException as invalid_err: + message = invalid_err.message + detail = get_detail(param='database', field='user', message=message, err='invalid') + return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={'detail': detail}) + except ForbiddenException as forbidden_err: message = forbidden_err.message detail = get_detail(param='body', field='password', message=message, err='invalid') @@ -304,4 +314,4 @@ def join_study_room(room_id: str, room_info: StudyRoomJoin, db: Session = Depend except Exception as error: print(traceback.print_exc()) - return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) \ No newline at end of file + return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'detail': f'server error: {error}'}) diff --git a/app/crud/study_rooms.py b/app/crud/study_rooms.py index 54afb4a..d36847a 100644 --- a/app/crud/study_rooms.py +++ b/app/crud/study_rooms.py @@ -24,9 +24,11 @@ ) from app.core import time_settings +from app.crud.redis_function import redis_function -MAX_CAPACITY = study_rooms_settings.MAX_CAPACITY +MAX_CAPACITY = study_rooms_settings.MAX_CAPACITY +redis_session = redis_function() def check_password_exist(room_info: Union[StudyRoomsCreate, StudyRoomsUpdate]): return False if (not room_info.is_public) and (not room_info.password) else True @@ -93,8 +95,8 @@ def create(self, db: Session, room_info: StudyRoomsCreate): if not check_password_exist(room_info): raise InvalidArgumentException(message='field required') - room_info.current_join_counts += 1 - room_info.created_at = datetime.utcnow() + time_settings.KST + # room_info.current_join_counts += 1 + room_info.created_at = datetime.utcnow() + time_settings.KST data = self.model(**jsonable_encoder(room_info)) db.add(data) db.commit() @@ -142,6 +144,9 @@ def remove(self, db: Session, room_id: str, user_id: int): def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): try: + if redis_session.check_join(room_info.user_id): + raise RequestInvalidException(message='Already Connect a Study-Room') + data = db.query(self.model).filter( self.model.id == UUID(room_id) ).first() @@ -150,17 +155,21 @@ def join(self, db: Session, room_id: str, room_info: StudyRoomJoin): if study_room: if study_room['current_join_counts'] >= MAX_CAPACITY: raise RequestConflictException(message='no empty') - - if study_room['is_public']: - if room_info.password: - raise InvalidArgumentException(message='field not required') - else: - if not room_info.password: - raise InvalidArgumentException(message='field required') - elif room_info.password != study_room['password']: - raise ForbiddenException(message='forbidden') - - data.current_join_counts += 1 + + if study_room['owner_id'] != room_info.user_id: + if study_room['is_public']: + if room_info.password: + raise InvalidArgumentException(message='field not required') + else: + if not room_info.password: + raise InvalidArgumentException(message='field required') + elif room_info.password != study_room['password']: + raise ForbiddenException(message='forbidden') + + # data.current_join_counts += 1 + + print(f"join study-room(id : {room_id}. current count : {data.current_join_counts})") + db.commit() else: @@ -178,12 +187,16 @@ def leave(self, db: Session, room_id: str): if not room_id: raise NoSuchElementException(message='not found') - if self.model.current_join_counts < 1: + study_room = db.query(self.model).filter( + self.model.id == UUID(room_id) + ) + + print(study_room.first().current_join_counts) + + if (int(study_room.first().current_join_counts) < 1): raise RequestInvalidException(message='invalid request') - db.query(self.model).filter(self.model.id == UUID(room_id)).update( - {'current_join_counts': self.model.current_join_counts - 1} - ) + study_room.update({'current_join_counts': self.model.current_join_counts - 1}) db.commit() except AttributeError: diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py index 78561a4..8efe305 100644 --- a/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -24,7 +24,8 @@ QueryNeedyStudyRoomHandling, NoEmptyRoomHandling, ForbiddenUserHandling, - ForbiddenPasswordHandling + ForbiddenPasswordHandling, + AlreadyJoinedHandling ) from app.schemas.reports import ( ReportsCreate, diff --git a/app/schemas/study_rooms/__init__.py b/app/schemas/study_rooms/__init__.py index 52da0d2..e6c5250 100644 --- a/app/schemas/study_rooms/__init__.py +++ b/app/schemas/study_rooms/__init__.py @@ -14,5 +14,6 @@ QueryNeedyStudyRoomHandling, NoEmptyRoomHandling, ForbiddenPasswordHandling, - ForbiddenUserHandling + ForbiddenUserHandling, + AlreadyJoinedHandling ) \ No newline at end of file diff --git a/app/schemas/study_rooms/crud.py b/app/schemas/study_rooms/crud.py index 7707859..3b7054a 100644 --- a/app/schemas/study_rooms/crud.py +++ b/app/schemas/study_rooms/crud.py @@ -49,7 +49,7 @@ class Config: class StudyRoomJoin(StudyRoomsBase): - + user_id: int class Config: schema_extra = { 'example': { diff --git a/app/schemas/study_rooms/handling.py b/app/schemas/study_rooms/handling.py index cb2335a..87362dc 100644 --- a/app/schemas/study_rooms/handling.py +++ b/app/schemas/study_rooms/handling.py @@ -140,4 +140,21 @@ class Config: } ] } - } \ No newline at end of file + } + +class AlreadyJoinedHandling(ErrorResponseBase): + class Config: + schema_extra = { + 'example': { + "detail": [ + { + "loc": [ + "database", + "user" + ], + "msg": "Already Connect a Study-Room", + "type": "invalid" + } + ] + } + } \ No newline at end of file From 1a467e6911bea4edce419f962c377f0d7fca6aa4 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:13:17 +0900 Subject: [PATCH 142/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20get=5Freports?= =?UTF-8?q?=20value=EB=A1=9C=20=EC=8B=9C=EA=B0=84=EC=9D=84=20=EC=A3=BC?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/reports.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/crud/reports.py b/app/crud/reports.py index a23bb3d..5fdc847 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -29,9 +29,9 @@ def get(self, db: Session, user_id: int, date: str): self.model.concentration, self.model.total_time, self.model.total_star_count, - func.count(Statuses.count).filter(not_( + func.sum(Statuses.time).filter(not_( Statuses.type == 'rest' - )).label('total_status_counts') + )).label('total_status_time') ).group_by(self.model.id).first() if instance: @@ -40,8 +40,8 @@ def get(self, db: Session, user_id: int, date: str): Statuses.report_id == report['id'] ).with_entities( Statuses.type.label('name'), - func.count(Statuses.count).label('value'), - func.sum(Statuses.time).label('total_time') + func.sum(Statuses.count).label('total_count'), + func.sum(Statuses.time).label('value') ).group_by(Statuses.type).all() report['statuses'] = jsonable_encoder(statuses) report['max_status'] = [status['name'] for status in report['statuses'] if status['value'] == max(report['statuses'], key=lambda x: x['value'])['value']] From 78b253868f58c7a3c08a4a70607a16b95de1ab34 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:13:50 +0900 Subject: [PATCH 143/147] =?UTF-8?q?=EC=B6=94=EA=B0=80=20:=20report=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=9C,=20=EC=A7=91?= =?UTF-8?q?=EC=A4=91=EB=8F=84=20=EC=97=B0=EC=82=B0=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/reports.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/crud/reports.py b/app/crud/reports.py index 5fdc847..72eda38 100644 --- a/app/crud/reports.py +++ b/app/crud/reports.py @@ -85,9 +85,18 @@ def update(self, db: Session, id: int, total_time: int): instance = db.query(self.model).filter( self.model.id == id ).first() + + statuses = db.query(Statuses).filter( + Statuses.report_id == instance.id + ).with_entities( + func.sum(Statuses.time).filter(not_( + Statuses.type == 'rest' + )).label('total_time') + ).first() if instance: instance.total_time += total_time + instance.concentration = 100 - int(jsonable_encoder(statuses)['total_time'] / instance.total_time * 100) db.commit() except: From b330e8cf4e05c7149d5f492f33c49e183acb5339 Mon Sep 17 00:00:00 2001 From: limm-jk Date: Sat, 3 Jul 2021 06:14:31 +0900 Subject: [PATCH 144/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20socket=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20=EA=B4=80=EB=A0=A8=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/__init__.py | 12 +++--- app/crud/redis_function.py | 24 +++++++++--- app/service/sockets.py | 77 +++++++++++++++++++++----------------- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/app/crud/__init__.py b/app/crud/__init__.py index 438869a..a36396c 100644 --- a/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,7 +1,7 @@ -from app.crud.users import users -from app.crud.study_rooms import study_rooms -from app.crud.statuses import statuses -from app.crud.my_studies import my_studies -from app.crud.reports import reports -from app.crud.redis_function import redis_function +from app.crud.users import users +from app.crud.study_rooms import study_rooms +from app.crud.statuses import statuses +from app.crud.my_studies import my_studies +from app.crud.reports import reports +from app.crud.redis_function import redis_function diff --git a/app/crud/redis_function.py b/app/crud/redis_function.py index dbc031b..65e9cbd 100644 --- a/app/crud/redis_function.py +++ b/app/crud/redis_function.py @@ -28,10 +28,10 @@ def __setflat_skeys__( raise TypeError(f"Unsupported value type: {type(value)}") -def study_room_starting(study_room_id): +def study_room_starting(): return { "status": "study", - "study_rooms": study_room_id, + "study_rooms": "", "last_access": 1, "sleep": { "count": 0, @@ -71,14 +71,22 @@ def logout(self, token: str, user_email: str): def check_black_list(self, token: str): self.redis.exists(token) - def start_study_init(self, user_id: str, study_room_id: str): - __setflat_skeys__(self.redis, study_room_starting(study_room_id), user_id) + def start_study_init(self, user_id: str): + __setflat_skeys__(self.redis, study_room_starting(), user_id) + + def set_study_room(self, user_id: str, study_room_id: str): + self.redis.set(__generate_value_string__(user_id, "study_rooms"), study_room_id) def get_user_study_info(self, user_id, user_monitoring, disturb_info=None): return self.redis.get( __generate_value_string__(user_id, user_monitoring, disturb_info) ) + def check_join(self, user_id: str): + return self.redis.get( + __generate_value_string__(user_id, 'study_rooms') + ) + def add_current_log(self, user_id, disturb_type, disturb_time): # status를 업데이트 해야함 # 이 때, 이전 상태를 저장해야 함. @@ -92,12 +100,13 @@ def add_current_log(self, user_id, disturb_type, disturb_time): self.redis.set(last_access_key, disturb_time) + print(f"User(id : {user_id}) update status({last_status}-> {disturb_type}).") + if last_status != "study": status_time = disturb_time - float(last_access) - print(status_time) - print(last_status) self.redis.incr(__generate_value_string__(user_id, last_status, 'count'), 1) self.redis.incr(__generate_value_string__(user_id, last_status, 'sec'), int(status_time)) + print(f"Save Status Log({last_status} {int(status_time)}sec.)") def delete_user_study_info(self, user_id: str): target_key = self.redis.keys(f"{user_id}:*") @@ -105,6 +114,9 @@ def delete_user_study_info(self, user_id: str): self.redis.delete(key) def end_study(self, user_id: str): + if not self.check_join(user_id): + return None + self.add_current_log(user_id, "study", time.time()) result = self.get_user_all_info(user_id) self.delete_user_study_info(user_id) diff --git a/app/service/sockets.py b/app/service/sockets.py index ab623fa..5fbcb36 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -1,20 +1,18 @@ import socketio import traceback - import time - - -from app.crud import ( - study_rooms, - reports, - my_studies, - statuses, - redis_function - ) -from app.database import SessionLocal +from app.crud import ( + study_rooms, + reports, + my_studies, + statuses, + redis_function + ) +from app.database import SessionLocal from app.errors import NoSuchElementException, RequestInvalidException + clients = dict() @@ -39,6 +37,9 @@ async def on_connect(self, sid, environ, auth): 'report_id': instance['id'], 'my_study_id': '', } + + # redis init + self.redis.start_study_init(user_id = clients[sid]['user_id']) await self.emit( 'response', @@ -71,6 +72,7 @@ async def on_connect(self, sid, environ, auth): async def on_joinRoom(self, sid, room_id): try: print('join room') + print(room_id) self.enter_room(sid=sid, room=room_id, namespace=self.namespace) instance = my_studies.create( db = self.db, @@ -79,8 +81,9 @@ async def on_joinRoom(self, sid, room_id): ) clients[sid]['room_id'] = room_id clients[sid]['my_study_id'] = instance['id'] - # redis table init - self.redis.start_study_init(user_id = clients['user_id'], study_room_id=room_id) + + # redis set study room + self.redis.set_study_room(user_id = clients[sid]['user_id'], study_room_id = room_id) await self.emit( 'response', @@ -88,7 +91,9 @@ async def on_joinRoom(self, sid, room_id): 'statusCode': 200, 'message': 'SUCCESS', 'eventName': 'joinRoom', - 'dat': {} + 'data': { + 'my_study_id' : instance['id'] + } }, room = room_id, namespace = self.namespace @@ -200,9 +205,8 @@ async def on_status(self, sid, status): - response 이벤트로 message에 disturbance 상태를 보내줘야 한다. - 개별 사용자의 휴식이 다르기 때문에 Redis에 휴식에 대한 것도 저장 할 필요가 있어 보인다. """ - print('status', status) - self.redis.add_current_log(clients['user_id'], status, time.time()) + self.redis.add_current_log(clients[sid]['user_id'], status, time.time()) await self.emit( @@ -244,33 +248,34 @@ async def on_disconnect(self, sid): study_rooms.leave(self.db, room_id=clients[sid]['room_id']) self.leave_room(sid=sid, room=clients[sid]['room_id'], namespace=self.namespace) - result = self.redis.end_study(clients['user_id']) - - for status in ['sleep', 'smartphone', 'await', 'rest']: - self.__create_status__(sid, status, result[status]) - - my_study = my_studies.update( - db = self.db, - id = clients[sid]['my_study_id'] - ) - reports.update( - db = self.db, - id = clients[sid]['report_id'], - total_time = my_study['total_time'] - ) + result = self.redis.end_study(clients[sid]['user_id']) + + if result: + for status in ['sleep', 'smartphone', 'await', 'rest']: + await self.__create_status__(sid, status, result[status]) + + my_study = my_studies.update( + db = self.db, + id = clients[sid]['my_study_id'] + ) + reports.update( + db = self.db, + id = clients[sid]['report_id'], + total_time = my_study['total_time'] + ) clients.pop(sid) print(f'sid: {sid}, clients: {clients}') print('disconnect success') except NoSuchElementException: - print('not found') + # 입장 전에 공부방을 종료하는 경우 await self.emit( 'response', { - 'statusCode': 404, - 'messgae': 'NOT_FOUND', - 'eventName': 'leaveRoom', + 'statusCode': 200, + 'messgae': 'SUCCESS', + 'eventName': 'disconnect', 'data': {} }, namespace = self.namespace @@ -290,7 +295,7 @@ async def on_disconnect(self, sid): ) async def __create_status__(self, sid, type, study_result: dict): - statuses.update_or_create( + saved_status = statuses.update_or_create( db = self.db, type = type, cnt = study_result['count'], @@ -298,3 +303,5 @@ async def __create_status__(self, sid, type, study_result: dict): my_study_id = clients[sid]['my_study_id'], report_id = clients[sid]['report_id'] ) + + print(saved_status) From e13a1a5a7201971a78c2b704ea6b21f7cf525e65 Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Wed, 7 Jul 2021 22:38:37 +0900 Subject: [PATCH 145/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20Socket=20status?= =?UTF-8?q?=20event=20response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/service/sockets.py | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/app/service/sockets.py b/app/service/sockets.py index 5fbcb36..e5dffe8 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -16,6 +16,19 @@ clients = dict() +""" +To Do +- joinRoom, leaveRoom, status, disconnect 때 방에 입장해 있는 사용자 수를 알려줘야 한다. + clients 객체에 접근하여 room_id가 동일한 객체의 수를 세는 방법이 있다. + 또는 Redis에 저장하는 형태를 아예 바꾸는 방법이 있다. + 노동과 시간은 후자가 더 많이 들어가지만 효율성이나 속도를 생각했을 때는 더 좋은 것 같다. + 전자, 후자 모두 효율적으로 코드를 만들 방법을 고려 할 필요가 있다. +- 오류가 발생했을 때 자동으로 disconnect 되게 하는 게 좋을 것 같다. + 오류가 발생한 상황은 다시 말하면 허용되지 않은 방법으로 소켓에 접근하는 것이기도 하다. + response 이벤트로 이를 알려주기 보다는 바로 연결을 해제 시켜버리는 게 더 좋을 것 같다. +""" + + class StudyNamespace(socketio.AsyncNamespace): def __init__(self, sio, namespace, *args, **kwargs): super(socketio.Namespace, self).__init__(namespace) @@ -85,6 +98,7 @@ async def on_joinRoom(self, sid, room_id): # redis set study room self.redis.set_study_room(user_id = clients[sid]['user_id'], study_room_id = room_id) + # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. await self.emit( 'response', { @@ -143,6 +157,7 @@ async def on_leaveRoom(self, sid, room_id): """ print('leave room') + # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. await self.emit( 'disconnect', { @@ -209,13 +224,16 @@ async def on_status(self, sid, status): self.redis.add_current_log(clients[sid]['user_id'], status, time.time()) + # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. await self.emit( 'response', { 'statusCode': 200, 'message': 'SUCCESS', 'eventName': 'status', - 'data': status + 'data': { + 'status': status + } }, room = clients[sid]['room_id'], namespace = self.namespace @@ -268,8 +286,20 @@ async def on_disconnect(self, sid): print(f'sid: {sid}, clients: {clients}') print('disconnect success') + # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. + await self.emit( + 'response', + { + 'statusCode': 200, + 'message': 'SUCCESS', + 'eventName': 'disconnect', + 'data': {} + } + ) + except NoSuchElementException: # 입장 전에 공부방을 종료하는 경우 + # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. await self.emit( 'response', { @@ -304,4 +334,4 @@ async def __create_status__(self, sid, type, study_result: dict): report_id = clients[sid]['report_id'] ) - print(saved_status) + print(saved_status) \ No newline at end of file From 335ab722b1ce164174b01242f658333ebf1b37ce Mon Sep 17 00:00:00 2001 From: 2_taehyun <63915557+0417taehyun@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:49:40 +0900 Subject: [PATCH 146/147] =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EB=AA=A8=EB=93=A0=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?Response=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crud/users.py | 29 ++++++++++++++++++++++------- app/service/sockets.py | 36 ++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/app/crud/users.py b/app/crud/users.py index ba9f1a5..0bd43ba 100644 --- a/app/crud/users.py +++ b/app/crud/users.py @@ -1,14 +1,29 @@ -from typing import Optional, List +from sqlalchemy.orm import Session +from fastapi.encoders import jsonable_encoder -from sqlalchemy.orm import Session - -from app.crud.base import CRUDBase -from app.models import User -from app.schemas import UserCreate, UserUpdate +from app.crud.base import CRUDBase +from app.models import User +from app.schemas import UserCreate, UserUpdate +from app.errors import NoSuchElementException class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]): - # Declare model specific CRUD operation methods. + def get(self, db: Session, user_id: int): + data = db.query(self.model).filter( + self.model.id == user_id + ).with_entities( + self.model.id, + self.model.nickname, + self.model.provider, + self.model.social_id + ).first() + + if data: + return jsonable_encoder(data) + else: + return NoSuchElementException(message='not found') + + def get_one_by_email(self, db: Session, email: str): return db.query(User).filter(User.social_id == email).first() diff --git a/app/service/sockets.py b/app/service/sockets.py index e5dffe8..72af03f 100644 --- a/app/service/sockets.py +++ b/app/service/sockets.py @@ -3,6 +3,7 @@ import time from app.crud import ( + users, study_rooms, reports, my_studies, @@ -36,23 +37,34 @@ def __init__(self, sio, namespace, *args, **kwargs): self.db = SessionLocal() self.redis = redis_function() + async def get_users(self, room_id): + users = [ + value for value in clients.values() if value['room_id'] == room_id + ] + return users async def on_connect(self, sid, environ, auth): try: print('connect') - instance = reports.get_or_create( + user_instance = users.get( + db = self.db, + user_id = auth['user_id'] + ) + report_instance = reports.get_or_create( db = self.db, user_id = auth['user_id'] ) clients[sid] = { 'user_id': auth['user_id'], + 'user_nickname': user_instance['nickname'], + 'status': 'study', 'room_id': '', - 'report_id': instance['id'], + 'report_id': report_instance['id'], 'my_study_id': '', } # redis init - self.redis.start_study_init(user_id = clients[sid]['user_id']) + self.redis.start_study_init(user_id = auth['user_id']) await self.emit( 'response', @@ -99,15 +111,15 @@ async def on_joinRoom(self, sid, room_id): self.redis.set_study_room(user_id = clients[sid]['user_id'], study_room_id = room_id) # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. + users = await self.get_users(room_id = room_id) + await self.emit( 'response', { 'statusCode': 200, 'message': 'SUCCESS', 'eventName': 'joinRoom', - 'data': { - 'my_study_id' : instance['id'] - } + 'data': users }, room = room_id, namespace = self.namespace @@ -222,7 +234,8 @@ async def on_status(self, sid, status): """ self.redis.add_current_log(clients[sid]['user_id'], status, time.time()) - + clients[sid]['status'] = status + users = await self.get_users(room_id = clients[sid]['room_id']) # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. await self.emit( @@ -231,9 +244,7 @@ async def on_status(self, sid, status): 'statusCode': 200, 'message': 'SUCCESS', 'eventName': 'status', - 'data': { - 'status': status - } + 'data': users }, room = clients[sid]['room_id'], namespace = self.namespace @@ -281,10 +292,11 @@ async def on_disconnect(self, sid): id = clients[sid]['report_id'], total_time = my_study['total_time'] ) - + room_id = clients[sid]['room_id'] clients.pop(sid) print(f'sid: {sid}, clients: {clients}') print('disconnect success') + users = await self.get_users(room_id = room_id) # 사용자 수를 알려줄 방법에 대해서 생각해봐야 한다. await self.emit( @@ -293,7 +305,7 @@ async def on_disconnect(self, sid): 'statusCode': 200, 'message': 'SUCCESS', 'eventName': 'disconnect', - 'data': {} + 'data': users } ) From 7da5430ab07e180d88ca62d005d760c729f1de9c Mon Sep 17 00:00:00 2001 From: limm-jk Date: Mon, 11 Oct 2021 15:08:02 +0900 Subject: [PATCH 147/147] =?UTF-8?q?=EC=88=98=EC=A0=95=20:=20=EB=A6=AC?= =?UTF-8?q?=EB=93=9C=EB=AF=B8=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EA=B0=9C=20=EB=B0=8F=20=EC=8B=A4=ED=96=89=EB=B0=A9?= =?UTF-8?q?=EB=B2=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e7aa7e..2c52178 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,32 @@ # Studeep API Server✨ +### **내 꿈을 향해 깊은 곳으로, 스터딥** + +학습 모니터링을 통해 몰입환경을 만들어주는 공부 습관 개선 서비스 + +**집에서 집중하기, 잘하고 계신가요?** + +코로나 19로 온라인 개학과 원격 수업이 자리 잡은 환경에서, 집에서 일과 공부를 새로운 방식으로 하는 걸 쉽게 확인할 수 있어요. 이제는 집이라는 공간에서 학업과 업무 그리고 휴식까지 24시간을 함께 하는 공간이 되었고, 그곳에서 각자 공부와 일에 집중하기 위해 큰 노력을 기울이고 있어요. + +그래서 "집이라는 공간에서도 몰입할 수 있는 환경을 어떻게 만들 수 있을까?"라는 질문에서, 스터딥이 시작되었어요. 학습 모니터링을 통해 5초면 몰입할 수 있는 환경을 만들어드릴게요. + +## Live Service [Studeep](https://www.studeep.com) +## Getting Started +``` +// 의존성 설치 +pip install -r requirements.txt + +// DB Migration +PYTHONPATH=. alembic revision --autogenerate -m "migration name" +PYTHONPATH=. alembic upgrade head + +// 서버 실행 +python3 -m app.main +``` + + + ## Production ![](./images/studeep_product.png) @@ -11,4 +37,6 @@ ![](./images/studeep_modeling.png) ## API Docs -[Swagger](https://www.studeep.com/docs) \ No newline at end of file +[Swagger](https://www.studeep.com/docs) + +