From 5c87f348793f2ffe542af9f2653a6740f7b4496f Mon Sep 17 00:00:00 2001 From: taehyeon Date: Tue, 12 Nov 2024 12:13:26 +0900 Subject: [PATCH 01/20] =?UTF-8?q?docs:=201=EC=9D=BC=EC=B0=A8=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "taehyeon/1\354\235\274\354\260\250.md" | 213 ++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 "taehyeon/1\354\235\274\354\260\250.md" diff --git "a/taehyeon/1\354\235\274\354\260\250.md" "b/taehyeon/1\354\235\274\354\260\250.md" new file mode 100644 index 0000000..ca6a438 --- /dev/null +++ "b/taehyeon/1\354\235\274\354\260\250.md" @@ -0,0 +1,213 @@ +# 1일차 + +## HTTP METHOD + +### GET(read) + +- 리소스 조회 메서드 +- 쿼리스트링을 통해 데이터를 전달 + - ex) localhost/members/1?username=inpa&height=200 +- 쿼리스트링 외에 메시지 바디를 사용해서 데이터를 전달할 수 있지만 서버에서 따로 구성해야 되기 때문에 지원하지않는 곳이 많아 권장하지 않음 +- POST를 사용해도 되지만 캐싱이 불가능해서 GET을 사용 + +### POST(create) + +- 전달한 데이터 처리/생성 요청 메서드 +- 메시지 바디를 통해 데이터를 전달 +- 만약 데이터 조회를 위해 JSON으로 데이터를 넘겨야 하는 경우 POST 사용 + +### PUT(update) + +- 리소스를 수정하는 메서드 +- 요청 메시지에 리소스가 있으면 덮어쓰고, 엎으면 새로 생성 + - ex) /member/100 +- 데이터를 대체해야 하기 때문에, 리소스의 구체적인 경로를 보내줘야 함 + - ex) POST /members 멥버 새로 추가 PUT /members/1 1번 멥버 수정 + +### PATCH(update) + +- 리소스의 부분을 수정하는 메서드 +- 만약 PATCH를 지원하지 않는 서버라면 POST 사용 + +### DELETE(delete) + +- 리소스를 제거하는 메서드 + +### HEAD + +- GET과 동일하지만 서버에서 Body를 Return 하지 않음 +- 응답의 상태 코드만 확인하는 경우 Resource를 받지 않고 오직 찾기만 원할때 사용(검사용) +- 서버의 응답 헤더를 확인해서 Resource가 수정 되었는지 확인 가능 + +### TRACE + +- 검사용 메서드 +- 서버에 도달 했을 때의 최종 패킷의 요청 패킷 내용을 받을 수 있음 +- 요청의 최종 수신자는 반드시 송신자에게 수신한 메시지와 200을 Body로 보냄 +- 최초 Clinet의 요철에는 Body가 포함될 수 없음 + +### OPTION + +- 예비 요청에 사용되는 메서드 + - 예비 요청이란 본 요청을 하기 전에 안전한지 미리 검사하는 것 +- 서버의 지원 가능한 HTTP 메서드와 출처를 받아 CORS 정책을 검사함 + +#### CORS(Cross Origin Resource Sharing) + +- 교차 출처 리소스 공유 정책으로 다른 출처의 리소스 공유에 대한 허용/비허용 정책 +- 출처는 프로토콜,도메인,포트만 비교 +- 기본 동작 과정 + 1. 클라이언트가 HTTP요청(예비 요청) 헤더에 Origin을 담아 서버에 전달 + 2. 서버가 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트에 전달 + 3. 클라이언트가 Origin과 Access-Control-Allow-Origin를 비교 +- 프록시 서버를 사용해서 해결 가능 + +## HTTP 상태 코드 + +### 1XX(정보 제공) + +- 임시 응답으로 현재 클라이언트의 요청까지는 처리되었으니 계속 진행하라는 의미(HTTP 1.1 버전부터 추가) + +### 2XX(성공) + +- 클라이언트의 요청이 서버에서 성공적으로 처리 +- *200 성공* +- *201 요청이 처리되어 리소가 생성* +- *202 요청은 접수하였지만, 처리가 완료되지 않음* + +### 3XX(리다이렉션) + +- 완전한 처리를 위해서 추가 동작이 필요한 경우 +- 주로 서버의 주소 또는 요청한 URL의 웹 문서가 이동되었으니 그 주소로 다시 시도하라는 의미 +- *301 새로운 URL로 영구 이동* +- *303 다른 위치로 요청* +- 304 마지막 요청이후 페이지가 수정되지 않음 +- *307 임시로 리다이렉션 요청* + +### 4XX(클라이언트 에러) + +- 없는 페이지를 요청하는 등 클라이언트의 요청 메시지 내용이 잘못된 경우를 의미 +- *400 잘못된 요청* +- *401 지정한 리소스에 대한 권환이 없음* +- *403 401 인증 처리 이외 엑세스가 금지됨* +- *404 찾을 수 없음* + +### 5XX(서버 에러) + +- 서버 사정으로 메시지 처리에 문제가 발생한 경우 +- 서버의 부하, DB 처리 과정 오류, 서버에세 Exception이 발생하는 경우 +- *500 서버 내부 오류* +- *501 구현되지 않음* +- *502 게이트웨이 또는 프록시 서버가 잘못됨* + +## HTTP 헤더 + +### 공통 헤더 + +- 요청 및 응답 메시지 모두에서 사용 가능한 기본적인 헤더 +- Date HTTP 메시지를 생성한 일시 +- Connetion 클라언트와 서버 간 연결에 대한 옵션 설정 +- Cache-Control 쿠키 캐시 관련 + +### 엔티티 관련 헤더 + +- 요청 및 응답 메시지 모두에서 사용 가능한 Entity에 대한 설명 헤더 +- Content-Type 해당 개체에 포함되는 미디어 타입 정보 +- Content-Language 헤더 개체와 가장 잘 어울리는 언어 +- Content-Encoding 해당 개체 데이터의 압축 방식 +- Content-Length 해당 개체의 바이트 길이 또는 크기 +- Content-Location 해당 개체의 실제 위치 +- Content-Disposition 응답 Body를 브라우저가 어떻게 표시해야 하는지 +- Content-Disposition 외부 파일을 불러오는 경우, 차단할 소스와 불러올 소스 명시 +- Location 리다이렉트 된 때에 이동된 주소, 또는 새로 생성된 주소를 명시 +- Last-Modified 리소스를 마지막으로 갱신한 일시 +- Transfer-Encoding 동적으로 생서되어 Body의 길이를 모르는 경우 조금씩 전송 가능한 청크 + +### 요청 헤더 + +- Host 요청하는 호스트명과 포트번호(필수) +- User-Agent 클라이언트 소프트웨어 정보 +- From 클라이언트 사용자 메일 주소 +- Cookie 서버에 의해 클라이언트에 설정된 쿠키 정보 +- Referer 바로 직전에 머물었던 링크 주소 +- If-Modified-Since 제시한 일시 이후로만 변경된 리소스 취득 요청 +- Authorization 인증 토큰을 서버로 보냄 + + +### 응답 헤더 캐시/쿠키 관련 헤더 + +- 특정 유형의 HTTP 요청이나 특정 HTTP 헤더를 수신했을 때, 이에 응답 +- Server 서버 소프트웨어 정보 +- Set-Cookie 서버측에서 클라인어트에게 세션 쿠키 정보를 설정 (캐시/쿠키) +- Expires 응답 컨텐츠가 언제 만료되는지 나타냄 (캐시/쿠키) +- Age 캐시 응답. max-age 시간 내에서 얼마나 흘렀는지 초 단위로 알려줌 (캐시/쿠키) +- ETag HTTP 컨텐츠가 바뀌었는지를 검사 (캐시/쿠키) +- Allow 서버 측에서 지원 가능한 HTTP메서드의 리스트 +- Access-Control-Allow-Origin 요청을 보내는 프론트 주소와 받는 백엔드 주소가 다르면 CORS에러 발생 + +## REST API + +- HTTP 프로토콜을 기반으로 하는 웹 통신을 위한 아키텍처 스타일 +- REST(Representational State Transfer) 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미 +- 클라이언트와 서버가 분리되어 독립적으로 개발이 가능해야 함 +- 각 요청은 독립적으로 모든 요청에는 요청을 처리하는데 필요한 모든 정보가 포함되어야 함 +- 응답은 캐시 가능 여부를 명시해야 함 + +### 자원 + +- URI를 통해 자원을 식별 + +### 행위 + +- HTTP 메서드를 통해 자원에 대한 행위를 정의 + +### 사용 예시 + +- GET /users 사용자 목록 조회 +- GET /users/123 사용자 +- POST /users 새 사용자 생성 +- PUT /users/123 사용자 정보 수정 +- DELETE /users/123 사용자 삭제 + +### RESTFUL + +- REST의 특징을 따라가는 것(얼마나 REST API를 잘 지키냐) + +## 쿠키와 세션, JWT 토근 + +### 쿠키 + +- 서버가 클라이언트의 웹 브라우저에 저장하는 작은 데이터 +- 최대 4KB까지의 문자열 데이터 저장 가능 +- 클라이언트 측에 저장됨 +- 만료기간 설정 가능 +- 도메인 별로 저장됨 +- HTTP 헤더에 포함되어 전송 + +### 세션 + +- 서버 측에서 유지되는 사용자별 상태 정보 +- 세션 ID를 통해 클라이언트 식별 +- 서버 측에 저장 +- 브라우저 종료 시 삭제 +- 보안성이 쿠키보다 높음 +- 서버 리소스 사용 + +#### 주요용도 + +- 세션관리 : 로그인상태, 장바구니등 +- 개인화 : 사용자 선호 설정, 테마등 +- 트래킹 : 사용자 행동 분석 + +### JWT(JSON Web Token) + +- 정보를 안전하게 전송하기 위한 웹 표준 토큰 +- JSON 형태의 데이터를 인코딩하고 서명하여 생성되며, 주로 사용자 인증과 정보 교환에 사용됨 + + +- MVC, MVC2 +- 인프라 + - HTTPS + - DNS 서버 + - CI/CD +- 각자 intraid으로 된 브랜치를 만든 후 intraid로 폴더를 만들고 1일차 md로 작성해서 pr \ No newline at end of file From 848afbcc9b3e8b79e5ea89793cea33adf635e9ff Mon Sep 17 00:00:00 2001 From: taehyeon Date: Tue, 12 Nov 2024 14:22:15 +0900 Subject: [PATCH 02/20] =?UTF-8?q?docs:=201=EC=9D=BC=EC=B0=A8=20=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "taehyeon/1\354\235\274\354\260\250.md" | 180 ++++++++++++++++++++---- 1 file changed, 150 insertions(+), 30 deletions(-) diff --git "a/taehyeon/1\354\235\274\354\260\250.md" "b/taehyeon/1\354\235\274\354\260\250.md" index ca6a438..9c8599a 100644 --- "a/taehyeon/1\354\235\274\354\260\250.md" +++ "b/taehyeon/1\354\235\274\354\260\250.md" @@ -147,39 +147,48 @@ ## REST API +- API 설계에 대한 표준이 없어서 구축과 디버깅이 어려워 개발됨 - HTTP 프로토콜을 기반으로 하는 웹 통신을 위한 아키텍처 스타일 - REST(Representational State Transfer) 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미 -- 클라이언트와 서버가 분리되어 독립적으로 개발이 가능해야 함 -- 각 요청은 독립적으로 모든 요청에는 요청을 처리하는데 필요한 모든 정보가 포함되어야 함 -- 응답은 캐시 가능 여부를 명시해야 함 - -### 자원 -- URI를 통해 자원을 식별 +### 주요 특징 -### 행위 +- 어떤 플랫폼이나 언어를 사용하더라도 HTTP 프로토콜을 통해 통신이 가능 +- API 메세지만으로도 의도를 명확하게 파악 가능 +- 서버가 클라이언트의 상태를 저장하지 않아 서버 확장이 용이하며 독립적인 개발 가능 +- 로드 밸런서, 캐시등의 중간 계층을 추가하여 시스템을 확장 가능 +- 필요한 리소스만 요청하고 응답받아 불필요한 데이터 전송 방지 +- HTTP 캐싱 기능을 활용하여 응답시간 개선과 서버 부하를 줄임 +- HTTP의 SSL/TLS를 통한 암호화 지원 +- 헤더나 토근을 통한 접근 제어 가능 -- HTTP 메서드를 통해 자원에 대한 행위를 정의 +### 단점 -### 사용 예시 - -- GET /users 사용자 목록 조회 -- GET /users/123 사용자 -- POST /users 새 사용자 생성 -- PUT /users/123 사용자 정보 수정 -- DELETE /users/123 사용자 삭제 +- HTTP 메서드에 제한적 +- 공식적인 표준의 부재로 인한 일광성 있는 API 설계 어려움 ### RESTFUL - REST의 특징을 따라가는 것(얼마나 REST API를 잘 지키냐) +- 클라이언트와 서버가 분리되어 독립적으로 개발이 가능해야 함 +- 각 요청은 독립적으로 모든 요청에는 요청을 처리하는데 필요한 모든 정보가 포함되어야 함 -## 쿠키와 세션, JWT 토근 +## 쿠키와 세션, JWT토큰 + +### 쿠키와 세션 필요 이유 + +- HTTP 프로토콜의 특성인 비연결성과 무상태성을 보안하기 위해 필요 +- 서버가 클라이언트를 식별하고 이전 요청과의 연속성을 유지할 수 있음 +- 사용자별 맞춤 서비스 제공이 가능 +- 로그인 상태 유지, 장바구니 등의 정보를 관리할 수 있음 +- 쿠키를 사용하면 클라이언트 측에서 정보를 저장하여 서버 부하를 줄일 수 있음 +- 세션을 통해 중요 정보를 서버에서 안전하게 관리 ### 쿠키 - 서버가 클라이언트의 웹 브라우저에 저장하는 작은 데이터 - 최대 4KB까지의 문자열 데이터 저장 가능 -- 클라이언트 측에 저장됨 +- 클라이언트 측에 저장 - 만료기간 설정 가능 - 도메인 별로 저장됨 - HTTP 헤더에 포함되어 전송 @@ -193,21 +202,132 @@ - 보안성이 쿠키보다 높음 - 서버 리소스 사용 -#### 주요용도 +### JWT(JSON Web Token) + +- 정보를 안전하게 JSON 객체로 전송하기 위한 독립적인 토큰 -- 세션관리 : 로그인상태, 장바구니등 -- 개인화 : 사용자 선호 설정, 테마등 -- 트래킹 : 사용자 행동 분석 +#### 기존 세션 방식의 문제 해결 -### JWT(JSON Web Token) +- 별도의 세션 저장소가 필요 없어서 서버 확장이 쉬움 +- 사용자 인증을 위한 추가 리소스 비용 감소 + +#### 구조 + +- 헤더 : 토큰 유형과 사용된 암호화 알고리즘 정보 포함 +- 페이로드 : 사용자 정보 및 권한 정보 포함, 토큰 발급/만료 시간 등의 클레임 정보 +- 서명 : 토큰의 유효성을 검증하기 위한 서명 + +#### 작동 방식 + +1. 클라이언트가 로그인 요청 +2. 서버가 인증 정보를 확인 +3. 인증 성공시 JWT 토큰 생성 +4. 생성된 토큰을 클라이언트에게 반환 +5. 이후 클라이언트는 모든 API 요청시 JWT를 Authorization 헤더에 포함 +6. 서버는 JWT 검증 필터를 통해 토큰 유효성 검사 +7. 검증 성공 시 요청한 리소스에 접근 허용 + + +#### 단점 + +- Base64 인코딩으로 인한 데이터 크기 증가 +- 토큰 탈취 시 만료 전까지 대체 어려움 +- 중요 정보를 페이로드에 저장할 수 없음 + +## MVC, MVC2 (Mode View Controller) + +### MVC1 아키텍처 + +- JSP 페이지가 Controller와 View 역활을 모두 담당 +- 하나의 JSP 페이지 내에서 비즈니스 로직과 화면 표시를 모두 처리 +- Model은 JavaBeans를 통해 데이터 처리 + +#### 장점 + +- 구현이 단순하고 빠른 개발 가능 +- 소규모 프로젝트에 적합 + +#### 단점 + +- 코드의 가독성이 떨어짐 +- 유지보수가 어려움 +- 컴포넌트 재사용성이 낮음 + +### MVC2 아키텍처 + +- Controller(Servlet), View, Model이 명확히 분리됨 +- Controller가 모든 요청을 처리하고 Model과 View를 조정 +- View는 순수하게 화면 표시만 담당 +- UI 와 비즈니스 로직이 완전히 분리 +- 각 계층이 독립적으로 개발/수정 가ㅡㅇ +- 컴포넌트의 재사용이 용이 + +## HTTPS + +- HTTPS는 HTTP의 보안 확장 버전으로 SSL/TLS 프로토콜을 통해 암호환된 통신을 제공 + +### 주요 기능 + +- 모든 통신 내용을 SSL/TLS 프로토콜로 암호화 +- 전송 중에 데이터 변조 방지 +- SSL 인증서를 통한 서버 신원 확인 + +### 작동 방식 + +1. 초기 연결 설정 (HandShking) + - 클라이언트가 서버에 연결 시도 + - 서버가 SSL 인증키 전달 + - 클라이언트가 인증서 유효성 검증 +2. 세션키 교환 + - 클라이언트가 세션키 생성 + - 서버의 공개키로 세션키를 암호화하여 전송 + - 서버가 개인키로 복호화하여 세션키 획득 +3. 데이터 통신 + - 공유된 세션키를 사용하여 데이터 암호화/복호화 + - 양방향 암호화된 통신 수행 + +### HTTPS 적용을 위해 웹 서버를 사용하는 이유 + +- 웹 서버를 사용하면 애플리케이션 서버는 비즈니스 로직에만 집중할 수 있고, 보안과 성능 최적화는 웹 서버가 전문적으로 처리할 수 있음 이로인해 전체 시스템의 효율성과 안정성을 높이는 결과를 가져옴 + +## DNS(Domain Name System) 서버 + +- DNS 서버는 도메인 이름을 IP주소로 변환해주는 인터넷의 전화번호후 역활을 하는 시스템 + - ex) www.example.com -> 192.158.1.38 + +### 필요 이유 + +- 복잡한 IP주소 대신 기억하기 쉬운 도메인 사용 +- DNS 캐싱을 통한 빠른 웹사이트 접근 +- 서버 부하 분산 +- 네트워크 트래픽 최적화 +- IP 주소가 변경되어도 도메인 이름으로 유지 가능 + +### DNS 서버 계층 + +1. LOCAL DNS SERVER +2. ROOT DNS SERVER +3. TLD(Top Level Domain) SERVER +4. Authoritative DNS Server + +### DNS 캐싱 + +1. 브라우저 캐시 +2. 운영체제 캐시 +3. ISP 캐시 + +## CI/CD (Continuous Integration/Continuous Delivery) + +- 애플리케이션의 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법입니다. + +### CI -- 정보를 안전하게 전송하기 위한 웹 표준 토큰 -- JSON 형태의 데이터를 인코딩하고 서명하여 생성되며, 주로 사용자 인증과 정보 교환에 사용됨 +- 개발자들이 코드 변경사항을 중앙 레포지토리에 자주 병합 +- 자동화된 빌드 및 테스트 수행 +- 코드 품질 유지 및 버그 조기 발견 +### CD -- MVC, MVC2 -- 인프라 - - HTTPS - - DNS 서버 - - CI/CD -- 각자 intraid으로 된 브랜치를 만든 후 intraid로 폴더를 만들고 1일차 md로 작성해서 pr \ No newline at end of file +- 테스트를 통과한 코드를 자동으로 배포 준비 +- 포로덕션 환경으로 자동 배포 +- 안정적이고 빠른 릴리스 가능 From 5343a07cb4e4bfe31a2a8e0aeb57c5b7a292e1a6 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Wed, 13 Nov 2024 15:37:27 +0900 Subject: [PATCH 03/20] =?UTF-8?q?docs:=202=EC=9D=BC=EC=B0=A8=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1-2\354\235\274\354\260\250.md" | 22 +-- "taehyeon/2-3\354\235\274\354\260\250.md" | 186 ++++++++++++++++++ 2 files changed, 197 insertions(+), 11 deletions(-) rename "taehyeon/1\354\235\274\354\260\250.md" => "taehyeon/1-2\354\235\274\354\260\250.md" (99%) create mode 100644 "taehyeon/2-3\354\235\274\354\260\250.md" diff --git "a/taehyeon/1\354\235\274\354\260\250.md" "b/taehyeon/1-2\354\235\274\354\260\250.md" similarity index 99% rename from "taehyeon/1\354\235\274\354\260\250.md" rename to "taehyeon/1-2\354\235\274\354\260\250.md" index 9c8599a..a261982 100644 --- "a/taehyeon/1\354\235\274\354\260\250.md" +++ "b/taehyeon/1-2\354\235\274\354\260\250.md" @@ -175,15 +175,6 @@ ## 쿠키와 세션, JWT토큰 -### 쿠키와 세션 필요 이유 - -- HTTP 프로토콜의 특성인 비연결성과 무상태성을 보안하기 위해 필요 -- 서버가 클라이언트를 식별하고 이전 요청과의 연속성을 유지할 수 있음 -- 사용자별 맞춤 서비스 제공이 가능 -- 로그인 상태 유지, 장바구니 등의 정보를 관리할 수 있음 -- 쿠키를 사용하면 클라이언트 측에서 정보를 저장하여 서버 부하를 줄일 수 있음 -- 세션을 통해 중요 정보를 서버에서 안전하게 관리 - ### 쿠키 - 서버가 클라이언트의 웹 브라우저에 저장하는 작은 데이터 @@ -202,6 +193,15 @@ - 보안성이 쿠키보다 높음 - 서버 리소스 사용 +### 쿠키와 세션 필요 이유 + +- HTTP 프로토콜의 특성인 비연결성과 무상태성을 보안하기 위해 필요 +- 서버가 클라이언트를 식별하고 이전 요청과의 연속성을 유지할 수 있음 +- 사용자별 맞춤 서비스 제공이 가능 +- 로그인 상태 유지, 장바구니 등의 정보를 관리할 수 있음 +- 쿠키를 사용하면 클라이언트 측에서 정보를 저장하여 서버 부하를 줄일 수 있음 +- 세션을 통해 중요 정보를 서버에서 안전하게 관리 + ### JWT(JSON Web Token) - 정보를 안전하게 JSON 객체로 전송하기 위한 독립적인 토큰 @@ -259,7 +259,7 @@ - Controller가 모든 요청을 처리하고 Model과 View를 조정 - View는 순수하게 화면 표시만 담당 - UI 와 비즈니스 로직이 완전히 분리 -- 각 계층이 독립적으로 개발/수정 가ㅡㅇ +- 각 계층이 독립적으로 개발/수정 가능 - 컴포넌트의 재사용이 용이 ## HTTPS @@ -330,4 +330,4 @@ - 테스트를 통과한 코드를 자동으로 배포 준비 - 포로덕션 환경으로 자동 배포 -- 안정적이고 빠른 릴리스 가능 +- 안정적이고 빠른 릴리스 가능 \ No newline at end of file diff --git "a/taehyeon/2-3\354\235\274\354\260\250.md" "b/taehyeon/2-3\354\235\274\354\260\250.md" new file mode 100644 index 0000000..28826df --- /dev/null +++ "b/taehyeon/2-3\354\235\274\354\260\250.md" @@ -0,0 +1,186 @@ +# 2일차 + +## RDB (Relational Database) + +- 데이터를 2차원 테이블 형태로 표현하는 데이터베이스 +- 테이블 간의 관계를 통해 데이터를 구조화 +- 데이터 간의 상관관계에서 개체간의 관계를 표현 + +### 주요 특징 + +- 테이블은 행(records)과 열(columns)로 구성 +- 각 테이블은 고유한 기본키(Primary Key) 보유 +- 테이블 간 관계 설정 가능 +- 데이터의 독립성이 높음 + +## RDBMS (Relational Database Management System) + +- RDB를 생성,수정,관리할 수 있는 소프트웨어 시스템 +- SQL을 사용하여 데이터 베이스와 상호작용 + +### 주요 특징 + +- 다중 사용자 지원 +- 데이터 무결성 (ACID) +- 사용자 권한 관리, 데이터 접근 제어 + +## RDB vs NoSQL + +### RDB + +- 미리 정의된 스키마가 필요 +- 테이블 형태의 정형화된 구조 +- 데이터 중복이 최소화된 구조 +- 테이블 간의 관계 정의 +- 수직정 확장 위주 +- 복잡한 쿼리와 조인 연산 가능 +- ACID 특성 보장 +- 데이터 일관성 강조 + +#### 예시 + +- 금융, 회계등 데이터 정확성이 중요한 시스템 +- 복잡한 트랜잭션이 필요한 경우 +- 데이터 구조가 명확하고 변경이 적은 경우 + +### NoSQL + +- 유연한 스키마 +- 다양한 데이터 모델 지원(키-값) +- 데이터 중복 허용 +- 테이블 간 관계 정의 없음 +- 수평적 확장 가능 +- 단순 쿼리에 최적화 +- 높은 처리량과 빠른 응답 속도 +- 유연성과 확장성 강조 + +#### 예시 + +- 대용량 데이터 처리 +- 빠른 읽기/쓰기가 필요한 실시간 애플리케이션 +- 확장성이 중요한 서비스 + +## 테이블,컬럼,스키마 + +### 테이블 + +- 데이터를 저장하는 기본 단위 +- 행x과 열(Column)로 구성된 2차원 구조 + +#### 구성요소 + +- 행 (Row) + - 하나의 완전한 데이터 레코드 + - 엔티티의 특정 인스턴스를 표현 +- 열 (Column) + - 데이터의 속성을 정의 + - 특정 데이터 타입과 제약 조건을 가짐 + +### 스키마 + +- 데이터 베이스의 구조와 제약 조건에 관한 전반적인 명세를 정의한 메타데이터의 집합 + +#### 스키마 3계층 + +- 외부 스키마 + - 사용자 관점의 논리적 구조 정의 + - 여러 개의 외부 스키마 존재 가능 + - 동일 데이터에 대해 서로 다른 관점 제공 +- 개념 스키마 + - 조직 전체 관점의 논리적 구조 + - 데이터베이스당 하나만 존재 + - 데이터베이스의 전체적인 논리 구조 +- 내부 스키마 + - 물리적 저장 구조 정의 + - 실제 데이터 저장 방법 기술 + - 시스템 프로그래머나 설계자 관점의 스키마 + +## 데이터 모델링 + +- 데이터 베이스 설계의 핵심 과정 + +### 단계 + +1. 개념적 모델링 + - 핵심 엔티티 식별 + - 엔티티 간 관계 정의 + - 비즈니스 규칙 정립 +2. 논리적 모델링 (정규화) + - 정규화 수행 + - 스키마 정의 + - 속성 정의 +3. 물리적 모델링 (역정규화) + - 데이터 베이스 특성 반영 + - 인덱싱 전략 수립 + - 파티셔닝 계획 + +### 데이터 정규화 + +- 데이터 무결성 확보 + - 중복 제거 + - 일관성 유지 + - 데이터베이스 구조 개선 + +#### 장점 + +- 데이터 중복 감소 +- 데이터 베이스 성능 향상 + +#### 단점 + +- 복잡한 조인 쿼리 +- 성능 저하 가능성 + +## 트랜잭션 + +- 데이터베이스의 상태를 변화시키는 하나의 논리적 작업 단위 + +### 트랜잭션의 특징 (ACID) + +1. 원자성 (Atomicity) + - 트랜잭션의 모든 연산이 완전히 수행되거나 전혀 수행되지 않아야 함 +2. 일관성 (Consistency) + - 트랜잭션 실행 전후의 데이터 베이스가 일관된 상태를 유지 +3. 격리성 (Isolation) + - 동시에 실행되는 트랜젹션들이 서로 영향을 미치지 않도록 보장 +4. 지속성 (Durability) + - 성공적으로 완료된 트랜잭션의 결과는 영구적으로 보존 + +## 데이터 무결성 + +- 개체 무결성 + - 테이블의 각 행이 고유하게 식별되도록 보장 + - 기본 키는 NULL값이나 중복값을 가질 수 없음 +- 도메인 무결성 + - 특정 속성 값이 정의된 도메인에 속해야 함 + - 데이터 형식, 값의 범위 등을 제한 +- 참조 무결성 + - 외래 키는 참조하는 테이블의 기본키와 일치해야함 + - 참조할 수 없는 값을 가질 수 없음 +- 사용자 정의 무결성 + - 특정 열에 비즈니스 규칙 적용 + +### 데이터 무결성의 중요성 + +- 데이터 품질 보장 + - 오류 데이터 방지 + - 일관성 유지 +- 시스템 신뢰성 + - 데이터 정확성 보장 + - 비즈니스 로직 보호 +- 유지보수 용이성 + - 데이터 관리 효율성 + - 오류 추적 용이 + +## SQL(Structured Query Language) + +- 관계형 데이터베이스 시스템과 상호작용하기 위해 표준화된 프로그래밍 언어 + +### SQL 명령어 종류 + +1. 데이터 구조 정의 언어 DDL (Data Definiton Language) + - ex) CREATE,DROP,ALTER +2. 데이터 조작 언어 DML (Data Manipulation Language) + - ex) INSERT,UPDATE,DELETE,SELECT +3. 데이터 접근 권한 제어 언어 DCL (Data Control Language) + - ex) GRANT,REVOKE \ No newline at end of file From de1c5246a9a39dad3f2910df8d046984e5f545e7 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Wed, 13 Nov 2024 18:06:38 +0900 Subject: [PATCH 04/20] =?UTF-8?q?docs:=203=EC=9D=BC=EC=B0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "taehyeon/2-3\354\235\274\354\260\250.md" | 4 +- "taehyeon/3\354\235\274\354\260\250.md" | 90 ++++++++++++++++++++ "taehyeon/3\354\235\274\354\260\250ERD.png" | Bin 0 -> 278081 bytes 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 "taehyeon/3\354\235\274\354\260\250.md" create mode 100644 "taehyeon/3\354\235\274\354\260\250ERD.png" diff --git "a/taehyeon/2-3\354\235\274\354\260\250.md" "b/taehyeon/2-3\354\235\274\354\260\250.md" index 28826df..d62a820 100644 --- "a/taehyeon/2-3\354\235\274\354\260\250.md" +++ "b/taehyeon/2-3\354\235\274\354\260\250.md" @@ -65,7 +65,7 @@ ### 테이블 - 데이터를 저장하는 기본 단위 -- 행x과 열(Column)로 구성된 2차원 구조 +- 행(Row)과 열(Column)로 구성된 2차원 구조 #### 구성요소 @@ -148,7 +148,7 @@ ## 데이터 무결성 -- 개체 무결성 +- 엔티티 무결성 - 테이블의 각 행이 고유하게 식별되도록 보장 - 기본 키는 NULL값이나 중복값을 가질 수 없음 - 도메인 무결성 diff --git "a/taehyeon/3\354\235\274\354\260\250.md" "b/taehyeon/3\354\235\274\354\260\250.md" new file mode 100644 index 0000000..dbad4c7 --- /dev/null +++ "b/taehyeon/3\354\235\274\354\260\250.md" @@ -0,0 +1,90 @@ +# 3일차 + +## @Embeddable,@Embedded + +### @Embeddable + +- 값 타입을 정의하는 클래스에 선언 +- 해당 클래스가 다른 엔티티의 일부로 포함될 수 있음을 나타냄 +- 독자적인 생명주기가 없음 + +### @Embedded + +- 값 타입을 사용하는 엔티티의 필드에 선언 +- @Embeddable로 정의된 값 타입을 포함함을 나타냄 +- 엔티티의 일부로 테이블에 매핑됨 + +### 주의점 + +- 테이블 구조 유지 + - @Embeddable 클래스의 필드들은 해당 클래스를 포함하는 엔티티의 테이블에 직접 컬럼으로 매핑 + - 별도의 테이블이 생성되지 않음 +- 컬럼 이름 + - @Embeddable 클래스의 필드명이 그대로 컬럼명으로 사용 + - @AttributeOverride를 사용하여 컬럼명을 재정의할 수 있음 +- 중첩 @Embeddable + 계층 구조가 생성되지 않고 모든 필드가 같은 레벨의 컬럼으로 생성됨 +- 관계 매핑 + - @Embeddable 클래스 내에 @ManyToOne 등의 관계가 있으면, 해당 관계에 대한 외래 키 컬럼이 테이블에 추가됩니다. +- NULL 처리 + - @Embeddable 객체가 null이면 관련된 모든 컬럼이 NULL로 설정 됨 + +## 데이터베이스 연관 관계 설정 + +### @OneToOne (1:1) + +- 양쪽 엔티티가 서로 하나의 관계만 가짐 + +### @ManyToOne (N:1) + +- 다대일 관계에서 가장 많이 사용 + - 조회 성능이 좋음 + - 조인 쿼리가 단순함 +- 외래키는 항상 다(N)쪽에 있음 + +### @OneToMany (1:N) + +- 일대다 관계 +- 컬렉션을 사용하여 여러 엔티티 참조 + +### @ManyToMany + +- 중간 테이블이 자동으로 생성됨 +- 보통 중간 테이블을 엔티티로 승격하여 사용 +- 실무에서 사용을 지양 + - 중간 테이블에 대한 세밀한 제어 불가 + - 복잡한 비즈니스 로직 구현의 어려움 + - 확장성 제한 + +### 연관 관계 설정시 주의점 + +- 연관관계 편의 메서드 구현 + - 어떤 엔티티의 값을 변경할 때 연관 되어 있는 모든 엔티티에도 값을 변경 + +### 중간테이블 + +- @ManyToMany 관계인 경우 사용 +- 다대다 관계를 일대다 다대일 관계로 만들어줌 + +### 연관관계의 주인 + +- 외래 키가 있는 곳이 연관관계의 주인 +- mappedBy 속성으로 주인 지정 +- 주인만이 외래 키를 관리할 수 있음 + +## PK(Primary Key), FK(Foreign Key) + +### PK(Primary Key) + +- 테이블의 각 레코드를 고유하게 식별하는 키 +- NULL 값을 가질 수 없음 +- 중복된 값을 가질 수 없음 + +### Foreign Key + +- 다른 테이블의 PK를 참조하는 키 +- 테이블 간의 관계를 정의 +- NULL 값 허용 가능 +- 중복된 값 허용 가능 + +![ERD](3일차ERD.png) \ No newline at end of file diff --git "a/taehyeon/3\354\235\274\354\260\250ERD.png" "b/taehyeon/3\354\235\274\354\260\250ERD.png" new file mode 100644 index 0000000000000000000000000000000000000000..3b6cd143318759859e35e4fa99932be737f27586 GIT binary patch literal 278081 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�WtHcU2HU}rNR$xN z57|GwTd|b5!?)nHG2uVqbXBR-Io)e8Z(8g?>wwV#*Q%qi(zL<^>mqP;Rf_RHLf>#A z*M^aGBb0t#%_~|f=JB{jcAjAz4A9G>FqNp!m|GukJPKPD;WwD1q=yd;%v(Q+^vw=n zDp^~+SHj!QX*KhP4q@_*d)ca5fv&TtUIYH`fBNqUizugXX5Q6$3b2;WJ`=NozV@M@anFOTj zQ2Z~b&37+mM~>9j*lMrmJDsTz(&F9r5Bwua?^{tVA)G3 z$S)iHF+7|d6}r4}bt7%CTq;i)XEoux2iHvc66W9`xb$udl(4ml6vF}NFRG=g0|N$$ z*9qxK0yz@E@RZjoV{8H@Q%znpJs*6#zS!uLmicbOQtwF*RQb+QSwQLMu&lYC`i&*W zrTaPvTvq7^PqsgGuV0eKU(n0tSPMZM2IC}YifoI%+;Jq8-hLri{V2DR^3KAoE&s&g zN)K0WJuLtb4?uCAfEd(-Aa<<%k`@l7=e&UUAU62N^EA{+gi|hfRyjt1xOL)s19fcQhh9$(VY3Pi3Q(i5p!f8gP$wisZf!iO0DfVOWJH3I2k4XRG%Mx1*ds-E5# z8heP>G`a8bgIKd-%tUBcCRM|k{ zr#XS#u}2iS%(oEskZ2=epBoHZnAj*H$--J&Cm}zoVk}wbi@#_IFq247O@X=Wn>FVp z2yp#tSPasefiH$QbflKlu7T=igS&hL6UBUM_AwEC?h>}wjN-PU&BYe9el-96IfDl1 zMqd89KxQyf$|a+I{3k3WDVq%h>uh;m8t}7(Mm5x$a%S}2Y}-U!qQaApd`~Y^#g(rR~UFmR)o(*MuHJvl*(Cl(P+a81l)p z2@yVj{uMO)cy-2Hp$~5m5Ee7xO#f)Q{@I-+@3FzDyKCz{#XSA=%DD9#S+LhXl$%?u zaA;C`2ti<@%yX@z5ayR?4=ZuFQIrCcv9%J}iYJ|aG_M=NF(Zh>9r8>>@_{m!*g5GQ zNk8>q4k~o9asqJJo#5(CZkOy`E;1~O>h>xd@jW4*^JKfHp0XW%3iVR?XATh_On7O2 z+yM-?U+bbC`3Ro1)|I)hlY=~91b*G$f@K1aUA*mCf(b|Y2g~VraKxp$=O4%yw4IdF zjzl*>_rE(&%qBNM*TbOWxUXy4Lt%2PyU*5seBD>IT)2qK>~ocuB_3IJVFkvW$YWQY zEYq?&Cptc=A7Jv`v+R>X)X#u18AW(Rxxab%CV z7(j`*uk`BcaVR(kK>GzD2Jll_&?w}>Sw(}vTO5Scx{Rvh4thilYy=v*p^iWyTE!3i zv4ss#D@1)yo+YX_u1}6N{uT=GSEc#?QO|!c9Q8=cE4YGOKrXV+b}$7UG)F6gIz{Li zX|@trNZxUHnu$WgvzL|U@CA+4u!al#P?~OsAJ;?M3^ZHMM8sq6*=tkzQ(_2V5CNZ>)~RcZ)^KF2?b9b5Dx>0cmpwj&dJrU zFA|zdpHFhZzA~tPdO3-ns2>kU`@Fz&#z(HZ>U*m2GL_ zg44^ITASowKn-iOW^`AZs6*)Rd;BjrJC|Rpex2h< z*(T`oEJN92XyQ=w>#?D%ciIg_lj~0~8Bg$6MNY>iDIXllD}UjkN#5yqWiqFHe*ULF ze+9gu>y1r$GNtIQA^bnu3qs~l%Ikf3Y4N}M4YN1vp~&?cT0Ne6(GmX8>d&i`${Awlp+Hpca{CV!E- z9pVoNPfqM^0j(@odibt0<7lfxW$eGrp2>d*@b%4KAphPLPW$6s6(|y3rq1j7P0?|t z<9+4yKg}vc^_p7fw2snB-B=ZmqEipe>bt++bBOMly=_8NUQt!kl*F0ceIYq;<+I}% zKK8XxrUB0HDWA-pmwvlGSnrhDh{zI8DToO}*oYE&Jt<>j9jy$2rOk9aLuJ_>wt@m8PCuUfWei(j@I{Z1Up2o!y)DjLTVyp-y*XV3aeX#kqhLP zqQa?MJcJvBTMb37x!x0JOV-~b9WiFfyvY(Pmo@)+yDAjzy9%jigm?JL*m=M3r{sOd z5l?%gl0rik8zO~4b$Z=i+<~-GgC2FuD*QpChXJg)IXc{Y$Y4+a25-X%2n+gfyYJz&YX^(A|<4I!KtW)*R-gA4*cc!MAu)Jmx#PBXsFu--jn_&JuZ1n9jMq;VOeS_hfRXl z!I4iBx&SCHeT&lhC_1g~d?qrV`{>T0dNigJZ=jZO-YHUVX6@z5N|pDqw?+=AZ~1D* zl-otR=9C58ul@H_ zTUW$(C9Sp>GRW`2TfnxA5Qe3|EX6z;(svVp>}WV^u334mKgj!qwHH`SyS?%s zKJ7aRcBV(p_7#uIV)aklJ8(=_{aLte9Ee2NR71!s5xo6rGV-|NvI|1EJ~n_F=nb!9{z)G17o_O0EF1fLpceozHbSx&M@^WMKq%Ru zo|AzR%liO=Nj>k@2iQCoUHF!MTXIB@>~ChmSDWYbdgJhdF;TEjgE;O*AV6WQx_*Wr z=rnccOgb(L{I|_`CY&fxkv`QxG12k1)C9`&VCHz+6IdDH(^>*Yc7W2xBlqTPTB6%a zy)+fZ=WSnDuA5Z#p1fa2ovGshfS9Uk*6a9-vjB-bkOBS!C{KIH4GFcCYKNPDPN=H?R?BXaev zYsXU&5911NNMxswHzh6SFL|_aurw|_Yz)upJ%~p(AhYnGFCMRgT#HbK5x}Uy#rOk| zWVOA15VGX`qZy&-J^Nk$#U192t$!4wYX5%}qY$?+S(z4n93YejqbW!Awt@1v5PS&K ziFN^Db1)aZ+UQe;$I#(GnVhFtXST`nLt4T=0m6T)%3rtBe>U-9Go}%zkChiO)BtKw zmT9dzo*IA+!L;^xPJ+P78>rp{+~j1M{=X33`ws?LtSg$LzVYU`3pLwsxB|Z~>AlAN z>a4e?>(np#o}?<$ayjqceBZ32yQ?$SL5enOcH$A`wsB)GnLi>_cRDnhXwuy!noh4^ zsv4%!*)2u~fnYSirTh{h?qC6OQ&wB^s=HkQHnQ-F=)o^vkIPf!N0|skncn?9tA=%STBWvN|R4yfD{B-(<{>&)4>2o^0)Atqw ze)XhzZ5Q9Le6svBzzoVi#qrT75PO0o7+jfh3Nkj!TQmVc0uafYW9thY=~IOP8q5G1 zhzx@A5QLd7(lN-C--p0d5U0M;*Zgdif!z!NuRRQQU!lZ+^7u{<#FMKZp958qQAZg0 ztk(+|JG`|?1%Aj0>KpWgI#Cq#0Zgb|f2Eon0bFHi$|kPX17 zCY*G>>0X#$7m4`qUV1?G2WdH413cR=Z6d@E!D_PVDG@Gw!K!#JT}dAW(+J{AsE=ws zC+Ft~CjKL7GdIg$);V9Ambp4@S8g(Nzl0pI-lm)&UBU*R6`X&(jW>v*H%mA4%W~`^ zQqrF9>bp^)t4SOOa>|I;@eO@GFTh55-9JnQoT(XQNWuGL zm^aZvP8yaQPyn8Kgsr~CQ`0+598!rG<8uk#l1%~2NvH`&66Oj)0O-jGu@X=-y4Hji9Eq(zC(8P?DNGe17h_!@elvTL=+Arw<`mLsB zJ(Joqcb(6?disXPdJ&a;G$5z=7U+_$*}Yxb=0iD9 zFci6{%fqMSd(T8~VuIq9R|tE!yk>Ti3)98(`d;nvP*kuljXd5ZhjqK>i}P#s&?LaN z_f(ogsn8ubV+@AO58N@wH8B{od|t38rLKz4eeFvf<@<*nl*pySR{Q^c01`h6#cd&k zR5R(zgaU^3>jaR)wU_Dcxvk`f#g{dVrFuM z7lvBPkvhGOq-w>WA6YfpL@Q%klcg>C-fL&+IqzRcX>*-S9W|Ik3*bgvU8Qq=mt(+l z9^44cS!>pbfHQd@65^n1%{I|tYpc(UN?hj!iK(MsM{cxDyIQ6-W(6o?B(5O)#wW_l zKRmKEf?Tz26vS zC}-p}V5uE=Z5fj?%I<5@T;Vq-%B<0mzADL4mF3CiY>Vlc1G;@H+)5u zOpC?zgBu+jPj_sVc08O4tmhI|Z&&g-Ub3M3CD-8z69O|&5#PdGu|k#UBR-jrxJ04e zjzs+AwQ(6K#nZ|sg5uk^ka}z^bnTr=0`NJ+^iHGNeLCxGU}~lpW`>>~*kHW}Q=kk<#g*P zhbbaX*=;FXepY;P@A8ppF5BWS?$e3{`5E_lIAJiFHr!-;upisEx0Q6T6|Uk^O>flk z)N^ZcEk67TS8x>+yAtwc>9_m^Q(|GC6Xc68%aYrxv5%9qRD-#S3xCnqe=X?%jNDlL zC%FF;>SJiA&>vJN6dY`1*dE6-%=*YsO3T*v?B}3xm2f4O%`(F9Q@d)Kw+B`Uulw#f zAH>3KIUEfF$TB&u+RjTQ)B3NUQGGetS;K3$vsmP8e6ZagP&kmZ^~;KJy(0D|Yuk9Z zZ{*F$$sa$t4-MMtxsAGi0NsC|=Yz^^#{d2hSjDDZ#c~2hsUF@tZdk?$^DK*y_z>*) zXeYsWWZ>GeYx{iSO0X3oe!ErYybEVl*Og@#oMLI3(xhnZPnAS}xxxB`nGH`;9gf55 zlhkiDqwWuMzMMCLcFGD(7G1|Oj@}W}W%!Zum};Khm~z7z6he1`ZJ5JkFCE3iuGv5b zfB~_HQ`_rbGzG+6E~+i+nn9B0?7zqeFGS7Ai?Vx6e}EZUUJzMco=e>Ok+#Va6g&Jl zNjO-kGZzHsOFM*vebSXDw&SY>-8x*cRRj4}x>hz$&bPc)qmsBo3x(S1*^QOXk7rL+ zxNkCQF2!3oXRo!xDu)WK`+r(`3aRWaO}em*=j|7>)GsriC5uAtY4^CVdM~Xo-;#YK zJJzg^8N~sCC&71;{s#F7Zs9i=y;Db$+@T5r(n= z*??VFLhX%o1xUD6$xUD_vfC_vHQ0!+t8BG9mYmU&B1b5~u4i3mA`Gz87&%t8+{|-J z4tlz<7gR|JIyzxkbKx|6*V#}%ZSb4h1Ai&ye{){x(s6(Uu_a!waEt@wJ)dUzh<=Wq_fy8zfye3v;WpgDDR!j$9t#3V)YzY1)q1X>a{)4Lrk~b+( z7iAW20tkAC{V6n3`IE}%TOk_0#C>ua6U!Hf46AY%zo^N;IhK9MRYC9bM^}j=Fjss5 zes~D1Y}2JVs7bNfI+WJ)k98IY-H96oOOcuq91CyEwPqAy9uO1Lu_hXvwrDOTAGVWk z%FLRYhhY9OyEXTyQsMVgTeF81xvf$VdsCYxkTjxo9rY@#Q0W{aS_q_RY6g^EZ3@|m zG@oOQBh?TUcyCf&k35Og-nO?J6PCe)G=_zse%XHOg&(lzS z*+~bx(=f=avoc?%Q{vBU-t@UsEw=Ons@z!iOM~Ix#MRU`fnzsTcDX@(Fw#cvAM`u4B>FYi(*v z8M+>GlJ+||uU%a2O{CIR6(fi?5KSUciF)q?Cye)cjd{qst(9BQfHXcl@;(I&zvr7D z+ELFaA=>1wdSv`+r;sD$bn1C*3C?p3P2k=Tt5UsldBVd1s)VQJ3qckIxN zpnt1XBJJ+{94%i_8f|o3m2lqj!>F+sQi2)pfhN2V`BQs0qk9 zaZP4j!T7odS~H;0_If3+KVKz8(OGUaK(SJfsIHrh9bOrbcJ#M5B64`R6LjkB(qn`= zLDVJm17+{?-X;zNVu`S)=cXFQekuF;;#-0?Yv+Tjr^8V7BiA>|Y zxus^Y9PTAgr?`BfcXanljaDP$PDOo$OnBhf0*^$kF2(Ej_%(IHc57kWxp}ZUrUMca zQxtmcc9&lmWJ?>RBMQw5SCPzUDI#no5I7_wMnbn)KeJ`F}XgibGCw<9j<9@|V-ZuhQP; zEl%F^=dzu%U1T`{X>?vHXxN$^j=EfuUa5Exyf3jC<=-S9HJev}a|3+G5smZ3WdjLw ziJX#Wa^h9U_qBeCstbCXh_XhlRqnP_D*YZnt@l1+Vi~b#zseW=;`h;yc>#Z+LUXOY>;`WzQAK*~_9LPfR)Zbs^8)->*Z=}h8@P*0ad2tInOiSzI>8sw;wyuw(C!Y(Q{w;%yTw6qX?MU*^ ziF#WpuYG9Qjh)F=3KtQ^%X(5(`$C4iHmtlhNZ&4&X)mC6cS8u2kg=s*XvM5{?S0im zwp`JCOZX+02?>w=TX~KxJ0qJ|Q-|Jey2N*qouz{;w06-ZF8yUAGFrrszo26;L^+}| zvnEnHjIlYmbq$NHm6#VIf&(6d;MP5gwljql?Kd>BQMB_ z=-fV~fvE2?W2TKnSP0QI%bMO1aw1jpG7f&55b!n`5V#X@TfsMb-6g;je?@pBM;%l& zXa`8v%HfbjBLd0LNL~TBUO{So1~OU7Pg@MxTpBMhjqk$gdjRj(I`BVh#lV@ct@Gvu z^s@aLpw~vC9UKcVA?wd;$-oa~ghI2UGk~=#V;C1(NU{+G4tY{mPstgSo}&Gp%tK@R z9CwxtKF@Lwc@t%BRiL(=R#&vxP{gxW-^0&(Ez@pLEv~v~oKe**M6+A6^2U*NP;KP-m zE(Z_Da1A8{7n3x#0&XV^zPT+tS@T*S(L|MR>4F}p6mTOu26@OY-HIInJn9Kqy{*(X zO|3MO+BU!#WLO^jsDs)h`=vD%S>EN{KL#AQ)mI^`jC^w2xwI?d<7Qd=I2(KM6&qgc ztaM``u#KYhPK=vrF5s50U}?YstnfN07n^zopHgv;Zs_+4%GzDNmA6-KR5gRtbD1w$hL$*TRhC{zH;mx`;p`b6}y0+bbEyTMFOuQ+_T^2DJYX>cJa{G+dUQri1^k; z*SiiZZ4jMxS7uJgsE3ibw@RAaxUG$5adEN%+BYTefn38B#(d|cSH4&IiJCYpIc4b> zAEhe1zy&}^1uaP2#6=r#o=DZcoObFP43qU+6|pK+z3de;YR9Zv@KYHd!#ozuYr91f z&vw|_yXjLMO)GS#6P*yBn7nd^hBZ)nr4t!RllVL$daXv<4JD!jU)2gGNo1IO5Ri3Y zzCA?hp-R-Cj`rgrzq1)ko@`MX9yJ`49nNv<&Gc9P77fp7C%@0>wBpX%j}ASw|0f+? zX7k8(+JgWmTOo`=Udl$p>$?tKgSQ=!%&)}8+OfrLL_s5$UX-JR!#(yfb23hBc9n<6 z07n7IEzTFvs3sg0n!L44eC-c+&hQG zHd~Q{hIMq@_8@Ke3N;JgUmEjAWzEwEx9G*l&V&PyazA zJ)EcW$5*o>&nir&Pd{%eJOz1h_teLM=}sdzYm7i{*|5($&ft^TXWo18vnzKEd<_dT z+V!I=F$l;o6;Mt%r26@+X=EjP?Ymgw`;O-v=8n|p02<2QW64J#C;Ur3WfK9kg$ zpeLi%6yY6m#Si#Jc(um3wD8TikWntJE%w*dI5v=}&|eS&rdn9-;Z%#qkgjeyoole< z1MHj@q_A#3W*qIA%vReUgd7)uSF~Robmt)8aXL8$KqB%K$jzuXTOoxiE-i?7Ao^*|?K76KeMgPAW;T!s{lsLt>ntc`cpLQ;1gp*YvBPTKP3Sbj z073P;OEGr)%X9-5asiaQaAtB=DRVctVq&;(%_QfT^PMmj+9lg($=d$7$y86O{l&d* z2J%fRe#q#STc?_4OUjQ17I(qi6S|;4!A$*imMX`O#jn*1rBa$6=nA^rukziG9ygqz z_Gx;|rDH9IbRQb>e-&#pfUoLijXVXhkp3rB!^Em|5Ud3!tb=c#KR5A2Azj$}JmU*` zISAvs51I7_+XdHjm2cC&qe*$OLL%#h(o=GSBLEX6tTTRwH zKSo`}+@||x;{A+b3C?}ayU+6RoF2Dql++s5eKwX}8D5UIu@g>kym_Mm__O-yK@wg} z|9wQ(dK!XOUdmL%3pY_{^tTqk#gY2LXg4~9eo)j{4$w;KA^3E~oR4AmnD|d{DS%$I z3zkwf;dEFq%IY}5wSJp1c7eMnGltkyUwAfqrgp^%_t9>G zy8S1|2Ba&b?D_o$G7-LKa6BG)j~ytfy0z-|nKa#z$c49}B~Ri*L4qI2{(Nn)muwU= z_ug`6>a%$Hf@I(=8J9%Nz#m{=)JpMT?xEg_W$RAD$s9nb)Nk-~7@N4{IpHVUu5($K zto0dDYY|yKcT6;H zUBj3h>a3)QHZ~87nFoJ#G;sDoV_r-cS2Z;Lr}W&{807AISsFBv>ul^vphI@=!w1b) z#qS#KV`H}1?DN>t8dkL7h>~>U%b+n1l@Zd_aW13$?jsm|U}Mbvz#25Ry2tl>c$l=# zwNo~VluCx-AD5luM$GP9rN{-`Xur!;`>B48g?)ET=muHFVjWuM4%3~9yJS#E-sY7j z-`=!KQgIohPm(4FN>8clUu%5{t9yJ)pt>$Wk;GtV6S?gVEjLYvIbVcxp6G*-Rbd6= zkmlHX{F)63O_swedxz{>_>Wxf_tZXaSI%sqE4R?Kb>o@_t!mT@4H`1C`oW;T3OD9rk}r} zRP4mPlM-)K9RzJ#7$8m=B@S7wgtVQr9>v6+`w}u*KoN+>iRCwCi{{U^p!f=Jp481 z^VOFM>$(jeiM=)^(wVT=5*`9N@78kz_sgb|%_rQdt?;DIogY+TDaz~ES{7k`s90N9 zwYt<*avrOfH4VgG+)s=oq^Ozn>V3;3#p9&xd^Pm->3^)k_t+=m^OW9 ztstZrg9J6r2$U9e?xY&1A(K|qAF0vd-hnWqn8ygPINqwLP4&+(Zvn|xE=hjcB<HH}AFGjE|{ zeD7XI;RL<1SOiWWevX_udB*y>H+K#F1>)Ilv#M){nYCxWsfJ3tO?l!yoB@O&9bw{2 z9z}sJzbfS@b8Grk;*6@vO$(7N1A8TSMRZlcGcmqiepg|HO@z6KhaHhC0W2Z1WNl!M z!rZDltYhT^)dMfvkqLAxQ1*=mX^;y{3wL2tNzZE!T?=f9K$Jcqkaur@RB0ncihX@+fa?VH$T4c^+yNTg#gS#G(U zCU%21x9Cl&d#klk_tPF-TDSY>`<_6zkm4IZ<9BzTSMq1xtQ9lfYBtS!^|t+j1oOyN zn=|7Mb-b1{W6KAZ@#@rilv}-+k<_Q6AJ9Gh1@H5sd41GAbRJE#Q6I@qUR4xGFNhNc zcx$mcPf-*l{2N;xe~MA@RS?v4ED>0SdMf5VH9S?B90+7%kV`tG@fT&?u6g| zQOt5JNrl#e?O^Y@@abUomev^lFU#E<1+OaIZ$J`dKl+_D8iHQ`*(v0m7F{RAUhk5w z%gL^JMtpiqRMJX_kyxQd(}Dgwz$oQ*yKygO$dWl9rr>BjkD}< zNg*iGixcy{-dmd^4)=Ot*&(>u*2xVRc>C`YDYvXz*HJp1~`l`@Hb2m_`3uU)}{!lCZ%j(g6WN; z&3ipex|^X6Uzos8Tzu2@{+}N6#%Et0F@-;A#^*3GjP#hnDr?k%KX@iP<{h#v?+h6H zMlL+>XOUsA&PjM=_)bE$I zU4|6TzrRK=1ktL=QKzbYnzlhp>4xofn`XV%)x;|~Da8jMN0~Pc_LmR#N24k@FKM1t zOW?eUTUn`iwcCf>>$8K({OSV)kE@XLv)Y@?f{9;0M=3iW-P_JN*e0FzO|iJ*eY!A@ zvJ6UAw+I&ej(bWA-Z{&bfasts68$g=$K$f>NQI=vTX&d^<#inu;6ZKS33 z2zNE_2@ksO+~g^o!KXo51atS~?@I?72#u?;UWve(R&s~VcQSR-_+Py$m*-6JWb86X zjG5dvy|Qn4+2anZ-gniV z5y7<2L-mzyJ{UxKE^VA+@`>f?Aq51wJ0C||C~f|J<$lfm#IWr3^|Rh7?|w@mkVm85 zLpp7qA+B_6E~Sf1Kw0(|^2*x|h0U=$N_S4M1Vd)D+%(U32){5D#NR$&98~wTquX*Uf0Ogo${NTi0w;G%Ty-lMOn|qH^tnoMn{I36Bx&m#f{&%v6vE!t9N8QOwF^ z^B=wX3|~J=yVEkuwEHrD|A8-eXix9H6E*ALl$C`m9>E<`|Y1Sx_6I zasHk3U-Rl;S?(zCJ@UIA*4O$^*R-6bY%@UD(e9p>#q$RP?Vh)sZ@^v@KB*@TZ&rFa zdx?-X%M_Q&ttD%34vVIdqipt`Zl@)A4%!9mmP{*q#$PoGqozvW+Z{czlO~D1qP2=! zb%(4fjlU3Rf4UaS<&c(5SMPGAdKd@c)V}%gw%1^HqO6kk`FrQjm~?&8y7ZySh~+ip zg0?LV(wwLg?h<~%&K8~ZQR`~S^DB`&5alLC|6L8ubFQ4DR-RKIA4 zqpJ<4jYIF?0z_r2W-7kps_5mWGwAA?`l))LtPAmfHPSw3MPUqW9cdUC*ID+hUL+svCJRzVnb=BG;#yUUM?J8W)aF-`8c z(Fn|EkHIpPF5NtiE4HqW@a!wq1fsBL-3gGFC~!2OeM8A!2NPcVq;f~=#LyM*BTbk7 zohpaD!xeIvRLZ&16Zf~PF3C|DZ_V|WUG^L+-M3wB@sCS+D_aKg?W*@}_Y_Y^FBMN@ z@3##vZ$`N=t+RA#?(lwk)izNk^3=u183lV`#cV5HPyAdKHq44(?i5O-Q;Twrr0Z*k zp0Qa~cz*{K^~Pe{g=Ha<7II4Xn$|N7>Ug|Uu$j-W&^Pnn{L4!g(;FUVbwzST9xQ?F|>BJni;|L@P+A7rNkqW@*MSb!p2&;27QgxnRoOQgpMe= zsuWTCk3*wU6W_ggTRCvq`}~=4Mr-A&DkQ>*H}D)T{@3PaG&4&rGj+Si(krH+oTc6m z7RM8m#UPfZh->b;Z^Pe8m*-znrdsNW`&8?NK9i|wb3d|WbFTa6gTd!d3S>cE0MLDPSg-Y!ha%MMH(U{MRxvK8rH}iMnoK73Q3O1kZN-Yqcu6f^Q>iG<#0fGB)TxcRFjefs;iHso-&?*Nsg<>{#9K5qyHZP_UPNZ z|D8sGRadClq`Y%~RqZo1`TjrF-aH=4{f+;x6iPx0WsTyf(cUbYO@OTU-EHzDA%6q@x;JAq3H_j} zBzd%xf{_2y^;ztBu~ZwuNUW9^JYZ9B(4T zhfsSoo+oM`>smYe!SyKbS;>1#ncp7O+CCso#0O6>qsaGz^;%;(O=S|Vwh{iV`PK^N zXt%M@_1UoBs^}8g9nd4uf^kb^q$4t(`Zed1Mbt`c)6ti^tCgWV+jqy4wpF>~w#3eC zeQQeq!;zJd*^mkQmbcAfB(%N7Qp4@F*@gO^EBkr%h7U+Svo@AdzH0&U^f9)V#eYAj zIHGJofdt}qt)NG#|2fZm(e+lwGMB;P{btzYqqjker=m*)Pv3?#KG~i6I1D`Cty3PI zDe)@Qtp#2P)L(z?O#5D=-1mLeV9Wnv>iGn>j|dMWmqbNDYHmF2u!CM~DR0zM2!JeI zlGFcpk>(-iF{%AOk4cj8?wGH4LUz>DXbSTlJC0)CjJ$ccm9dO-X;TpIeu3zC%&WX( z2iggnEp~+SE3$qrhol=-pjJ2bA#9HAeT}FpL{M$yn6J&QM|HW+0YnIekMXV z3S1!hzcP>i`?A?M?F7P_#mon~jJ{HOgMV5b}a4N*3>secyH6T0eLApFD ze08FR|CtK3EG0ADxq_~=2oGGydadSy?ENA8GuIh9NHC)U2|BG_evS-)wlo|=EV4Z0 z?Tt?Cstfpvu3jwnp<^56G53%}8bOHkj`&9*NYU?dNsc7LV7BuQzhfFI>f>38<*8J6 zxye?N#1A^RfTroC=U;zT9M7>tC{ub5R2j6m6M?2*;K)irqnGG+sk$3`W9n=_dM=O5 zi|K?Chm{MyKeA_h4EG>kQOF1k-I49CqH+x;K_ z_#Pp40wJBN(pivoiHr(3V_J9M)3z@l#Stl0C%$cYS^?zO}MuI06MV~=8 zEgyGh87>UK%bJ%f^^S;gWO*(GJc&kn$~rv>q^;h_Ir_{dO`}__pCS445z4#dVg3eh zPi2ukA0#?&{buYwz4yd-7fJQyR_$1B!bfVU)eMRevT%T7yru0B9>~R2{{_%7lcb>p zG=r>+H?Z$T#IW60fFXXw6mL-LRoA&UiU(dU2VA{BZtVfO#m6YE8(LI6`nhr~(P%vvYTjlbwtK z|HkPa++oOih5uq|yD?%INSbg!!MUS>h%W{S<9=>ilpuM+yz8H)2RJdj1EMEx@O{_w z8)fT256<#QO(%a$*~-&7K=h!&_wzc^0SuWhD=;bqh&%QY6E*|;OAdj436{8Ou~q)A zHA?_dQDgj8v3*YdOOF`zD0FNn>#<**6KuYe^%Q23B{aad_F$t()OK+>`PU z^~>Z9Z~ZoD9|9^tYqMn1m3t%^Iq>qy;hD->2>>_Ut>_nV zu6976_`cjE0YhM;SNkr{z%S~&4;oeq_yo)AFV()XKEjjr%U?<(Hv$^~CLUhm>HZe`%?B2<(Y^jX`rUs?zqtJQmR6(H4#J$61HT6GMh|yK-<*SQrZNd1s?g zf0JD3sbhHUdzERsW8`dFa}^QZ4vm+yx0k#8<^Cbt5J9|st9!S0rroEOx`v(F+b!=L zqz8tV?of$TKXloln>3Se_IbDL8UP9E41+q^cU@WCjfM~1;Ro4i`9eER8YXE#{<|LxaDNt|F8WX+6>Zl+ zOab^kFqxgJAN|Tl!&5WQRTf389J82HtzBlmlEhk$yu;<4fEzcsGfs|%XQNYF~8f!2ss{0tevFc*1*sS?eYXk#+Qe{9y*>KzPHL2ddmXT z>cN?M4ybJapU7c_8B9TYfC!u0#vx%3_c@=ENt=^@SxO`eYFyKTtaTTD8IYY0Wn4(w zJD7Sw6#+|uTEKDu31r#N0cQK%DZUw~JH-8u<;)Qv4`s3w!%pqOgwb1pYqgM+_#L>| zfFrJ~MG+WzQbV;_A)hU2GdGl6$BvSdWVm~P*1p%kL|-EbehWHTej7oN?(8^@u>u+_5>JJaXik157Q!-plCMdKJ2RyYRWix&P5>p98<) zP(j=7{Wn0ei36+G)P_gMU(5D8rW{wL>-*}S!T)~b^3L~QiT!HNRjL0hvL&Ek%Q)%% z(i-H~p!Ne}=Tpzg>3{zbXWLPp|HcSThrrU=hTDks_c~dfgJMd`n=|+L_e%I3$Dexq zQW$5be~$?EYef0@p5b3RHwIzGpRXTf{ritDgKZBb{^1~V{&54Nb3P=o@%O199^kCm zbKdJ_{L6QH>16`={`Z34xBm|2>#@H^RLC&@8*l#y2&FDOFpT=QSyhI!&HtaUlJie0 zXLN3NCZ&JvMZ%JETGHMx2L63o{y81TcRbn88^2HTuz4kD2RHZN6W3G<(Av9I)Y!RL zo`h{oht2D$+b2=z#bJJCRqBt8SmrR!t@4zVD0GvddxtvEy?~O7UVfTuH)QYE0;*KR zr8Dmt#_%R$7&BtI;g{oea+&n%4E*tAXI<99>yF0=>)iWf>!)tfziX>A zLzm~~3T_2(WJ7M%1=P!=GL=2jpJYB<)zqEMZ=*g!t||UP0O{*+66TDV*F7GLk72+{ zQu{Ig-ZB=f+aKOA*O`4IZz{Q2&m|yHget-9!n{L)@}uo;(2*l&S!GUkqg>*9{hAF0 z>Mh=%`WXI6o1#|x0P=mwa}!4*@B(M23O37;LN^3i^ z(hfGsMco8*=NwRb~Tst@i+*H;-k92-MEGQH(PccI6|GZ%K;%ZlS7%(>wM2gXxN`qa)Zu;0aQmf1=E8k=dcDzdJ=!`z=&v{ z3_K2+Ho=y!M}p2yI+JpnpcRY-r%vu_3dKGE>>SJCPkg2(_&g+y^i|{u{1Y~j@XMe# zPybDJ^lV~^{Kuh({~w1QD50f)Ri$eyiI~VBfI50n6+d%#k-3_6Lc&B8n(Hz&Btit{ zqtt4_nx(4g%vZ<+%7(2{tD^DV)X2=^q9;}SlO*Ryc&ok~s-DO=o1gM<&=Yn+O&q## z3;8id%@UwK75!hGx;1eYW;1*C)`cwBoc35#RJtosN7Ghyfu@(A_#+U8Dtv4AvFxLE zD(vHv=dwn6?bo$+a_5wOys0qo_!xs%^uM*{$5;h?r$jAfsZ9yW`u(=(0eZ&1$ftUp z9#|ys(3(Y}SsgU-Dn$@^Rr#g^!!f#WvhTbJvfYu>v8y2mr+>_3A7s+$l$(S|kWG8X z#6C$7aoU$T)I7=Vs`0yEr`GwENTAYY4S^Yp2jFV=B!BC;4!hu6h_Do`Jmt;g?okI# zMSuYhhz1eO)E9u^g|K8#F8gu-BHc}Y`vK8}38*(znKFC;PgS3QI$Z>80m%?Le_^-R0cef<{*O`QKa^Sw-(6dPR+MbG!}L0aZ@51E z;s&@GL8m+{Qi3cyR<>*?p-KTOPhrtP+ZvfKV_-3gbiiFGTCfS>b;=zBP9Cv#v|V z+1aU;{me!5SUegChB7P}iMjv(G3LPlV9pLdYUDUiQ`8=CQg6u7w*vj%8d?GQNbmT+ z$VbW?@=<7sI^7WH#cQoD>?6-KX_ohc)oQfar_lG4P`jFe62%RXTCe|MAGu0P4?>jy zk_G_W@}1{MVH+ZPzZj%mO8u04z7~u^afgf>@uc=N|x4`9BEKP>$&4|J(2F$4rLKX{8db!+)k585(%J>@E{@ zl;hP`_3Dwtxw=(XLT zz0?OF!V@tazhd<_%K(V`QvZVrD?k3rS~_tO?}eIxn)%kzbNJ_TYX{o3@CM4hkCXri z59k4I8q3%X*!xp=jqVanAE5Y+{AHp90UhCfR+P6qhP&uh*)HVDG4|4|^J@+}Z2XO{ zeNg|E-{kLLX3l0nV*=ZyUhea#$0+O(xKjXeX055n%uem$@O^-r3ts7_d2!;ImSY3Q zCMRB8b{zVe^*GiGoCaK!I)Efj)SoUI^{`*pO-*h!h*s3?b1Qt9-KBe`kq97J0f@-M z1B*C@2RRK6G9*U;q9*g(uribgk`aZ#oJ`SVfENIGwC{qfE_bA1JbWK;dh+#_xn^H1HF*SRyYhf4i39p&H*_A0NOT;R$V) zvGzVODR{3SWY-bf$(gHHkBBndcL`4`SkF8^nI)oB96ATs`M3Pj1aKw|ZScadTNTK?f$qx2NWts3N@ z-;quDY)d4vvNxm&2UOSexQhVwscF4N=#5Hm)xARr==CTp%A0X<9-P`>%U6wfO z8#UsV3gtvxM~}xt6ltjxA6GaA&TEk<=`i5dKdrOe>{%8Pne%U_z4m)_@}MQF+r)8g ztLcF|lR|$OK)Mdw(ep*LHsh5);37F)6fHV#ISD#Y9jO9*VssQnR6HE)Ck7t|K-KZx zqIw@9jzbzM!mvj~X%_5)lWIAgRZ<`!0l6CAfKl{GD+Jp)-P<})9qv?qy>ZF`800a0 z9%zEZk+**d`bB;8IpVWbms7qmqz z7@Q`xgOt37AC6v6rUuiZY}39*pT6oho0?n?V-H%_^`C%GHV zH66LLI9s#?qesqZ3F1$i|L0F0*FWIwSE1-i>4o3B*=GoLv#(XH@Cj!uHKyRF;40e5 zpT9=}J_pMLV}@mVWvX)y2#mVkTo?>E!xz6-kF({D%#Nz)J2D8b^nXUe8KJNd*ps>4 z6ZhD^4-y=DBInQ(9c_Oddhm1b(}MrJ+rsaWfX|W6fH9NK^qg`1eV`efL)RTe976m$ zQ|G|R96v|@s`bxEIAc~w0((lYl<(Mc?4NV0CB`{)F+$m|Lti+_+3ENGPo!Um`1jY9 zgzYdB=Y6K;C^Z(f`D47WV(hToiM(3ST8XC%w?DXZoIYPvHISX3p4p^0c% znNgKaz$KwN4-Po3gv_Tk_|D>UK^+*mlt^tquVG>sdR z{RL`~d3@8Qc#LG2X}$<-@+-heukDoBv#(*UaW%-ruV++@p)dR?+&Q`A>GU z9FSYI^Jg{EsTIdq22_m!$f$HYUh+r+L6CHAww zCsoAG&$-_R#7^C&Oq^aPGV5A8#lDYA_*bfDx2XE->uwN&&bWCPVTTdD#t= zmmy31SZM@Yi6X64pbke$2?sb3%r!W37e-r^rP&89x%paiwZ&F)V{cAfwIU64NAWHC zLb?tom3{U}z6PI2Vp_S*k?zfyMR=kp1)5ZYC`+3F|Yowmme+P)+Yw+lIE^TDeF4h~Rm=(Pp`E3Bl~`oPKZ z6MXI$W4aoFxpGifSU1^L;h?nc4y(O(h<>I}tj_+Y441~D{wohIORCvb z-f7t<4)cyxgY~9JqgEDf3zwy>E$8p-IV_IF15>h`W$=(ifrhSWi=x9W41js$w?DNn zaURIl3=Vv6U;auns?2$&>;^pT!+f7OWNqqEcy?0AC!IPD!JrSH79R0ze63HX&e>M{ zMDoR`C!$b)_GtpZ6@6ben>BMd;Qhnp3NmY|;-h9yFoxAxBw>Mjbw*DU|HDTH5f(am zQGj1SFEsp&)!1}ttNRPGiyiFHsdlEJM{Ax`U7jfN=HE|TC++R7N%OKBwcySGD&UcR zZ;Ik@s=8c}DE$d1P#_&5%Xaot52TcEic!?-qluOapcs{y%Y1(7{u4<^A;qigBFR7! z+R7oN=BOhvH4c*&k~leC7AQsya*9#6YBi<2+1f}_Wu{whlCc0LZ;Vt9ZXH99R~1z@ zR6*Anv@|Vy)poaTI3;Ec)vc0e_yp+31y2h%m&D*6< zzHURM$j4KMae^H1b^$dS$wPKG5NJxyLerA6L*gd2G#*MsrVxnJ29zDk?PrQ zambue?%8mP+zPaKtmFZ8?afSK7}t@P+u^S+at-Wvua|czk+k@;kV{3kQTC5}f`kA* zDHplW#xFJt^e4@>u^-LVzflJ#1jGes{57`MWNdd|E^t=pACi4cI{Miu+oAB@mB4FJ z2WdSbIGqHX-BAy@evzDs1MuGNqi?F%Phn*uI zI>C%7v2q;sdXYwEEAFWT{+93Xsm#{2?q3fcrHHDxZfE*zncuu5tnD!6iMieT7HU&_ zY>OJy-CX@z=fC=@Dy+Qn9qRTrZ5j0c(V3)A$;i$#vmsii)$}h_Z3oj=LK>4+-NnwI`*(1HplUh;t)fWOq zf&(Pw7n<908{@ic$BWA>iMA^V0V~I>+!V!W2|BG|>k+L-D|O@-Zo?#$%*&I|kb*&H zVOH&;bNfE)W6X@Bb$Qk&&^qOFg}0uBUxXLG8N1uenC=}8S7jZBCCL(IoBaLYQNrGn z%Uj;%>scS0&Qd1im!f6jQMjPb_eTie-r0ru!x0Fw<9^xw$l5EBn{`bfVK{mV!y^gbv0_t8odB%2 zHhk#EjvG_+V&3h9AJclRmTY*(RubAU`F6}uyKw93REy7y&x_57)}B0H+f}oh#7sTAIeA(z4q==V z*z2dlkhA>_?%o+@vDl>cZZ&6OqwhzBE{>Om_VrJG*y!b6ON+hJUHa<2+sa703f~6V-6pC*MPJE# z_pDyBJKIIrtRd(ks3=DX2L!ccJU(hBK919vZBKmW>Lhk+r`>6wyvq{DucQ9zI?CEu>a!JD5E-NJFLqMigmRtI8$?$ba=)5Ma0<9x&`E=mftx|9# zzL<_{$R3+#KU>}gGb@Hv3n|xXZr!VAy`3Byit7x13O2UdwpQ`$>KSJh`uVo|iU%pr zYfcx3aW!1|@b}99*Lpka984x%AL)yWzT=C#qlYXlrd&8WhStj1sqz2-gqGN6nFDNw zBauIbuo}YZyt62=Z&g~`VZ!6KtI$Zz411xA1*0b|(UYj&JmK>1dscr;EJ336Hrg!q zajgGwM%Jhn4)&)1I{!k{(s~q}o|nbQ^P_yrVm?8h^gVj|(DZrYi@*4H`pi?Nk>hI2 zST4BC$Ab_afKOlthAv=WgcAd~*SPim9>+d3*wU*hSZgwdZbDcPLQZWix-9|m(9)AVdWXhCHQBC|kYK-i zCey12&k$%(f(Gd_y#~3yv=6^DdLa+Q=^Bog|AM zEHxbvrD+n-^XZQ{1uKE#?5L!h6?f*(T-C%&+~ZXhsOpmOYf%K~8;g@R2+y*W4zKi$Dgj%R%daGs}o2t(uh6?u+ z7}o5$%Bu&7^VV*=$(`cFnbOXxA~h{@X%7VlthQ|zzKIlt;dF15M?{oBPbyIVZ6R74Ep8Wbd zP=y`=k>aX2uLxZkzsY!_&!Xr{iEgUsgnN`>))~F^f!%5_`{cK{GMN5n#s-8gSvHoWc;a+x$>p{jzxIglIJH5{9 zi`>Z=cF8NgN7Xnbh1ejFB$gWRxy&y1hQ5(GrwFq=4p$Jd^4sBk#E>Lp@@~?@f@Q4$sH(Pb+{3lZ1 z2IgHF`5e6oph(6C0HPpXpMFnYO!TPA`UCe{Di*l zs3XLpTWH7)HTHKpySNB{t%ZG%58XLl3tmuUUDds|5?jgOeoW$v2M`v09flHSs3xC1 zO4tmc++{g#C?VbG_@zyJ_p_D(_KG9xQzftG`JRc{7L+KFO=WYyXHu*QM<$BWdT*C8 zY8j%`EG7^q7*Mg5dUKs?=y1X z%Od0jjQdOU&kE8~&`g*5X(7nzrO?RA1&_da=LXg$cuyEPu$Gv9u=E~3Mh;qi-Sxi3 zBK`Vb;>h_Xhk2f)QZJ#{!j7F7Bm_bl+KGK`G>j;*Z1%lK876EE6IqKPyLh%bxHAHV zwFH%PG5e4dI1`QSq%`m$dB=hOD`Pwaxg-!5VujfqG8#0!+|VcA_`GMmaM5JtRjh|u z>F=rbYbM$s<0Peq{11ivexhBJ1zR@ZG9=#RgBJ;_x`b1BuEBvU`dV~LFe;wK0=3}1 zY`Qd?LS=*Nc`k~znk6kNqOyE5aIG_(z1r!DdOfBAQ)hwVoOqY3`j-nYL$rw(UWXim zrZd;sEOIhmg0Ct9ydfRm?%;c-zwtz0Th%b3LtEL{_6>6|Yip3YB(f5@e;nKu1jP5A z{d(O_+pV_rSk&a?F6oVrMy;_(RJvO2a^o_YHH;J&osN{PR}iV)98@?F#mGg57sM|; zuK442L%(5M$TjE}+Uy=$N$8Mm6l)q8HS$O3N}ED_7X3k1rOQ;$L5Q;QPJLRhWj+Q0 z4&qj%%Z>;ir>h#8f<-dALTa$kDz!Mg%lT36jFzyi7V>Nd_cL+X;hkSRJX14iN~j+U zuF;+(ehu-fj8;d63DT=q;m^+V`3W6dTV{^EUG(dS>iRI1q0OV)BMcm0o_{gW%_zozSz zZ!y0Tll?DmX8gYNJe;czt}%Tw+5q;Q2UxL)1{e6E#`u?%f&d&M%E#`HwZ(NK>BvC4 z$l)uT#%M1Yt*QcyZhB zERIz9b$3^7lz)SFuL%RJS|#?I)ZQ^SpR0W}>2(3axnj+Xi@^O$sd?AJdA$-2k*{n~ zz{B2p4(2Q(%!i+wlQ`=(%6&K1M#5)5=?(P?FGBh2%02yHk&pncSMfio`sL-(PDe&t zqdSgccCEnzI%R9oI|%GT0ip9)i)6C8a6YPT<)+)b~u%$Xl<$>4+ot{5N4P zs>TK6Rxz9A*JG+*@xaNoUcm$AzHEZgQ+E<>n7~scv$c}>w^!BY?te`f7&o$2Vs8{D)3}Tt{$%5aP$H+hiBA6LI_n_}} zf0YtB1bLlW#=y;3MeVwrKUz&uHjK!v2~mTtRgiqIc397ct{2DFNN+rnu9~Z9jie>V zURb*Dv+umf)`4ki$tx$<23_>JQhZ(XH~TMoVNR=Z`0!&cR8>#E>Z*bkQ_Nnh=k4hJ zy9*Xuy%uP`*PIvW7Byo4Z`-OMSUXRqChN24^u_tmioo=m^{`RyMr-ROZX_UQ5<`48 z55yGPA4i1*K${Qq)~Ekw0sI1Ejhy?VA^oob9RE)7>tl7u;2`8qapSA7ZC?^QG#$;} zkmra2;=KO%E!2K3)97uoD2CpTYa-$vE?=KT>eO%XO2E6xxqA^ObC`h-qkP86>`Crm z##6#@+UgAhh8t|h^09SN;7f0ekW0xSQE}d+EeupVgw-arV@zxa!&xP zu2?`VYW^*C9$i$!s=lFG6?Tv~7sa0+9{QtuHN_2+c(yC$UrFzyAg$aX&MV(TmCTe+ zky2T@<17kz^qP5a?5Vt|uF}S&F58>8r)!xHZj9&GZac)T>`MMxlndgG)SyYVA=j+s zBIa}ZvUvUSlR+><#rpvs=bmtN>{GK|3;T#67e&kmm6BO!+qs;0ueO}rq__5-agl{j zgGMy!ypmIORNbD04?CVUdG6pHKL4Ys(j|}-sSa)j#0s`gcR`x)csMl?HT)Ugz>|G1 zHAtLyEM;LnQn@68SRA4Y-h^Ts?LvH1kyCZ0gEh%@N@Eihv8{xk1FWIS6V^j1#R3sr z=Ovq$&yrWqz8$9G47$6bewI=i-=ViH%_M~!(XHo3(-CzE778}CYk9jM__&s;(aS@+ zuj{;rbsJO?%ja_TdV+aboKM{?Xds!xZ22xZ+;wKv)K})|35)vqA@Hju>Oq4wtE5fH zXGCP0#TT2(ig$2Tor-9uPVe!|RL`;3NZ6ZQ#_LKY^~Fef;9ZM@E!I+lpG$6fQlfu; z|4S`$)`T*3mw#_$*Tk7RM&KpbB|4+{!;A%D##PUYlK;5bnX5rwo(x%;=-K=B$9YHB zKeCRid)P&q&%W=8`r(b#L9A|wTB%2Q)A~Fk)-x;FpX*!+>~B0|0^@!5a6HCZyH$wJR)}= z0cXR1ZsJz%{U?MM8FXXaC-!12iGdL)NtdCg75v3wSaVLI$ORH!qiZz?85F^`ey7UV1MI|1>RT<`K{;)v1Wuh<(~(1M{QlGvnFdnS3lwc)7Yf`kS!YX+`9-7VaHB?W?|*#y&)!GlJyP zPfMpLt$%t}=2_aIuoJPPEjM{BjIplS1v#)~;iwbwb0Gz-MjQ+TuBT3dd_-j+poiS9C73CA7Uf)xy>8DQ1v*QElPp zr&)xKl_X7cy1tCYxSlxoF_Tc~kiJUHo$qm?tiOf1u&i9OlbB&3_gWR_+9xDlydk7S zz%`ode%%g9GY{yi4lt#O1lNVT=AN}BJq0C)8FzaGwIXkd{Fy2XSOfdd)CRA3wLcQD(o)WNQIDRT{7E^32p4u zwxzYkBbrj}lgI9wl^Lv|4`V0=6;u2>CDA7iWF!iDbIFs=m7a2X5mVwVbYQ%cEBU3J zSQ)ReTv%>WQhVpi>GPih3=j+VFJ2|4CX-illOByU6{Vg41%{30-6noNKU`Il_HftK zJeU8Z+BpHe-_#q{Jh$m^PtkD*>mIL&oXblhg=)H}D3QkIM&@g;{YNs4LXGaNQVIoi|Im-L^HqB3>ghYPveSzwVIeU|T?d z!9JB$sA)LJ!Y{NlTeEgA*r|>UpQEoVe~g#1t;=S9K29bqwTIfeT7t^M)(Z4f+SMsd zimYzp)E=a|`#b9&^s0aqHWWOL{g@n3DKTUiDzT%nYU7b!VEF%MNXtrl8{`cddhwO?f(*2j^pt+UGR zhq!FkgurWFm4#RjOer4w1l~~i%#XR+o?M@12ios9OuR3?-X0|_3&0TEex%Y7F*jcWAJrA0H+em-)dSn3t2Rd?;=DfC;1&8K(GG_-B7d7eF;xxn2s zAXTW;d45&B73Ruy-jUI)kSVzoB$MN(h&)KFex2p$(6=So^{kF7Y$;pOT&m*Bc#;;yJA1o@!gqaw{*y;c1mGQQvJvJ=Oq2a z&uWR$^v@dsssjx5tQB1(3`%OI<=Ifev9V_KrU%ll&!?+w?s?hOtd~5WGu!GdwaN+S z8!h{sYg|Vqmbd2gLT7S3q(s7-9!rjPsDo^(eHjwnadi$YGK0o@n@ZMPhtE|8+TXLE ztnisdcj9LK1~7W2+$%FOr>toLE21*HpTY%9Enp!;l^Y#;~vimRGchJ&3kO)rp%r_}=5n!5(>(i_dC#=u6yIgrcwad$ zd;k1)1=i7F5y--c8%DIRA}Znn-B+@cCT>~hXWJYT4%Vp<^Yd{&Zca6n3@R5vg5Rlt z$!cxt5Wd!GE^a6(0EMTu${YxqENzV&D`~iKr4B9DDorw_#d(?K4$0DfsuEZFROeMz zTue5fZJ4R1{#~=}iEn9#7k=@Y)TACdb>_C)3-a9#JNyIwn9}4kW!2-0T-G97w*JWH zkB>U|iU5BZ#0C8wZ5AHH<6BKoD?BA_s~0mxSr_k03&zhe-KF+k8$4Tq+$ zr|9ZeR^5T{s#p7ZFBBN-1>LRaMW8}>UN@Lznn94jv zu&iwwfTYzuhIjgP#eP_xw-h8S^AY}eGlgTsc^Qu^cG2ITG|&%S>oyv=);mB8=t|(< z4t^1bj{n%VqPi846y@r$sFaAW9tuPiLu{vyu3RDcfH|Yb${=rSsZWpGX+pa?@Uwfw z&}O2lwPz6XZ=YFro1m*26-V_hq46Nww)!L;^(HhHIpJPCHzjNlBJiVp*-DipVN2i|M?9I@&;yU|f=Uqt;gdO)0vq^>oRPE?tTh*AnEyq z_d@*DdWcLfw;J&Sm+H>X{n=Keu*-WUPAUGOFta(hDreqh+&py6D3}>*|LN{NeIX@X zQ&Jzvsa-V7AzwTv)B6|`I~{M&XNkSd_cK9jP{r92BdA3PPhs_JNtI)(l0aaQ6D^90)SUYx6KOR)|zkx=FgI9YkU!gVC<`GPRt^dLRq%-UdefBhEAlK8fCAKwJe{0t79v5m1tk3$(U(RN7Gppn8g{)XqCCIU+ zaQg`nKj08^J?aB6-|`@4uuS^t3!HI$OV48T<{EPAMJ@}l$MtJ(F9dQy7e+qn=tqAs z4%bW?UIRgjz*mLu@9DR*XN=bJ*@FfCR}nuK2C13yI0F^FoeVWe#-;5YpMIzlq0gpi zn&SIZ4I_0PjN0jS+YXb?eFGTepCUH!$_CtUgy;^H34KB}PvZcA+R+y&=wNH_w4_on z60p7*FHnFlpV<)j^a znnwl#Rov_Xla5jHu%wHf-az94t)o*0=1cN%8qi?Bx^MJ;KlQ1-o!z&mZPaa*g*;|L z2-J4!)pk%1hP}3EQJ>Gu9mqWkYi=u+wJKLJb!Fuw4RuSrb)UAum&Fe>1lkia`%f)g z05Wir&jt8+v6Ycu{MhTQ2wHiJ*^C*Yn`If-L&kO|Weyrh<`T`2Y_dY16~ z`MQJm>y!vy!5K`|tKomd%yeHfuDM4l5BzZ7sLAl=;rVO2QO}yg1(7B`7S$Q$HnzlL zKB3?z%4EQm0v>8b@6R{Gl5e)2m5rZgs`#LK#dj>F`Xh$9d%kAd~RY;UPb`zC;t=2fNd-R+n>Ydmiy%K@#KLd`eFdzpq|u1W6Lgd$U7Uv zT9F&-Zi0n0V(L`ZA%ggp9LO=!Z^-+VTBBG}czkngEJkSfPKncPA#x{FE#pyM#5`$$@hx{=Un=mB>wF$Xo@?hzYa(iTdX!bW4Dkiu+jC% zW-)C$0zTAl31sLt*&Fa8-%RG$ia1p97JDfePn#NF6o|TmyBgkgTw%0o!V1~*h1Z$p zI-BPFgd)KDmTZ+Jvhj7!y8|E5vJ`z|WM0#w$@+}+cbdxyw9Qne2_&fpqT&WF3J>O9 zb5(EfaPVA>Sq{^uCdp(=(gR`{sa8lS|B-ac5}RU|d`cW^n7LAo6R`MEZcp^t)aAuI z={!9sv+V2jV-sX%mNIo5f7c#>a`5@@N@huBX!*!eP-Z z6_{;h*_BtS5FuqJy=umul+yf=3()3OeZG`2DgxAdk_CuEb|u?xtA91RAKB4W9U-%@ ze$X)O0kP(t3QLz@!M{9S8#UcT9$`1Ue&1q>+S0RsWj=@M=5$l>yV!(f&q!}&Q|Il% zRSjLZ8o1FGwwI{BK1)O8-LEr7Q9B}n%BzGh5)*z)yTm1L250>h8|+wU0OeHu^=@0R zU)?xd_Q#U^_ciO(EwEhiK9b%wB`Vp%orbR95W^{oYX;$^yK|6(mrHj~;q;V57{N=s zTC`hSOE10(LG9{X!gX+Eop^ag05m*@C{Bt`_YP2$Bs>Sn604m2kgNV1nvajneS^Va zt;(`FS5YfX6IMUF>t??A?&66WO0cHMPp^Brt;NdW>^UV=Zy3}725N|_O~nXCK)!fy zmb6sF+M|PnpXhdE(Aec4ZHosKeS#t=cNJY!s5J*4lD~ zX#3Zi;?AXa>-&`W{P9cVTu}+{tJEi1%t^6qgUDEEzI2hRKIfJ_j`Ut21lZ6+*xW3{ z`|)8=xG}5=(r=!Un7|1+Z9laqVme6J9UEFfQ``Egh89;~+9)3^jx`q-n4lKT*(4^e z_GV`Etha5(#G?QDqjO2g1%ZAVdmUA^XHkzfo-sMJi*Mawx$}o|jm0_4@aeDXBlpvC zl-q|tuZEx&MFwY!lp$-L20)|d?)o5Z_M>4|lzWeI;H_wK4pjN>@TD)(KC;aNQd$J| z@SAMS$cBv(WD~aYQ@o8tuA>&A#aAF0pZVE6hOJv1m7@xi6Ny^$#vEoKfwnesG%LD} z)i+#`USU=89a@)(WVQ4u9An*T`PLP0-RnbJk65gW2xVeR^X)>&b5Ddc2h2m>u?b}p z>z}(2fdJ~fv1(BO30%^T}0i>RGGUOgK{~d3M1X5hxigVZtqXFDGO9Z{S-0D7~W8R7|v7b zn*Ql^_NsRB>Vt0f+09XPm!CC_qT($ZIkZFUtIRw5rjxapMZOb3=F@-bV|9w-TP&io z&9V1wS8r6-t(=_m5PCxX@D5dZW?3lS^^Am?ReFxkpP6!wOCsBS%#+s+4q0*`v(NvK zv{mz-3e}-5uzU2bD3wi#8AyK>%`V}SW`5B^KWNyf&4G*aLnM3_GwdU;eN>2Ns_lVd z_#lT4h(|z_WZh}Pe8|r6(CN3%(|&f(rH#??$!7ZOacLHnzQ}@uWaABG%>v*12qOIo zx@L)0UwL^c|L$^PCFBQzh5+IMgW|U=%pzi{th#eUoqg7D$)QE`Y+2;DL>it+omMg#mAy=>L%DQ_$ zd~>+$T~-T}e1#lN*tw9hMK|SC+MSI53Z8w;@(i)pcNHdv+0UW>AKuJmT%R7#LdqHu?>gLOq z`}&J_U3vUgdS}+1lkF2UtJ7~+&UKK>Xq$J#^qR!aYZLue(YEzd`ujb0Sc&Opfd)0B-zcJY7zxwzdgzze}B|H51X4VsA!;vJ9n`|Br$P+N= z<=-%RH}B5pC!4!DBHeP*85t@PYf&3XsGm_ACmwvM9B}D#wtcJj*mgsSXls~OEwQafjJoy zMjCnxLimG|!~bL9Ur`b5i(*s9mDV4>(EXRMF8fvGK+=;zEbCm{SKxLZ6;e4DNT{+U zo<$bm8=be3JaF(3eiM{7+sn+568O@IDjB$wIn?&x;KWpAZPkeZou?LJ@m>Rz)Fu56 z4U#bg2F|(ez}o(I0qgI&)^&1HTIg$r;TH*8w4(I5FyYke?%H=X)ASJS@Hktv=$YZ* zODppiquS`sE9$JrJpP;;q{0hrCo&=-PF7hu4_8C2%18sKpSPsZ+Ueu^mI z5*6#u8CdEv(j7)Ji(Z2EFJFW4(l$c0=%a9ZRICtc3yia!2l-ZbIBE;pgAdm#pfetu zdRsN@_KH^bL(i!b$Sa-2^UF;GybTe(c67?!sjf>aR#D6*(qG(PTkX1sj+@41x#9=) zF*0iob8Sw7feA|s;k>+Rp7tFlU)^>u8#Fz-aw0#^nO$+u+#pS-HNt~I-(=*$=ml|K zNMQG1%>`=Rm1b9zE{!g2Ej}UI8R6VudmBCM4DsfFG7=}dc9~A6;VCjv&Ls{8-A9%h zt>>)ik@Wn^6M3W7rUS_!+7iQ%kL$0Rw!Y~4*v1q#21wZXVdD57b$d#RhU3Efj&(iy zVw>J#>Aw=&I?sfEeP7)g{>1JPuFvRK(O9r`k~`_6KGHs=zxT=P{7}|U^V9qL3ZIj{ z%uHzZ!(5bWi=J}+fEA&wpH3N(EopRGEgvqtTq=fH?f~C|o~}svQSbg{96@9yFRMg> zeQh)F1hPE-Bb5#zUGv28yp~EO@0m)$gtjDY!m@R*7mCOlILx}tXh>F4i)d^QvR>x% zebq=VW=U} z=3z**r(*LPLTHYiDtemSGIC_Det~}uI$PBl%>q6{b8UQ8F$wOWQ-p6j$qmJy-Sign z+*RGv3X9~lABBfu(I->~^3`m$`c?_Pqe(qaHMptBvc&>xRNnDSo|c(W9n)QY?ZXYm zNBQ`umJ5*FQ)x8u9`aIJq1%VAa17m!NpE=;9V35aq`J;i)p-7V6;Qa`hZ?RisHSby zWjc08j#0ho(Pzq-==>pjejX zR$7)Hiz>VsL1eAcMK6Gc{y3AHwY9TaY&s`1Cq{oFzv0uxfo#~1C9zC* zdPk^?zUGgpSC^A%Ch&dj`BA$ZP{_`_tYlp)Gqo(Y2T`yO>%9Uy7HJ`D9n032H4ge2 z|75GCc;P#9^qsTOW4A8AaLqqnCglvv${m&cqo|jpq6MUo;$u|wFn(;_>Djg5uaU+U z`^Fm$CHr$K5|oMMR;3x3tp^Uq;Xw3!8Sj*Il|tzNBMl{Pv2Ks9Y`-xdE&pYcVH(G9 zEc*8XT?yHKgExlSVm&ULs!b?Z9V1i`@Bf$d8Q(-EY9?%>CSy0wsc$_Fs`K@CLsH-*t*}RH-`SDxwEvxg>{jW8kSE~og zXLVtZbfT@~<@)Aq(`nrA`%%3SliH(hc5Q+aB1|MXLhKO=3~f$*S1_y62xZ9GjojhZii$ghGol{nCLSHrze8<#8V?sG`p z{i22kNaqy=it>I%nc>Ffjll6y*K9*0v5%+`L*AV^^gxthow5Qu4lf2o{ufuGhImlE z;_PcxjqP1UMO2~_@ZqTbnRu}owI;HU5qU;9a9O~MoF)EA4lCLr)LKJLx^oeF5sDZX!@qwt|AY(9V3l$+Nak z4}UwHqxk>67lw_u{qVBiud32>B+qAzn0Po4MNwrV=@Q8Lfzh8k61-+xDxuwwpkARTT+>lFSUjyR{vjDSPIR4!*2(!J9%J|Eev2%NaBfXZHF6Zanp0x-usd zNi0yajv9H`xa-~5Zgj0nP!cAnKST^_J;;b1zEu-&JCe6 zlB%}VFGr8?pv=6v0;{IcQ9!OaS^mzgtc!hR3`+SGhpf;w<#UXNyB;m8ic}I%MB!k% zNJOZvshF4A1nWSf@UEGo`6b}!vYYtYfbws9A<3-RbayrJJ~PIpuV5$yTok8c6{<2W z5gsk+VA6?C%KB~GFJ)fyr+qx0xG0f6G`)#eTd!yg(yqf+}wf(P3=xJ{GJKf>#;}=f%{&t(<_wW;>Rdw8d>#7{R z$f4bz$Bi|H*JtrNIa^7VTa76Cf5G#qtMJmVZ}33tf|FR&!O8lV`q>~xsg{Tno^36( zYWi#w`OnBAZMSOyQaW|$D2Rvjv7gS3jA|?hfICe^zYbT$%U$W=1zJpbF>3;95ixk znBLe%yq$b4A-xyYQtlmfv-c~|P*yR{oJ&z%d;Co@GP-52eBZjI>$zL?irm-m1@BrC zZ(%}Qi&}5;UQ6O|DKeJP{?*zYR^?%FJbENHn;05rYaCGoD7F=h~^- zp?V!nRrIA5_02NeNM9dNnT@qJ7&lBq8Jxp+z8sn`I-EE z_^i>~GZINYTDYLdI_Q5F4582-NkDcw$LHu1e45!ogZ~h>V{~Rfgdcv6FtXR#6uUQtLi)u51jn;ycXU&Rwg*?=V6i(LYaG4I5%A0fPId4H97SDdD*p@}bs-Gf^ zLHpb6&3!$#m%#c-2ZZYhG+Wr-50_F<-2(~%MzVM4KI_}NW}1EY?S49RGO77x?;lUZ z@K4*gi=j&1w9d`ZS%xx@n;1?(%A`t4RF* zh({pbMJ4Y})?!ScgCD%C8&WwV!5t^Bx%8{b{zpbQj=<1#M<&3<;;dMi<6JlF7{e7Y82Ofb-o8=&IFvfW?4aPTp!@yhwh^akYcKUW;uV3So zl!M5BOuZlVK@{G0rT@|T&B5g|wytAH1-Hw`*UNhZR;5)u_SgLntX9;42W7NU>mUBG zWSbz)>Snih-(KmAUy*B|b8j~P_jUUJ^GW^VwV?<6i~Ce}KdCXI>4$~Kq`rSD6Yde; zdfypPQzrNiCHzUgFyDCd>h4ul)0$k8&RC;i8d@{d=2BGla9+slXSc1W)l!;U<2I@f z@psPP@>nUM7L=xLNP&M&rHb0sb@+1ju$@qTUH*#|N@r_6)a$De$C*v7!VkKLOBb*C zB#Uf={J(WM8K)^wB^@|l)ObDN)$ZkeTyiYV+Pv-3t(NgmcAwwW&TW;TM( z&q?Wp8Y5Nt(CS{iF)u7-ws4?XFKhT6szmb3jG0u!tWLBvS5UpeBbF=RDsAodX~yH5 z{g{9EA8!^0$Yqc&uRb!dIGQQu@_Lv`-BGN(_PIxRS1EXum4NQ#QCuOdvVWb#xfI%c zE)YoVtylmw6sBJOP7E*@C(^^G6L8Wce-KaAiGd@$T(UAmP=;hpFROG*zZPOuhKQ%I zb`(E$WAsDrrz9QY==l*L|%3Z)JF?8^9f z92|bTReGO$d4|Ms#*>~}2mxj05V-V}Nyxi1*>_{$gRj$dH*NxZA1z-le(Hn42?yCI z@ciLhdno0xCDUdlav6eeFqrFA0!35A63&;#sJshxilJp=^J#lpXd{A9p;0X4S|*hT z&Y<06M{3`^tZ=E(S}`3UkUydP=Nku3jLrlYq?6i?%>*R(;##5nYAFo}Kgu$1z!@Yc z2X)nW`ENIJ_S{VjQJxZW_GA-#&}MnrsEV>OBjbPUs0>Fj^JTb zZjx^Q2$DP5TWu*=-B#`hdhuZGuw^oKTdUOQj0a3LySQXCg5FX*=M~o_+f)E*jcNiY zASTwG#(BcUM;XIqHi`ou_N@5EbRX>g(7GU2bW^n{Ag^K{YD>M^Tz}6aUNr^P`Om|0 zg!g4oALvfw`jUZ?bP4%xKCb9vvCUCTI-iqjDYZi1`{PeI%}#bxrFB&l9KiNfmgU33 zq`{mDQab%yPi93Oz32N5RCK&9%7o6BsV&8V!jR7?g!w5yG%tz7=LB$;Wh>}9m7JUH zI)>Q(aINJWK8MseC7sTh>|o`n)i?1{B@vdH-p{nm#hYW8*(CgXlff^)skmPiTvcs( z*n3YeGcMM;<1NiywZEQww=lh>(kLHot7RrLDLGhVag8ot%$O|QUY1kuXRYKr(A6{C z1ZNpyrvG}QS;zcGUW&AG zB%6^MJ)^{of7oDPUz>lO7$(D^)tWK`ik&d$?O>(9B|s#H?BSKW9&VN5hsKwZy5=cZ zdNX2c-PB!pya`EB0;B;_0;DyNEY4`C7iNJJjz;>D9!Y6LVIFl~UzhS2R#h8ST_G&W z@>~N|!2|P5sMF0H8ODTWt9e_{9(d`cwY|VHEAn{sw8aLzGa`HqMG$Pa9Emrb!p&6N zG{XbVj;?IG>g4CYJXkorclV9-)?uqxpD8aXXa5X?^o6nv$d9-arH|uE zTn+_4z3#9=+jGF73S6yy#!sz`M)bO0aw{6!n}pwY-yN170jznvmN4~Tx%vAR==CUW zu+S#<$TWH0#)q6Ut>JOg-@p&(-kfmuNhSG#aeyOGo{!i=R+apXFxN-s?<=mHu%D!X z-Q5V^_nX^h&c1Hw`t-^aMLT8n=3LgsKS$?=nZW<`SPm9MIiJL$SD&vels#q&8L2nw z;i@-)DOuG{vN@W`33PnVw#@F?-V&u8g}2GLl4Fz^w5L1EsR64(|584Y#nnn^yK4!_ z5^V<;8?8s3Yp9xpk=>wwlv;Ye0Ql?fQ9w~{zZVUKB$8vguKhj*Z^^uowwqR_H%R|x zDu&9?3uurr;sF8(5=a~&SkJ!OjOd%7cL54qAF#Lu!sP4+Js*a>s|@z%y6iXk>%6hw zP$lK^DcbU^naoE;|H@fxwD zM8A1(4A!;mcmvtw92F6+%?EKnCYb_Q)0uBvqpD&Jk^~T_dDzBkGdakqG`uF~iK<9F z$v1sx#GOCH`6AAgySVJUsqc47!DE~Mrp&enQYx-fsabMYu5$vzO!h!yv{vlE)SlqW zo%3UMlzYK&cJsSxiBw!cv764O!Jeb5b{+pbr-u^ss9rz?;}am_k0$a{JVNzrG9G}h zRxRXf78irGCCJ2O`dLtILP-T`w6&?oH$k=116b!w%e-6=n6aw?ioM#1^0FrrpDa}z z?J|9~E`$!51GCt1)m3(2fVL=SkCwOPQ&2F8Qbm#?Yn2(nd6-8L@{MwptRy!cXHooh zU0SarJ8uYdfl}b*Kz_kkY=Yl4?`xIgMfeXm)FwwI^we$ws zUBLE@4K^p)!GI={uCktVlTHzg;7wX;zD{2PDs^n~51cUaI5UM21(j=nQ8qP92V zW|Cv{vB_9<+`w;#QNCrRmqN@#X^YQ$hXL0n!D5qZNuwibN7I4)$^u6}ThIV{)-30r zA@~$zml%qOGwC79vsn!R?TzGDwi$*1QIkLvIU`$v9y`c%K24C*He632p-V%YLbU^I z-0+-cDy)R)5A9%2q#F|&R_nyvc0+!rmH2uD3GALvx=&$Cs1J_%TMIfjq=4)ZWk5k+ z$CnrAF(P#-Bs6}gmIG@oOj&u*>_i=L^mXv@Ee|)5s>~`@!g;I=x7>A3|2@ymVztJ^ z>0qcyzO!+&oTsP+YV}KEUAl7*`|7>Y#cXGc4m1Ut3lhL%zS26D($)9Lyn3a&VBpII z8pDH8s4;P8C)Ut|uh1D*^G#0At9x0AoFi(^hQ~WGWKn>)%F0d!YLGK${tVMpJcIrdUe`rf95%8~?Xdea&@EczKEQADBwcO}+Xj%uR zDrev~d%UC{Z~PbCS~(zqw+>^zDgMWUZXldo&yCugZ`l5=J@OOwUIVQ^KsdrpAu(5J zl*j%*p6Lx9gcEdn#mO02e;Oi){ZggTWZ(54koiy+0;8=R$kH2r$R%zlA;9{^tAQ)u zaI@9=Pvodh2NpL=u#=N>U-~%_Jw`!8>!D;mP?l>83Fk0;{l-DU?~q1JJa<=tESt zrP2+@wDx@d(NF4mjo{E~x!ZM3@|+ZOm3Df6o&JOUqO0pY%W_9)Zmx6FT;t#cmBA}9 zh#jXqhR8ZK`aZ7`y5`r=@a!hCmL`*d{_f2t$s2E61H8yXC|(%wjDD~&9EljK!!L`W z@*!_5D}7%!#}hz&)!9xSY{w0|pKa@+5-!DQsZ`OYuO(AV7L3Y?yk+|_Q}Xt``)2^aTJmX-1*ju?#=kDxFp!ii-Fsmk7f;FW zZ8|5bHbFG1xz*(vG|yE)r7Jk4jk;+?~G2)BX=^e}bdg|IjXq_XVui>WwX8J2qX z&0N7_9*uN3hlY1Cf+IEXrfy8nNKq=}`-m7bl3A}8fU8JvtUcR^%9uhiTyzLNoMilI z!t%R)@m$JK2-^49)NYKm@q6q@g^Q!*ZYh5?q7hcTmD>l`^$(2e&bk6^%aFPQ&CPPB z*AbM@@>6v+)f;QWJ#mFX*6uVU(A~-GsOq>B4oFb z^g=}ZOB9whi#g1~3)#Wyq4m}S1&{UM@U(8D5!rj?56WmQ)w^<-NpMb%sP+(^5LNP0 zKK8e5z4ZA@MMxQ7&x0h+-PPH4g4hP3wXAyHf7p!0kyP=GdtQy_w+E16n3`C~?KPj_ zPf0y_Ef%QFavUUhN^kpCp}GF2mZIZ9Ul9`5rLaG0 z>|rH0&0a{Q$!xVQBcxm1OWyG|JpY>Y^&9qr?z<&1z&6zP#i~(#dQ8c()+sy{DE!2m z>ADmR4}6v(AW`ybNA2-X5QW8l*$Y;c zh|>yB?aC#b@Gk>SL(X5SszQKaeVU+fE0$|t>_9qb0R*L73p=2zrnp)RaW^d9_|Od; z8B+K}Ee9lWplF36(^jXbc{zXw+&T!`Z7W(wVm2>d9$1ZE&c8^o*(1rcC>X$UKk@dO zra*pK@94sy<=*&}u}ofv%c#xp5%T;TDiMz!n+Y>-B+F6k%whr5SYffn&KC%aStf(a zjxUnCY=kqy2%|GpLT=VpM#K4JNYy$`xK)N#(FGb&2MTJK3GyPrRcbt7) z-P-d^H54`fb^4k+TPONk}xDt>Pb_F0*=0+O_wa z6R~GIYv_e5UE%5OSo!-M@ax!xY!Mj zW;=!RyXG4L;AtvIXE)L>5!mJb?0kKeao|^P1@1D3@w zl`Ze5s<03Nr|=di9wfZ#pC3+u+kSdYO^TAD11nfOGPb zCkRS;ujC(Qa%cveD!|VG?M%4=+8?^_IRbbx5UDM@mt5R%lkt}1()WKB>BD6KJaJ~W zbbBh#eFvs&th(FR$y>dfO2JCDM%X7vBZe%rcg*LXWju2Ta<5A$R%*gIO<2;f`Dpw( z#y(pF27a<1lDGx^3}3miKKR5U4Gjf&{~^uk8SP6OqjD1qF-P#&T7jE}VOjo==vJc8EP z2my%&a@FI)O!M*{E#(kW%AXNu%=n9K%k;(hHmKY?oBmgA)L&cANv89hs!KLhl>H++ zM|M=M;C!jRkM-bf_d~0Nf5?oL5C35{R&ELpYkFjmNiU~jws79*<6fo`e?_g4rA)HR zv1`V2nNTgwDH}{E-Kv z=*v1c;vC*HBZ(=w)iNXDklVNFXsJ+_mD)e~7?Q7=$xC7T9(5lSG-!8T^nTX8Y{0Zq z`4$d{#7gq=gsV<{uD-{Uk*BU`C*+l4Z+zT+2R_s&FaHLn-cHXcZ0CL9&B zw0niw`h-QTkWPsiftJq-SZvGrKzAbLYul@rBs)v!htP<# zeF07!-8^mCFx93M7<0wU%We=roIJJ!VJzcqs*zkj$Mw+E$6F)GzOC z1cAd=mBFq4c_uUupC*Z2bz=DWix6bzPvW7r+w;>?#MIH6?IFgFklID{333hYB0Y4> zg40%6{~5LGe5;fZ=2i1zqcUW6a-xY#Yo8?zisHNbQes>#E*#+sEHt{o2Mx#0XE!K$ ztIli>FWfbEQt9>ty{Ds4JCmI|o1COuvDY@jq`x8x6PwNFAjPu4ywWTVHmP`LsRL@Z zGmycOWnD$v72{}Erf)7Hmfss}?{@|T*njx$QI*Wow7_=?HvP=NqeYMPMtDjXrwF2n zUa!BuZo84!?TE?ri~qcCuO7maGE0A^UL6R9|*ED+RP{E<@9%>Rt2^@~7JPz7>1T|m79fM2zdmXovfy?_6oKt2S9%mkA;B9+x zJ4*E&RSnXi!!%~yehsJ85zxAn9VJ>FZN(29ld+k$AFeeF|G~!V5ZEt`vpC*TsH%r< zXDzSx^6A1+d+;(BAmR4TkB&}$6eEv;6u?!ojRQ$8u#dg81v8?MuhLkQY^2mFY~2at z+!72|BI;VmOWXS8aex#1{5ZV{LQu_qxUrh-RyNFXO=(=_@V(}=ahBh?LEyG_a=~TlVRAITj5UR~W$cC&cVPb7 znkaSiJFuD^ZfrE5BGzDL`N zhXaQfc=aX%nE+!^{`txFHcJmXZp)cSSg_q3JMU67p5Fjb6)G07XFiaafUydd|4O!H z2cO#Y1&F*jW#UT$yGeq-p#h-*8}tMDq?SyNwobai3d6`X{UKKYwE$AtK^(Y;=fk`T zk_LXad(p~ld+OOcpu~|Mn=g9_-FZYhI|7^s7?}+qhX5AI5cPrMOfpa%*WczgBJw01 zM4nW8+^_6b3dCh}$4HIMBvU>R9tq;Wc$%gBjv$KmAb&)~J#;_o7h*ElR=P$7gZ77h z)H;b5+0&2%`N0~?Z>z;CSpt~DtoULR2sb5io1ZMb=j;xDN%2uPruI6@rqdr4AOYEQ zy*HRmIq9u>(`02K0~~}0c$jem+)uKf;7V?MT_ZH882|?UJ(`73T6R5fb|C_JYR#`EQ`D58#*WMg9 z(1Z90x88OMP#&>HVl~1Ppg^_UJ$g&k4rdEwk>&5x5G70E>AbHm=UnK)tKwC~-i^1{ ze7)%KtXufKSbNv9gk^444}<|5#NWgxW8E7A>2bEN^$F>PV$j_9m36{@q~IuE{UM{e zBFhs&UAauxW0e(1&7O%?jeywY?oVEO{TpadaVNhyV84iO!sR}2SRtT@AtxS!E;m3U zzJ#jCY)F1Ryv87Ir#1+bX#Kt}ww!Ly2ac@|K55Va;J^n;-4O8pUDrbQou68FKM(qK z<%Hp1dh-X$Un$A|)wHcAM_y^~76fope}3|p;srL}bM5g{kN2|q0uORHS8Px39(nmB zC9|$p-yu%wekKVN`>$*QkLIs)%0g%Fm^;4>eYc%?4&GkAQ5_kE!f`v=im8CT+#Z_e z9{j}XQ5g8}12H9gv_kiP9WX@zyO@=T4TlZt4X$~3oTM`G61J=MqTgtl&BHvbHk*&Y zCU2UJ>d>eqd>3;+5v(x9{r0Jwwt$AleUYBOgE5KLc3w0A)jbO|hN|jRVqm~#F;z8D zsjt&l5IRmyy16nYxohZyQXcxhSg9cTzJ7c9GNTctq8m!f%eR6H0ZB1p`W-KcGxp6j zJpq*W!61}Y=L+%;L5Go-GehVBAqFv|&^gNy;CjVgL7jA>5iRQ*TngXy11=GQkcSH6 z+VVzt$kEKrtSE@bP>u=A={4y7TjlzLxMFKk+Y`|I>7{+?YZ+}`rdqf%c76j)pbJ(9 zqHX4xcOcCewM9MnycA@?uP_lfj~*bbuSxs(10eNnb4)2{?qKQ@Ak-m(C|`NMYrrO{ z_M_g=#TAH=XM=$I9l<6&($NpXg{PB`8&u?Zhw)IY1>N!Qj7VrMl{6z^iDWwH`HUP{ zr-PhF^nAttjmegi7Ik3kbGmktJUfJZnyCgo*MI-oME2tIA2a3J3-3wAG^`P4>`7k| z&-|AR_W4EzYpyUM)4@u}=}G!REvEt77i-eco2vWaDA$DV2iHC8W<4@AUa3{n4iyTNSc* z@z2C)K*({nkv1Iy*PRa?j0K{o8`&c%IeD@bFVZMVtxY3GF2`Mb({}0?776Xqwo}ag zBJe_EjgJf-n1^%;qm;*?yJXEu#rl=ErXr*;m)eveO$JLr!zV$QsZj98a=tXv+Vo$k z?+U2HC84wA!9oZlMxkZbM`@t8(1IB(fV=}YT_ISAINQVF-$LroL}VV-VBMqwLba`g zeq|24izHgft%>wY7lU|Y0h?0=5`>`2no{0Yh9BpX#NNZ}rHGdE2 zs*QTv;iA;kYrFv>uWF4tr50CF?B?^q`CAIS`<`+eYAP#t`%Ztm|*fAs%^WPPZlW{B=R1P_(`-ez`;oi{8muS{k3-%sH^(eJIyT*Y0b(K!FQ9MsHl@#Yb%UHj zm8a+g#+CQJ+n}gOyyuq&DO*(g36(B!8K`<-%7zrTGK0pOD&F0b`CvFgZ)kwAJ9G8D z0`$+)Np+7QyT=ZK=@WlWigaXy2)D1PUOTbi-mIoCcB-){&+99!oW?bnP#`!Q&|IF9 zJ5o!>pQ6D|yUKpRtTqB9Dv}4~h~hNrxwkGH+f6+bv8BGrf4ujnVRlXwW%}`M)Xk#| zntwvY<&D^<6o__$_-pZCLf(a0>#EtA3JBU7GHSPih=!2-YwwKKTicpD2n~9&dw?>n z(C-csEuyj9DE@wN&SFG|Ad1+))PyE z=_!^ix9_Sd|Dg5+wwRgvu9V1YOgA7}A4InbKn|#~?QE9jzfkE$7~%$WN-N2E{R3`X z2WXL~b!2UQ!p{GfTK3SLCx{4DpSay&<;U&cLWo0sE3fY)rtnq-EbST_R`^#W`>Jx? zl-K&%^Sykem;{iWz%Fh$SH*dNbxJ=}Ur|JpaW z`dJBqn!O*l?K}PBRu0|xv^5qXxug@6-LL1zug~Z48jM??&l3(h*U?SkF>&|0!D+?jG&-;&lR4J}LEcY_v7& zLe(UVXOCQd8ydDrj>xJhJ8OF<@J*gW28WS-D@{#TB-KxJvmO6y*Sf-8;|WA>nWSr{ zkW)2nX3`EO$GUzb?M~bv4rBAR$Qp*7OA5sHLV@S5(&-K0J&BI97@D3@baG9I$I3AH3d?)|%4KN~VVa0B_9YYCF(gw5|@1a{SYbDQ98G!xx`dq=%Q!|$k} zN-{O$pWn&m;gx5ip(tn&d~f3PBuo#yfH$wFM}Ro(s%rZ1cq7PZ{R*2~- zZQDD&E~Ev(rMG?TskFI}YV1AFR(j^1RW<|Ux0HX@QC5b;k>^ZL&X;RdRkhe|Rdv&m zYBAldb(!=6IANG%xB z(QRWq!ozRtiCh`lud?VWBWEG!h6~z@%^K%AVF;DAj(0;KuvX7WCS0VdWzP(SX|y4p zoPpE*9r=n(P7VtPYVUMWeV ze(^L2Z{nZ|5=QAd`ECQDt3?4EDm{eYuJzdkM$D;&o>lod9s>ue`L{0- z(9^QQG?>Iv=;Y`O(MZGoi3KP8g|4SyU1Qp3MxfG<61ITZ9eWK1Z7Oz?s|m|Nc}X%+ z3+XhODap&TFginL3PnXj7na+X48+tUtZF?}wY40zLX9baLI@FH8V%`wQ@j0_!QvV$ zbBm%!;qhkgUBV4oCt}TP>pnuXff7s*%KPKArP*^VCzy3QSiR$M_uXUwT3~>*Z9$xC zQJ`26@G=DB8t&N=xYvjX8D-56tV%BcUkgSuWug7-C*1U=yM0Mh4@m+c^}S-V3qNC2 zPHiMly1UqYq4%9gjzE%imdsh0OyZlg;iCZ)4gA zI?k6-Baf=cO(oygzz=Q{8ymVDCWx(~Ew1?y0XKG>gK3Lp_RACNM6E=?06_=5abH@1V>>#idDJvuh@k0kS1K}aOSuN~xhEL!=#*C1UEi}Xle_y)ZM7#tc&hB5PrEuaQH{LYzy zf+TRyo^X|gJS@+>l&F#M2Z9!R<9%nhmkrC$?J$5=fam8s@-d!BD_~|V$`z7TqnS_v z11j(e_)epKqxiq!t}}k*5O=VO8Zx7h$k5dfNsx$$paIj$g5w5`A&6NNq-p29sq%vFxX_st{2nV&a90# zkWV}egc(=fb-woJ929Fruc&;HGOH4QCfF9X#5|4ubJS zRYow*%2`?;67_htDN@IxAUp7oE=b?7y5%V=1)#vq^UdtK8>V~=W}lTIv(IKK1md6) z>^CWXEx?u7{2ujPL4K1iXO&T%Xy?bDpoEjj2AkNEr-f$1s4eTB+@Zv!syDU9+sVh7 zniF4#Lm;HGnh-x&b4%6T$7!M}7xvL%Or??gLr$(Sfpq(ik7Q&+%sMhiXk%&<6ewum z@|Rd2&o<#cC}y3&Gc+x4F?IraAkSiXZM8Q;)SBu!RCWsiH-+-QspJoJ>3|6==`!(~ zo>`9souEM~7Zd2+`J|gYj2c+GSz$ehEO5DIMFw1fUh-l+g6yeo)7ZiGi+&-l^kxAg#tHSQcC#e|fL7}~QRISiJJHB; z+~v&)U52ASkrfX(vS0Q08FN$(+?FV}<;13f1YNJ6yI zZ#N*~z)+Jn( z1l1?kr7q2Yo2Q&E3TvQQ}o87k0~nrUd=_sf+oI5^6y35pma zDhS4>8$nue!ap2?w>!N7sMWMqk&A@2a0Yh#X0LK~UXD`z;{F{Ke>^|)==YHpT>esx zQM=3g0z!etsQGN>&ck&TbPLt9gy!T!(UJ%6oI7-WDec!^4$1H2GZ+hU`>XH#@k?on zjD{sPpOm8TX+n(A6-H!U&`8*FQ(2oJg~&3CFb_z!*<*zF>MZztK*i#{r5^ST?Rt<% zi}p-_$ZA%k`K@AfsTTbq53Kjq@&G4#uxx+Z%dUKT!3pd0xVK+Q4hEZAbN!M!59Xit zb$KnKD_(m%Qr+rujCQ`Cfu?_|l?F^~VuFT4JSef5{uciw7jF1g3N^V#kf z2`l7}k$9HM(qK^WQqx=xY75qWsi|{ds-MksKe@lhQ}^x0?|-anHu`L^u4!_`e|wlj z)-S)n<$oFSa9qF8-x8luTO6-qzWpZT?>h=Vcc1)IJm=2V=)aIZcno~a9$QpaL2ie= z8+rKA$XlY{uLpO6T*4@WWGnyehVSgzImvT>&&dLv_51(7*Mm#G*gC)Il+ZJtANQC8 zUzggqw6s2h-}sh_JX|mN#q_`T6nz|SA^N7fF!}pErTz66VSn0BugzoDZ}It%pQ`ceFBRM=8TlGhR9shwyfByt@NoRO!*PM%uNVC`0=b2V)L!Zk4BR;2L#3Htp~R3tg$MxX0PR5*s zOBUV!DkPd_TSZdD;c(-W0apScGp~0as?~n%)$BZ{H*kbktW!8xG5ht2T~1f6=Vr&- zXFnz4vppW}p&3%mbYfEyeWph9el;4qs&YR};a+#!1-~iD_E3?Q9d`WOK;BWFZPQP= zn1t<2)9fn`x}K{Kmt3mDe(B@8a+pOQBrk`Z=st+QwV`Kqg&-s@#Kh;=r;*y1qFfB&(#E z=)@;HZ_P(N&7ECd2pPaKS5CW)4tPv|{u#SdS}e%1%Rpe*cbGg^TQ_;&^}d>0kA&5_ z2a>6dgNY+dm+3H1uf{0utmCQEt$)gEJ8IMp>E&q18wA#2Q&MvV_Ns+46JH;7`;fH{ zM+lL~NpQ)u#TrpCPp|-t$VMSOTBF%{}vr1hWtkuJ&f5W)xSlF0E@wGkVJE3IQE3yBWq< zY7rWVd@7^P3APL8bXyDwjqz9ZJj3?;*mlWwAACJrS8#y%{=;hGblA$@t@ZNWF|(oS zn2wY4oGO3C+r_KT7pC5m(c0rQMNH=c^+eMkZ>KxA@;AxL@k`BbRw7K2?VR1`jQUM- zMki>eXMocM`&UJPC!OUdM3;hUg1hPK)Up;SMH8)^q1hd?vX5b1wxQUl1$TmQoX9Ga zNiC2@)e-Vc-#$7~rfXNCK+M;qm7gP6Yp;kW2u^NBjZvn<*g=kMH|LZ8-o-09R zCw?9BDI*DcQ9VYEPJP8SS_O4g8#=UycD=g1S}s8;Nbp}xT6k}{R#fP>a(#MyY*Xp% zY+mt9TQ?3=y)@4WoY6ZO3lFD?E9nm(^0v(bZK&ESEG^5lO|MguuMw9R7beE7GZ?PvD2P!b_BC!sjf<>0j53HuqX-w(6oX0%AL!4>tZ{KWq8)Y2VAK=7Y7NAv-==Dc^a8u8ODq^i7>Ne6tRQ`QgP-yxMqcuoifFil!>_0jZ zHjRr2n+XVj;H8RVjN!DOb)vr%`jq9*B{N(D@%XLR(%w6&iL{LyUUfxxHI&6gArytRu!=NEKm=S7a1}&E0YT|SX_2agwu(|jK%@u+ zL_|X`0Rt)qM0%H=fCK^Q0l^RmExgx&?(@9Q`_FgIcaFz%95a)d$vyXd{n|B3^|=u@ z3~}rL)NGf4Hj5@AYBhnvbX-&E+yjL7ug;S=iSPbYK)( zuq;o*1>4S5i%MX|POCipT6%e2TuGBv?fn5-C$;P#oBp9i4ZZ=dQ6?=!WyQ7CkgFJm zIO|bD+y}`_>|i7eW%frOenL9EGEiwRW-_;U2KDn_TTX1&+!d)4{MQF{jm<`1)Kv(Z z@18Q+es=Tp@`nIw$BSK|8i|q8bs;=|)twhBaNy+YhqI%uIaz6){!)7&><}qH=L_#C zshMBUD>A|2+MO@hHs!lYjKeGIW$vKJ@40gMlpvOo@?b{&Q-t55Wy2=`j73F zU`dannSob?>s$ok7l}uo=r&O54~|gu>JX4e9`1H54py?sywbS7ldn}LQ>}8OEyH9w zecBljbCwxc#@t`x7eiguI=6k?x113-FH$hj*QZ-`?1LtL$oEy5hU*asv+?;4`w%ke z=6cg<9m&S0S=Eau)Xr8krM&UC_A^plf3N=tT)RbWq&4RZ3hKsmJjeFR_bd9hqK}tl z>|P!r%o$9;W!*N{GP9W@`treyH}jXXkD{T}SZJ+J1-JjwyPH&I82cju4+W@-58I7d zEXGNr+|5gE$;aj{F z{o`7splLHUca$l~S%MPUJpjj;**#u0?bB{IUMlp>yKnIThPHUXUjg$4mi$~TEY#kf zzS<>tn3qF}i|Q9KMf8uG@%p-~s(P|Iizuv+MueU{4-;AmjL(-Qh}F?gKNvW^Xb+|< z1~r&n!Zk|b0}`y~s&7TrM<#YuL@p9d8==AX7%I75R<6Gzbhva+C)&|G6TLlCjWj34 z2##Uy@_+}yhhKj%R&7q-WPf`)edZ25ziC3p(Yp8-d~bq6xv5#I-p`dmdw;62NIG#;SB!yN!P;-1E;9qH67$tM)XsFTbl|l(=pV`kUGtf+L z=8b{2myR=4llDl0G^pj+^WNLbHEU{&XQ6hFS&7e=qcEm>L0&dL`dqi}pTRWg9Be%6vazEMfJVRwA`q zz_UYdIiq=}Ldmq>pG3aCGdT8zaK4g@xZ|m(8MS&$9S)I*HOj|DNeG!|2t*2>!+eQr zMRR6EYzm$6lLaBup*IKqD!oEUabbybp5rA9@S&5i+)lw3*#3`(3oD|X=%NXW z;XR#%5gh~Emoq#KX11kz>MLzp^^w9$T^|>#y*+6UQ;KUMl8^bX4EZZyov%8qaeW}u z`cJ1zby|wB1Z*;e4PRp2&t{W5I|=T_gw=On<>ms#RQbDCTK(Y>vO3Rq*jvjfLm(7> zy8@;TIepkjF2*?yr=U!-5P-L?q+*sy0U;wMw(}LQ5^?n;gHW3>sRrUFU6^tW<_-|` zJJB95=8wy#3n=tmI83vN&*V%(5yDYx?v+2`a> z-CyHuGSANLyO3OfZV-Eenw2DI&`xvlsv5m)N%0iSeOdNUgv8z1bfF}LRDYC^%&7H9 zcdB+4 zZgfrV8kLic-7XBTaMCd?JbtZ%+k5d9{WNp6@bygLPIT@Qr>@?aB%K>tJ<3f2T)7qAu+QW%oAE)FWr@?&aa5@v0bq!hEHb}UzTg?&~v%iBFmVO zNEY;`{*8OrOsyC5>_YFFe-dYV+wz)R6E)n)usR{6@YRqWnEcTtIWFb1<<33IcO(OFC;1;}-x;?W6n*0L{{Tq-xBaUV z%QVzIbm8iRv)iI86lxvcZl3rT+#Qgy0l+6SJfVpBjz*0(0T?sdt~MA!%4cLf{|#dH?Hn zKu*6t>wUTY&;LChTvr=_+I?Y-Tt6@^4FS1@lambOn$7i*-HDgly#75W?RYo^?Kj86 zo4(^>gOh*<4Swo7snmO1gb`rFCX!W6&uBtTil?`?caGZAD>V^fJc~m;#khVne1gnnl zJ+pQ7GE%giaIbt-Z7!o&gN(4z=x zAs|>{GbiJs<@SpHOu^rSW(_U-)r@yMKQtu=kBc3pDNm*BSHftE*|D<4DX|0-Y%yUQ z&$NPJ?p4mK@-qLl4wS+R=(S;RqlOIUMLJ5ju8Sg9xY6|W{I8WbuF}$st|(jX?@sY# z3n!$`iL~CXi=J$~Z5`uzRcs0sccgxozaFNct@i?kwj^DDU{d#Z6VOBj9Q|&Bt8hTm zpK}IFjU$SuaUEjHE4HhW26Ty@imS>+^k99*ndEpJfmoblm}ferH&&|ARydi^*Vi{+ z5Oq)&18=~6>YH-&c}w;x1*BxmiQ7E6HQdWR_|+v3hlP%Pa!3yrOBbJqRP07?p5~0GRtVQ*EY&-zUUPrdF$Hb)slwU1hZ_nLdT>jLO z4XZqxSWvMWn748+|LZ|97Jp(2V46KH@*L|pd#QCR~CM&nxdP}Ll zl87sH*)mWgw$|z6Hrg;UKP7Fepw_h%+Q>QDJ_aVvum$s@zd0D-*b?U%4m&W7`nHP3 zDdXxnwOh)O}^i_PR&Sl&Tk<+7_QD)C)k;z1R3Q{sS?572E#opM_4B5Hr#?PBz zrGG6z?ASsSq|}99m1pKKG;9;7b4}RsoDLl*QY{Z+^eE+A=!v*aw2~^I^_;DoV3y2i zFBKmUHm7nL7a^)*&zVd1$2nguI}R*b8I4|gHXh%7d{XMIbgnTjQ8$=e^cJt)Pt}~~ zOxsC1NpDfPi9HHhd%5Z<$gbqHn)tItA0sE9`EJ zT<(9~->?{%c>3KX=lM$@< zc3^4DCmyb2Jw+`(C~fqia!7QCPFUVT&OjJRn$WAAvfbo5Ewh(LclT5 zWWmxSl-7#Mgd|+0R^kc!tVA4x-?F{9j8b-Ire!3nw>W`NsMc9W{$^;^o&@A?q^Y$u z)DnU16(<&?RwAw5B>(0xmtFqJTy4MVyioH_+Ug~32c=lNRZE+nv6b-zN;xh+S(5>k z>Sc;vKf+N6Qe0Fuwoq*V8_sE7BW7dgu1w}RV z!yNCQ(b7#pyEcx6Ih-p=rvpHoI7EzG3{<1u205^_MoGa zFh9`4>FNaLLKC4XBIdewAMS~EexVjuLd{#H8Gzgqa8NdI!beQm>cVur$N-BjH(Si0CI2&_7^#|KYl6;2ywLRJ!vgA;Out zkD+RnJnlbhxXku0+}}ppcXjaRA2{mU@eix>hNsRA85%%&p?Un+%T% zFQ6*foMD*$jL2o3fC7oa7RH4YW=j3UOzg3%Py1{2$iZJ~xBYVLLP197W@5gD?)~-- zmcf4wJo$SlRZ_!P*ph{z-%nwU*k-5v@~5T06G|5Y0n5GJR|C9Pk@cT_9dks}Ke~46 z!_D%qf7%_t$i=^60Y3_`az2fK@!dN-KG%f)T+P*_SOQ6_4Q*)ehx6^FMi!Y$FGT|-kLO9zZj^@T zH03Jy&jdMnme!d$sol>QA-Gx-fk$xsU7xWO=gA68nlMA2&U#Xd*w;5ZDdmB0D**aA zG{9Iru~79uM5#cxd{-fq+Y$shfMI?=O|T0Up` z75dV5dvJ$Npv1lz&cpvsXu#6N#m~63gS0Oep)4o}`ZY?oFaYqyee-fS{LZPIpK6I? zP9N1QDz|MGRT$9!LvS(x@)?awrDoB8O` zu~aXAMlgT!5nAWUzSBPY%uTJdviXSA0iI0~rw1!bi(Wr9^2)D#C2&~jqB`l$K@!Zx z`kY{()rgkri9oSvWedf@I;8owZY-w(U^_}&7N|VXUM|hfUIg1~D1C1sU3H``uaSVe zp7^G{7>I~;U-x-whf-9liRZjSsos_*LaFi0I@tDQ+P3{FH>YX$3?KDqlQfJz6CAIoeVVO1mxP{_b+&j^8xXQYKc%mtTfNL|!AXIdrPry}O zp~zM&e*Tl#x@gesXMc19Dvcl$*%Mk*%$o3QvWzjA{@g7y3wz9TIq`2Pm|$2Parg?m zFO3%pQn2ic(w0D884XI~yY}Gy4zmKw#%M*#{rRC^jCyREE%xiLJZsOUzkUjgi@~kZ zung?{nW;2BNZn-9Kcaw3g++7xSUs1?@SY?X7sgdbVSZW*?AwFqM<2`aeeKCTWNa@D z3%|ud|NOeKu%~TLCXxD}aEtb3f6H-`;VS|11Zb5|dk&t@x?CdGvegHD4)-OU*-IRg zT1h^nFD!cG*Q?5L#k)Dn+kUOA?}<@$IJH!qHUBrKK=qt|ywN#jAMOx^As(@pEf34u zjt;pA0y+$=4&kXvsN*SVvkS~vnH3dGep!YTlD|1ri>cNd$#c$@JZ!O%Y04KAI;gtK z;eZ}XTa@DwxB=zkW~{%cXFyv%8ykLAIe+RkRK>SiFv+k*{<)r zcg4SO4N-%p8Rh=ZS2((72e1Wa*Ux9=wB_X!R;0)>xi0PS2T==k)EG{FSb?B@5S&v8 zKb+IC<~FfBc{qLbsTrj|x*n?eM3Zb+Vmt+t8}b|SC0A`2Us zGB9O}O<&QRqEF4-Ya!o8nbOlMnXIl&7gstQf8A5n;A%V55dVg>lPKtKldV2gEBjVA zh6A$VVaz*GA%|n<;TyPF*beTsR-*<*QUiNe`$Lo}Ty(Dub-@1+AzehZGO%0St&wfQ zMM!aZY;~Y3#nJjnNEEf}zK-Cik@mUdc%fL&c>L)pSSEfN{vkOY$X^6eY@j@#q|je~ z$&{rV>7>eMcYR$)l+pNC69cZx&tn})?s9X{{x2kX89|br^@>M-AW6PEtLW_u9N#S| zYsoprdU2i(>&LoT`3s|&BN+PCuWAFB=Hm7WyQnDo{)-qZ_5m6Ts_6V`zrKU{W`}bC z$hwN$xj!L*EPNMWOvQ`Co(2DY`(bg|-)at{Ut)YtuRVfr}_hc@KmLx{BccSYU?u0_80^Udw|aC_f*FXYmCdmU1#Jw5hw z>G$uWii~T*MI4-1OkEYLv~As|r(PGK4;Mu$6kV&+JmHm_(-!WK>R1^y3Q}W&PN?HF zk5!@IL|#W2%QHXP*6oqjVxdPTTF5Mj#xvQtGfmW3P`Sz9QR2JSn2-eZAgHGI7`u8e z^hJBV>z*B|VZ~BfvZe>N>+ioXq8NCsE^rTk$8)$WOZ~39d$O^YE!l5cfS{xLcG_4` zruhH#mX+UavGji{jpdY)`k01g+)9XHpRx6bc+m-?c%z^Z#SZ64;n|Fp+DJe%s~WW6 z(agBV-H%KwkEWt!n|eZcJV8uVzJyhuddm_E(5X9CuX!Q|d&%`?PJ+&>z|)jpDIq)@ zc@p)O}g38#`s8tf;vYMfv)*~&xv@+|>u86f8RQ6q(3zC*uatw)4v;i3_XZXyW z{3v$F@5#We?bD(MNMFfU7xoQxsJa9!rmvF)e5NYGHJj$5qV1L6oT$WadDf?-q$Ee} zHm`)LgJZtL`N3fY?O8#j;y*H(Q}vPalNM`NUQTg<<6C^g+;gbpFXnYY$2@uQ!q>|E zaY}q8He)(W_gcS9S~}i$BHqh*I;}^3$(H2&FT?3LTFel4e3cyQ1~fG37K^AN0T5(X z(%YF(^mWvVGWakgh2RAto4rebsNOU~NU-xEh79Ad11%&b-2?;j8E^k%;t zv1~u^iK)K8Jmp?G8{4D%`{W+H_X_)OW{n!h&~2!iJP(YfgQ0hU_nJv&)!T8W>)W>Y zYy9X1AYGr^724r+1+SjgQ3k*<>b!&7g9VUfX{OQ6)>_$(Z+ag0WzG?ePs4Jo^EQLl zM8GwM!D6R+eA&Xd89Qv0RV6p4x$4msoWJk9Xd9|O=rrR6nx=CFSI;MvEWru!Wk8)1jnI}U(5>eZF25WAW0Z5jC>A-2 z%>7@MqwPruEB?E8Ue~8TI4g_H5fG|xUN8F@5V8;J!pXl#-t&wrJ9x~gNh;n&zR9Ix zKZS{e1w1=??QO?WPSu0BrzgC=mBTBR+)xocT$fQaMunVt{39czDAgOuNPUs;}WjG2btpaG1f@7!2xP`TD>FxhsS{tBP; z4otG|{FRstAr$6F+-a7k^H}uThbh<<-ZUU_(b}Yj2^~uC$e8qGPRyBQpeGRQ+7k*~ zPQ`SV7nJm%V?gZ`7aB?HhbJHV13K0}Z7&{M0LkLrIAHMn!wdTMwZdO}`(NLg8H!kQ zboTekdgH}3_Lg$nlf0pB|4x&Sb4tLCJ@mCdLg7nx&Gr?fB8p;I0?;K6+UF=1+xS6J z6k&C*ON#BTYWuZ1pT|nzt@;n@GUV_>K6mN2BP1uom``2rUDm`McYp$QH#=D8H16s- z5k+0*@l34i%?J9d0gHcAPZNaE&6LW*QpZ+`B=Jnt&(X(BmiCrkFkj?4 z6`HbohfAG(?5A^tQ!m~q?8+bFE&pk9x$VJZ`c}f-(iwAexeNJUO^#tbckV)!juD^f z1PcqAzkPEt^mnyNNoC*9Iix$1o>!nyC-5##1UNYHe@Kq2=f*^;=W!7+TSZKlxbJoR za-c)3?1*ew{*_p|;=3-Y5zfhLgd?MiTl(pE_vijH#jTVS{UuOTn+Um<;ag(VAh zZvim|_#6uLyLqkJNB!{ecebOwycF3`)}6hnScZ8j&(FRTY7!0v45jF0Nu^8y1xzD) z-uKwERa9RGUJS#)T@PP~E1=oS3y8Z6v&Hhuqmq7k zIG1p71IDvWuDdPi}M*pQ; z2L#RQLoMHg0;^;z-B7>st|XkL zJ^>5Pkd|o$Ootg56*OBchJ7ToKwGUJ3uD(t-gd}R?gvwkqq|?0>~N23X}KmdCj#YJ zuh;LOeFZlsBXm+73Uw&w@xQLK4*xr3mK>v!0PDFv1mMR$Ogjx1AJLLcH{YV~Yq%>3 zcQudxY_}Xtt94^2%ooF_PVh*HA-Ybv=4i1Fblpgn5%+peqV8lDY}roMh-&?8f02=& zC-w7vkyUYwqqJG9@;w3PaoqlIUE{7V2 zUu`JWmGVmJM6;ea12NHj3?N_(Bx>McW(87D&sCG#2=;%8z^zrbYyWqc?4M1FZ%oF*_mKDDtTB+U`D_Uw}+oYiF5yBE0OxYl0jvX!=#(d0FV z9WQm#)GXYAcFkSm*96jK!mL;RGquy?#cq-bJYdqF3t<(lIN-`H(dAlt!#@;WCsYl| z5&)3JjaQ(_w4ZrJYSCM!jwjidq}*?9*bsTUelgZUA6PDP&=;9-=aGe&i7Fw@ahX|G znuSR!fd#_$^}NQ4hF#fwJ88~fB(9Y(ZxIK~kS?PDKO}tqTIB(_+KBAn`vCUt<= zmo&+>a{IN$56JiD2S^_OU7y|2g?Mo;*2vBgy}-+(?e51<@aQ%fQ_~~LfM0a*0{1^X z1Bni#O~Rp*Hxxx-$gph(q%CV$>?jcoRa3yTUe>-?8zV@p%n%ML2?rem^ggh&Qzx*Aml6rM`w$_w?*c}BN?^Qdr~c#=7DH3NNZmPPN~Q zRp=MTOFWpqdI`l-xV!srT-%@7fdCq{P+h|-v8}ywap&X1zNHo$#TN!TlF*2pbA{OQ zR0YQwT3g9j)s4R83F1m#*BZagH*|qrBSD|Mx+{<>6(H#tI321!bxG^nm`OeEGQJ`I zN*6=Tk=WIn_PZU0RVe6I%J(--KS6NL+9}2}UUa&7hU5(Z3wyL1lU5MBO{X=NtAN6UDu^<%KPv^^n&jheP;D zTl#FRzaH7ZJ6-qRPcw8={1&pl5=@Gn8|Sl1nuZ&a^UjThxBmxcbp;}*Nhd=%{rfQ= zssom*9&nW2z(k=42C8Dy{tKFk14!C;s;>LHzW1IF0e4#I)bpLlVY}jx1G>x#zy0?l zdk{-0Su$pe!gmL!3nCFJCQenYpNF|D0;=|?nGiMvNJPZE2M0NQXi?}pSW`R&-#M`T z_udQy+`Sh2g2kAxVR^%kg{=>M>OH81cvPX3;hKn zXSIF5nbmg?tA*f4;S@{d%gC1+Ss@3ku5uguen3FE$ermTUgGZfe*3Bs96WThX!rVA z-l;;a%5ufg>H7g;N50J&=|k5uEKXVqaLTp($i+d&C7% z_WhKrPPcvzN%vZ+1_v`>03C1H79;_-lAN`-6VAla3y; z7%^NLVo_DQo5UVgXV$zW)wz=Bdu9AH=2x6!vmBikWP5e&n3lJS7g@K~<#0NK@yQ|g z>f(ykb~itbt8A&sk-d9iuYqfUJ-GytH@56UW!WO#4VWQZj3-Sv#;nUZMk)MS=n+C{ zWryS5n>RB!>K^qaHjcy64mGTTCbr4TYZ$HJCu9?wa9{HFzLR^$u{ip%JX4Bz1a0>( z2NMvD4?(&9^o5Ga?mUxTL~aGS1m{EoyadWB^_%u)XxL*vwfuNMWmZDj?|dRVixw%d zI1r(c&3*`GyyOCKzKWI3)H$qJ)VMhfL~NVyIH}adsN{k!7wu{4+HdBE8=i>Srx-~% zUfMAn+|u(K+6U}x`cm1&0nt@+>Elv86?2bSo)_d-cJ`&GvESg!Fw1GrfHjO?{nD9) zqiVP^5CbTG`xv9=NZKsp>d{#}2oVDqv34MICJVx;E22QXS^d6p*ys1jy`m10D3ER8FL*sUaoO?2EAG zohL7g8H^e%ldD8_6ik){3r|#HY#w;Zxjk?=N3o&ZTK%Z{Rki~@4Wycp^LEXuqr~$jF{uDHYO0ND)4Tu4z2}{5_iVqPk z#7n5+6|=CphT+$>mCozn@+ITB$2B@F`R9rh4$qtF1P9-^HJ_&ZRK=UCY+ilxjoWAs z*LD8^ezl)|ErDLt#dlv=GZ zA4V6~h{lwaD%@WrzS)yehL1~(!!{0{32*p_rnLABy#dFUrcY&EYEj%`0+_j$?w(k- zmBsSgz^x*{~Oy3iHs(C3cgx69+a zkX@KBJ`>(XaD8`s)-qjS!!mbmIt}qIIevUYJ#DMT=|DFgnRGInoiVq4CPIQbmzbCa z8i|f);*dNujDFAnY{NQuP@3iN6#~jsfDt@CDVJq6(#Z6hpb-KiPQNj{=L5I@i3r*L z;25QcYNmE0z2f-g#nEKK+EVWtV%x;@`+4WR@$)SSB<5`OxT-|~mii^#x*I%m`naWc z)X|7js6O2%FR}Ow%p7S0R{n^|d^Tw(1X37bzN6T=Ay6C51HlO{f;p(<$>Xj56^< zZekvih#q$qE7R$h3HaYCB879psI_Is92bCOu*-d`5eDlmXR~%;FNOdng6?_M`HX~h()WvYWy$@7kzj>P7Wg;~M1^T{4 z(D{spJwRqCG{WylwShC8tFFMSi!3`lrL#|7nA8C8y2V202}*f1eZoXP4%b*!%lO*7 zj#BqY4^0Y8S9GKUCpW_e{Kc#jxMmb?5qAb*b)C5Qa6^o-5I< z>hVMG(u6HyS_#cU05i6#TJpD|yDx5QZhsd(5teA3#xwyCyNz85Zoy8JsWaxz4!e z@%?3Ir0c^$mL5TqxVDZ>m;EOu|Qh z(8~)^2?jhvCAb*M8Ia&+pCX_QZ0?bq7BD2sbl!?Wn7Ikm$UQ1-c8`Lmx|S!&b}o>o zsTg2gDk8`@ImC9D_M2}z_Uw$PYyoxW^#rhD#*U2aqf#x*OxP9N7JpwL>jW=U^0-*m zd=N8h>~Q|sJV&Q!+QP{@0F#74%Y z+BR6H!_@37I+%tFUnhbV#muoSM!X6PeJ~k;OI<*VQNMc0acQJ!8NGeYe%fbMgITp3 zYj+}?eD%5Gv3{@vdy_iQ@?s@DjGCbNor~zV$(A($Xuvq!<*q-S_O6SOM~i{8IKUX- z1D-Z5V?iO8k;1#dFuacll4*f$M+p-Vf3YwF?PwAW2Ux;h-1vW`f9;Q8F zn#<7`0WKnPH~EmaETD&}(PaM{oNwK0&bhd< zHT3r0-tMI~2mc7;=;YncmnAs{ImNYhH>JT!w(z^m#&?z^ZVx zvi>46+)@Y#@%b)o?!Y>u6z!a@;a)0RVNqWg_xw)JAl~vmkJ~9nd!~~kLJeSL!vI-F zCgD@7Z6g;wsrVghV%v8f6+QCcfueoYurY0usD-(q!yd*z52ad;oE9ck@Z5i#w8C;S zeW&L6Qq47VrwX*X&(B({IEbmNH@+vy5hush>?%2v9en#x`(vFi=j7rB9k!!sv!dXu zP>}Ypr~GB@4{qy7NJGrOxn-8a^a*YDb1kC3jll{1fNk_ue34jbf60IlP5xN_$44V3 zO}S80*tMk7_*M(%^~Xo7#JBmsEJ>~hFI7fyildxo&+fXPlr4wf6j^Is194N6k-lyI z$cRi4`M%hApu@2Ahf6?iNouVO*zvQt2;YPS`gUKg*r~6`Jq4?ZHmtT(U}5qtobwA* zvX38atGI%(6iU+nqVOV!RMFj@){^kme_?dwz}mJCP=R-5vDUT>9GZ|~dVx<~ALNGq z=K^h#-C;RcyhMGVV(XuWt>9VEpvk~&u-b3mPkuT6Bp9O?<_9(l=G#tPYeX zArot#4m`eo=P6J1xDTeDGgBs6h{w)q!s!ZBTgFo9QFt>}#Dr~n-vtWFM!tg^qYg{7 zwngC$Xa;%mr-Uc}0<6}(&(Pa_1SfZi4bG;kzO!!YkGQ9N8&+R+l0|a&*w6weTf1KBWn@H$T z`29fg#vaiRY`of2ja+$WZw?Z!L-Hdxn_uc-#ec%4hc>6IBgUrQVjKbB)T=r% zWzTFSm%-B&ZccUK3!j&u+9-|)7Ag8lr#MJMtjW5TTP@G5jAO2q$o|yRGvN^;vN#ZR zAEoNxAc|(#b8egY@EtzfaLI8dRk#;BvA8Mr%OPSxC{XE^{A7~@`aYsW`ddeC6I^tL zwLL{-mvfyhAH~9?ec_#G5uM&`B}&jq#?1}#f@!;<+0RzdLy1AlLvO$J)vs?x(PeOz zE@A-&moIx-o8(xUDz`fXmV5qOXxDI;j~;)7Oe?A9JCbR6@@Jz_MFm4D1prY5l~*hR zbOm76CcJu}YY(7}Q%xTB6SB!Py~+g{nsj&#m-i8hN6RW$x=OOaG>+;t@hWPP6Vbo76xzRygzcI zj!SvoV*a0=i3zESK>GWqzbCCW9$@YA{HE1N-e00IViKtHB*Qhk>KA@ed9v$6DwLzG zgbl@WuQ9MeF|<=pJ{Yi1*6It)^?B4jy-sETj(|7#HwsOw@vEO z*TY_%tQ2NWgC-}o&UUgh%g~#QeUT5oR|Mk-ihn4yYbhd7SE3jEJ#O79MsQ5YY~)X# z5N6=yTgmYDFEU5fD`Jg8_`Ml3x0dF{Cq~XkT5CB{6P0h};^W@;gYJp`_QL#2pvb9d zldI<*0x{(<#XAr$Z`X$W#LJ+3=HHX_yJBgq%;ueJrwt_Xc*@*|gg3+d*WK(H(J!|F zTK%cds0>tuMRK>&#V6U2+EaR<^8)(C)G& z-`<-c0k%lAJVd>e+z~gLT*I;e=at>eaph%?uDz=Ee}$6)PFKAm!b_#tA2|kvkOUL9 z5F+uTSHKioY4Eh4?FCWJN1T6f2DmvcABdO?Um410bxl=0q<@5D;KLE5|DBkU`KT6#JBIv^NpRDPFuQa(%YZz4@t9!K+6V-%?Xgy zu}h4n`!0*z)(Od4-CAIiLsm$lT&o~iSR&@{D_kEO>AurGx} z<_){26uMY4a_D%9TbY!M`X!xc{%qFgVE`Z(*awqRrCGkVw?*HORKA>^>3man8Jf8V?oSX)BV7@#MD}}^Hk;TNv z0JGS*E-LS2s#b(Ck*WvEJFPrgG33cs0(9ieuHU6hDnAMe&__uRB-ok~*aqo38N|~> zeTEh7LQhc5m~)=9gH`s(v$wM(4-%?GGRo~&X4soO@vES>cauRf;*@ zek6_F?@3Pi=lZM$0(yuUz9FX_h2ren#%wq9CtOmR;5sFxHE4AxSdtasa4$o(BLt-? z0nx~Hhb$_|ey04`bNKn;fiXWjbvZPhzQ_1FD%aAULYBM1!+Q-f0Z8RamuGNZ|7RWq z>_bFTkEr7s{g4v$BSZpfBa9Hm@0HzLlV#sY_5=pYTh#j|EN?pjl=#v;H2M0)>i9d0 z0*f~_!vS9>M$*h6##{4rQ+FxPyP0VuMP9x94C`YHk`E(ILD^ofxflkc!0=+&s#Gd= zX)`K%8S<+6DG>w5Y$)UE0!V&$@~Hx>OcNURo7%^GqSgg=O=)`p`F143+j!G`3qaP_ zMXz97vc&D0KndN3_8qtb0p5!9cD;>0=uE8T{_`sZ&zUIEjtj{z<(Mclwbf%KcV-sW zoQm?U#jo;flF-|!t>{Uxswx&pKcBh?bFioHaxbj)X(SIZ}vkQ=1Yg z?P0i{poGa!n3e~D^1+UsEn_IQZgBd!VLy!>lAK&KicsIM80q*3`@Vj%K9$e|fZ(hbr^X zD6?u8;*5vj$;;z2>a@_6>ObdV$2BIWPA>K&Kf?j1cFB4^E67j@BD#f49V7rG1R`WI#eEz}d)RyHslM2WQcHsF_! ziI5~md*K_opleigvX=KA4*I=aA7E0m7eStmBZe!K;;?=`9|w0`vnX-;MyGJig$- z5E_i((KhZPoO$OjK-jtaNKNk0pDVKmxA?D4_G62kuO&|zE+iZ_R8`ylm0yit-%q*1 z<9DS&w@5`2AobkeVHXA_Nhe-xk=x?IwLph)w`+_>uFcC?+55_bAaAMclOE(nIrCGp$er;^p9#O@5%jJDtcuI&T&me%}&z1Q1r7;|<}sb?|%g zFZjw|_xNpe(^*GdL8oC8_b=J~UEeWUR}36A+hJI^7}-Tw3J}@NR})i?|6Yj!qU#w{ z^qGF&VqSn;Siwsd^9_`?6~6M2IeQ}xxh_!(|AyeaKl1&4oT!l@q88@HxP3x)x%mn~ zqVQVM!td7!av}=$Fhbq({&D4XzkP)FStgY<75CE}&L=9$(u_nluIYX2{``{Vg2m|) zM7PbwDl2acinlU}Z+;+txQ^d`=_sp_Xf0zBx`7B1TBn50yqc^*b%j`E56@>R8Xot)A z&aY@N#nxtPM!K4&z?j&X^~A)$R}Co10>{tlxzJh4>?N?1A#aM#BB(Y0&Oy~H)H*w< zX34QIqeAUM$Jmr&QhdExEQFLb;_63tu?*$|2OH(C-P4&{DLNx^$T1J)YSRPhUXlRPGJ$cqDOI&DovMQL2EE5uz{#2zKVkUMYP0XeKX#n$ASh7 zwlJ7|Q_=%=Bzdv~;#a9T_|h9kH7CrPu_Gv^lw~o9ITe-lZb&qJ!-n%eeQ~Bf#a_D? zHi91gr!nzjc>a4HZ_TM{CX@tINQgnL35+-9sjJ66Tmt56`9@{#C*3q?-|z&=YTLMi zuTi7Cl=9z8GA4CcL7f*cK{;5+Uu13t>kRZjVfYNKY(+B`pB=&Yf|SLtZy9qfC+&6Y zA_hF3&o0v?U|HI)HNsWM9ov{*JGvE8KlAK{M(nzb2i_INOie&H5bfkIY-UT@G5^I$ ze{6SgUXj0*v-h%)#llfW`q1$SRF38X;I_mN(&X~suf&En!bJaQgg7Y~%q7RmI>DO+ ztFgPf^x3oy@t)8ZZ@QAq^hSTABb!4<4}?(N+djtBh>NP=l%whH#bWGKdKzJ3=E zCPc@p0BEY*=5d$5OeqiOaSJ?X(23~2s$U^hSA?iN`izdy>uE(}8m=9F39aa>!7&;r zQq`^gyQy)%Ijma*E4kDrsuI+iIN1Q^mK-IB*Pj*D(^?YW2WmN$maBsoQbH7XR`9?E zcm+s-qy)N>Wg)yY1{AJVUars=e3niX(KDo>f2vb&O$UAs{$8O`2QdB~s z`c}k;j2zIE$)_61H%I7qzTY46i|coCcvjU``WdaV(H-{%6vk zH4qS0PweWgd61Nb#iw?GqEK^$br@VwwovOp_K~XL4s!)m!KJ|>Zn-#F^@c^FIuEp{ z^Be{-X&d!Ncbwv~ckA78nt>AYrRq93)-QrB&?l532)&)mDs$(DC4gV}j2pWW!2XDG zELg{RSZL%#1eGkDkp{{_dH*GrrXy6=$*EIkq%Zo<`!-|VbtxTz--pX5EgS2bE@5hb z*jPWJK~W542LMWC;-Mi&?Js5>d?MB(z)QVc_po*d`zH>-BUcVb4S_ZebMc2Vu`4N4 zS`ngTyYWV(If+btV{r;JZ16R$1*cvQ*lMQ+DuSAL{MWSHrg~yVdbceQ(Ac8hg!xs7 zqp4%B3yaLW%x$7zldsI})=2V+YWY$*3}dw&WWsIipayI6bRo`^V? zP`AWRp=U+;sTRBfcP&p^bwl*=YsgIicSlxc??@K3J{GI89RJ6FsbyN3k#aJ;(ir`# z>?g;mU%ZO~6Ud)aD4A0BKU-3oTuYBC$0SscXU@64I6Ktz5z@bHt}lVEHDQp3r?yLu!4 zm@3fl5xtuBbb_fRU634$Z&$tA0OD1%-kg6Wyjx?rs9DID^x@Lma;)FXZWRX^?6H1D zyGM2)nW8Z_o0_qU;8+|*cZcejWxu4~4imvct1#deP$grGG=UDj)rUD)*B8?;;ZNwQ zRJzyWQw0*y={GcS1^Pg$LI@JPy418U(x8$2m3_i)u9_B03EOrUS^=fLN4NrB=$4B> zSxdyEi04)AJ9%L>WW8CKQe-@?4SG6NUX+8P+2~SXo#zFZ>4HjzI@NN8ptd1auMl{65|-L9|&)+3^ckT zv#+bCI-IvEx|@o!2oNLP*fO?w=Tk6$*^zJ1F|R$^app?aR!^B2HP=eJN^bN-t+*x_ zN1-`OH`*&Q86YN?zWsH|Uo)QzpjGA=hmk(61HA)6E%afr)v0tAWa@ZpdLk*?Z|PDa zJLLm}Q9owMjycVwdbd3u(WMTonl606hngMX>Z2yb&=)inJCkAh0t%x0<(VxTxFd{(z@RlJQzquK%?_$>SRkn$=8pnn`;)sIqJTeIcGR!yFn+ zI~L)Up(OzP;I|24s;$hHC7`?W6o8B;tm@p$dS~fUrO>F4Otz=! zY2itjG;oHCe6YO&2(WveW77n}nOquhA`Z09xaVQ6r8eHAL>#mV5FU<*bAZ%4D808I zNszyg-Gyu4iF0XE@7UNt1tTqn=#D%y_ z0q~jrE!AK=^A-}>pydl#R;Ib0s0XR@VEwLN&5t}Vc3{kZpz&N&c650DUO-uet;7-c zguai|g1{arh)X+O3e|uf7dlr$Gvvwip4i2)ZLf`RViq_2Q>+6@S#ka>PTpCE6NQ2E zgBMCN76$d&O*FBV66mK64#9NyEqB&VdLjK!v4qrRg56qLmRvMaa*lKu;rVlHpr_D{ zCxF{nso&Tg%txjj-Z75VajP%YzM%ucSVVgI& zX^J^aT02d{E2qn^W}EDo)Ug&=HnkFjK8AxfO*7ike`*D5IE&tdCboW}ef|0E5|F6e zPe?Dzy+#zU2@j>(;PuFl5J&gZ6NPf5SZ#UF26OdnC>Wgt9bR#+Vf0E;IQfuI)UdxJ z6;V5QVDmZHR3JcouYlZ`0LfXA_38Zduj3B?s%c$FqnnvDC9g!q);0g(Z2#)!_4Y2> z<|0UE}wh3EN|%b*gh4UDB@wqBwK4 z)Qu*-4R}I}hVf8*3~*Xbs``E&A}q~M|A)DE4~KI7|3@n=tO|*caVSBJAE?PdV*D(RRpm+y0rnte+3lEiaB8wrP}lvrUCxN$(Ov zMvnP7#_UgyBhC``snbpjd>zh9OC~j!MtN%81Uel2wZbh;{Q;AHx?ni6{e3n56izeQ8EOvlauy{vh{4DhB#9oSl+4(<9X{=Z@^ar1=~O$ z*M7cUgxjqc2c(#DSC%73W?ROa@V32fFQ^kLDCY;00R0PSs zo`E2cu4q6yzAMhedb&bY!cB0bbz0r$fzVNA|3Oq*!F zqR(7Az7cZ@=u}3c$})5E0^gdbLndOa?;e$_;a#(wUfTEdAs3O4Fb=7S1}=L2fR$fG zBvc^w3&>Q#hdeQ5uG;r+RA~5{xabMD#0?3uw)$ol&xhQV1sk6=_$EBG^iseq*+ z4~DLX+OFcInSc=_?;wDW@h^E_95VLMyLi*rh{uJ*9hU^7Um4)=RZe5g5BkA=<)bS( zcIaK+?pC0SvrsaP`jP+aRxwpcs)p z+0nMna51Oz-YbbBt}>Jk-W@?fLoz1a{ChEQiqJ~2cyleOP?}a&wdNj>$nf-ZR^2iV z083M$O2$3rt}Hv~A`)>UJIIHk1{A&?tTL*}jl0QLapJ+}=w$iWm^g1p6nHg=~Y0-jN9 z=ltdWWT3vg%7NsO~+ z-$Fp2Ae}Sx$6|H!C=EX3#AwH`Q}W5^4#~5&^&T{{2T&4yJbdK&ii~k~Km<2F2eiuI zKWbx-kZhaiGKd;k><|1Y{$QwHhGCfV(L9r&6+0#}hG<3l)JX^6C)`S2% z4Ij%dHxY(!_~f@!d^$rYRrYKf$QQ}W*nFQ!XV|6PK2r#lq>XAgJ4gjw*rZ_q913%^ zm-dCci8RywC_$=I12347g&r+1S-t~C#RC<(Ks$kk%*rZT0f>}Fy28of!kua>K_@+6 zd?5xuhojSq_iQkAA^MpS;23ayAsR-TG%***i$ntbYA^oGfzS~U&Z#<|1vhMEh7TMm zKxn@&HLi@Qi}juoMs;`0Y8&vxFI9&4Xk(e{w(;b?#1>GCOGpqq`TcKUiEAMUb+jZ; zFa#?5t-}y1--_0E4$)z-sL2 zQZRoaWKNQ<>~OCP?6xmBBFG1=`Ye(^4oYrYqx`+y*W?<7Y|dnF+A(pd zo>SBX8`m^m;du)=Z9p{ zp=j!t91js?n+&1A?$Ggh>f-7*t7-@AFp|n`; z8%C`R5FpG4g>l)4udF}ll1?3bUCk-k3VExui-d#^yqa3T`9Vs+cv$_Ue8=&h`g9uE zmYoGA;DmwrZ?K~?@7)eIhRA?fjnq8<3L)T?W+pPCHLd8qtY zx=71=|3@pC&ema(!re>u1N)viOq{{Ls}WJ<%}^&kAv(BMdImMyFMO;#+&)YJ09NlM zM)(67-MrEzVG3jYI5>Y?-cGH^Er2;bB+{Wj8ZjT#bKTV`4nC3ChkfTDx0m^F=*>R7 z-QXdm&ZL#goNy^G)Up%r4L1!O$tn1Fm4IZIdSX}?1omw!*y z0s&)(5VdE2kPy}BkF53K89-v%Rj!V|@u&}gH-#lp)#EGZ&958J93%T#Z~LR}jCr4g z7!$R0FkHX>O0Fe>X-Q+>t|IsGB^|+fDQ0(u{~$0083f}#F7o;P{zMT-sl5A<)@s|u zH0@|E=YJ5d^?KwM)?F$61vvd~BHqjK3vx9pQ9L?N?}AIZC5LqIk1Vw7Kzg}($Jp4OO)2J4clk?k4fh_l}ltm1d4TuT!UZB`_I6)+Rv&!}bspa#-dmeT)zGi|nbYL3758y2N=c)gcSEFQ zJI{UAJlV<9v&_lSw(@LL4my&-xWli~a6zJ76W6(Wi3cIR^O{E-B7eqFt}JFG=IOol z?Q6nzo5eKNkg}{~;gO&GgZ=h7+KzaKy?Ezm9F0wUd()%z&h!^ck8kzg{Esy*Yy;sp zJkv0DdNJV)G21``iA(srj}zM{`|QesUE;1a^MzdBjq0wGY%Wag`Kks2Zh92aUyD3ax~U7DC&v^Q(X@QW{cZ^B&llpy5(!vH#i)Va$8%an213oP2Ng`RmKn zB+(^%-7e1(4&7;*8z79XLdU}Lz<({tzJ2e!7xKh6>^l4WDuNxIr@L8b$VKJ+0J%1Z zp|a?E+dKz5S6~`sq$-S@s(O0m0wkr*O$H0#l`LpdWv#qcj!n-qm=$MXOUr|3RPRd0 zKvk&9z6onk5CdpW5p#i%ok6ZRQ6pQ3VqJPKh_H>;XWs2222((n+YMegb1Fmc#R)cY{05e$*A%nb^mY5j~)+1cPJZRcI#R zQFFhN7(#inn%s6v(^yVQ6|97dEhx%|D2bQh3S&t82KeMt&gnvyT3feD76?|rGwIpD zGj^}frU@-FkhYqH$|V_nL!c$232Qf+^Lz=^e!UQ2Ze5o1m?{CDti@3SO{K2aR`KAI zqG7OBlXX)|*c_hcLJqaim*r~y@me_XZ|i9-GHIk5vpI+hJ1f%HaD-yo-qc;_7|EfO*{ zU|{Hoo48FFimj?_Ertxf{)*U4YLGr;b*F&0W(6VIOo1rl`a+vHSR)@;v8tGW63u6d z$*#L%K0~e!N&{Z27cv2zE$2#P)2?*Debnut3 zy9bwI(~3idaTrm3`Y#C%p^%tepk99xR%FMx7}IVKfQ(cm?#9P+QNk0H zbUZFr8XhYNynj@mo^A&NXD|f}vJLaLe9zmb@cO_{*K}&olS4CcEvP%AKkxlt zY;S6i(EGJoW#`mo7*jAc^W;70grDX>3hI%rH*H^qj4)=0w8<6M+nmTK=JurIXY@zN58>N54Vt@|zT$eze`?aHw+*1X z9>O9>rBif;w_aD5V+y`%PQiQ@)w~5)c|45yf*nJ>WY-Za`;ESslemuGCx_i5s zxJ<79PNGBizfV;jBMfyd4}^&ZJB9HO$2fLt1Vu8tCax+hMy64&af5E~EG7s>V-q5~ z-|3iO+c#_50d{Q7aDNEtLP2df|DJMX0O#5{!Vv5w_AxOhpPC%_?;Rin#aiI&&(ng+ zmn^OIg+nP!EKE8vR2Rt64bbE*^T}s?;kiHA{Z4bP+$szvMM|t^*hux1=U9dE{XhEk zyg1o;`BpFs(?aLgt?YO?Km*2j4x?1_AdI(?6AvhnIOCW4Svd8(S@?*)<9-| z&yzU_VZd%b2ZEnC+=dk{It86O-b;gI%O>Gj!F;4NqXBv}uH~>VlSY5qu6Qo5YEFh4 z>nYQwIgB8q79{_Y7-x{fDy2!WU=a2k!cxO{y6VHd-)ea9wt4%@dX5w#s!vM!0|?3i z;%EF%XA3Wc0-fiZdzb+L@?b^RF<5bs;*TPolDpkB5~i+=`4l`G_Ps3CvK{Hh_#RBX zy&DFEM)F9fi-OJfE?-e3kk|1nR1C#9fX>r-H-vYB$@1DS=NoeRcL6e}@2K^(;`_Ue zwguN`7|@H;R6tt{T_7JS_hbOTQ4tQ z?h|v<=SWWbd7nW}=}HQWmo|vEpkv3XG5$3f<3=m%ZgPd`fJzT-dK+|5q4aXIh|ki{ zZ(eluB+s`L&;3_hRZGGic--qzDx~#3B0n1^0F`?kHJ4r_NG+HB)wTmCU54j+nt`~tk?gV`O^%O8#j?dS1r) z#QN?g1qqO>J(c_ZKt!5d;#pZIod?<_knD-La2z9U-WygeTJHd{p%AoK)b~j&u%{eY z?^me-?T-o}!`VEvY$<8NW=zt)tuQ5=09eTt| zoTwWf6dWo}e^kEL=%e+XM2MK!MVhhy6tf(hH#CrmQ|v)4YkE1Bi0M4C7+*h6!Yc`1 z8x7M}DNjr6v@mLZ_)_hl^RpYuY^>ar+VyeWk$?TJD1MO6+!J}}h>c15y2ykn zcGdNW^bL;~pJ!!!beI7{o8!AEIa%a7$CpA|$1`yi!!mG`PfXBnOrp;zrkJSYc$)Q^ z4IS4o)}0+_eIMcN?%J3jfe`}S1$H@@JIM`7;9{dSO$!OzG0M@s(#8;^$H<=gCjWAWfGR*hSYiiSV+}-^}FQ zzX!P)Yj)_={D%L2&B#?XDo)?3N3Nlu1s90vf2n%qH~Z<=%|E^N!vvvW?Jv;%-T~gZ zO}@9!tyPFk-wZ#;9b)ePbq{crf2B9WZO~}nZ!36udNOsUs+pIZFWU7w2Sz}=Or4KM zcGlqS3Fzr!d&rx4U<#$9+lypsZYosaH^#*tYFnHZE_5xds5wkI@wJks&?!Xtylc#3 zMBW+wu&~+lU;CPdwana^+kM>edsO-FxeVemzqvE&Y&-vBF zw|_3Zl?EM?tf|UifgNg7%_2-pBe4Vc!n{K%o?5-4r8nCZ*yh~@JtsZHnta;BpEq!B z_^4A~7%+NxA}HM$o#SaYOc}$DVLA5L2VS$wwvH9l#VuvoW8&!{)OEKtLI@{NH@ zqH|$Za0kvVAUdKs42F@PoZ;S!M@6Z3AV*c>!DH0=Wk8NdLF1CW_rLGIf{ITypY2Go z{;2-OvS_Ck=Jq=uRuQc|9$a8cTq3IGi~HQiCgJfX5h)hD6~D<=9lADZ_uEUCK1zq< z_)N(Y9^Xm=-;tjWK36{ZSZg4;!M=fcas=i&->V|@@5|nCV!zcSCTRGS)Ly{E=maQn zq_l2sgNM7AQT!S7&iIfFXG7>sDR*#6M=MEyF4f24vPWke)AkCxtAl0+3PJ%FSG=@5 zeIUYdYC19fdslYa;iC*T3tQS-Ouoc83|Zy;1SkAg=5Ca;=@O4x=ffaPy06kk-5gZl zY463$^_-AWRzWW~iG|85$_X#cnFG!-wkd3Q>_xWaE%g%U(PIuMu+}qCIHa2P!!GE= z>yJn%KX~({*~9iIrXc3Z#WD2YgUc>*TlTV@XSLlJm9GfoRLpeoD4R3Rgp?ulmW!y} zwaMLkcEoT#4Zq-W>npR+4f{QCs;6-8XBoA@h%%#(4zJ)5#H`~{D&i#>;>~F8Y{oWr z3}43ueK}rwfZWe#sKNAwi*lX0hWN*4b@hTzvQ0YToZl3Y>t2Blse{&zO)g9qGmpt6 z^Cu1^nz~C*Vs(10HdAP3 z2R?Q=$SoSce!l_4_ALb@e$%ekR^F7TKUW+D%Vba?J3~|@d)ruO?6R1!Z)XqfJmIqr zyECIW{^W61D(caDkRz7@JH1(FIe`7)!A75>OOoCL8(-vlF=w6l{MJM11}$FIV@NmG6$_4NRGm|(61LDq$;2E8tlX;t zi7k7W6}%{lf;CiIy;Y28&<#UM8CAo9nS7KuB$bKokg@<~QY}5k9`u!|W(8DUh8*j# zBS~>SlBzj@ZI@b-OOCU_yTB<^QY}H(zbs}B{X@F5Rb&pm*iz#`O60h2<-6cDKZ!0b zi9_FFxy)>}IXHne6P9-2bje_%)St7fJ>0%Th_%t94oQ#OmLzPE99OW=jqB>i^+34Z zA;p1w6RbruPL!zI1s21w1^sz!ZUzMLVMj|uka!=ID3mf%z7utJSZaq+3%W$KuugIV ze1sM@L9~-C*F$SHdzp5UiQ06D_K8Q&1%e4PE*Fr?IjtJ(!Vp*2TtB5>9)62z)kZTz ztVO|AmO3od9m7DJ{MJb>7izL$yeT zD9X3a;+qhSB-8m^QwF||ITfjN*Jsr9FmBW+4^JxYBNQ_xp}g(5+G@S#0nt18d39k&7Z%m-Qn9uqy!FOf6Aq`Y)rc8Pt8>V%N<_ZJznKxor!C`$8-&HX>eV zX)RY z(im+fid`G&^CspzDsp}!_+D{%eZ0$Rd*~hUN$g-MTSi40=QVA8{qFQnT8T^P#S&II z$9>iDFlGd@GM$#A&1s!bjj*jU_NNYPmqL?EA6L?TGSQtPqjJ9rVSa?RCr^w3!ARzJ zaoWU!H92SGl-TMuzXcTo4L{mU!7c(UyIE~~gQ7S@|?(6P)^40W)@7ip^oz@j*-Xi1ojO!%~qB%YYaQvf9kvB9C~0Mo$b$YAAh5m%*tdj z$K!m&oz&%!W#}H7XBd9f5S0_8*`ZJd0kiJ=cqUruf@%_}iWb0{Z^`O3vhBc`<>}G` zE=PffLF+6s4oPL9-LqkjREb>{B_*jII{9osOYa+Y6Df7v9N8nccZ!nAQ=jl?*q8yO zZrjxgMYZZIU1D(d(nx?9qTVpmf2PesX-uEYE`)N^Hgu&@W^uuMo1HTgBA)!i7CZ86 zsCd>SzC?5Rn`Y^F>BUmk{CCgN(ykc7L`)WS#OUf1_}&oE&eFEU`$-wJDC#^h!I@nr zYZf{f)0sSnjTHOF2m9u`UE!3|=vG<1(Y2{N)aYoUY`3B?_`t=g2t{N=7GvMHQ%7uL zhfMQOko3i`LP-TgY8#f@;&p2=cofQccyOVe1IUgzs`Nq74W8=mgXPbid38&6nB-Ix zg09I-1<61+syegpEqr1wvxLG#R#rd@#%;4pJ)pv=jJM~)TVUgpg}Kj2|AgUfho&l- zr;?hwUU*l$Q8-k#QLgSUI)+WMN^Ypk{j&D1-hdLQR|51lAuA$hEUg2-MgE18)00!uc><;5wR5wei9(1 z5>j~OX)NK$G#AZpdCXV|Pfo&N+){3t_kL94a54-fIt?p4T2N+=?3(PV6i~}YEjU`9(JDM7 z6qiJG#*sT85+QC#_MmzQyZXovk;gpXMG2aNMp^ZcSyC9T%_2y@fXvg~u3#(|-a(5> zp?khbsnAk?o~RIb^c8nc=k=ER*!DFM zWL8G$&GBkmQb`-AJioOczj5S0m`TA4L0(IOhkpY|Q+Wg+K27_+YSql$hCsVb7iqt( zoN)E?@JFYd7=^#l-O*u=^`XD?yu1iB47}w2@Xt$l>;jDXw)w@^U&N!IvH&2rSU;xc z>aU=7z|X_1>H2@Lw%(V`a1UZ1`mw*>%6quz@2H#xKLCzH3cBH|!d!S+>nY?l=eONh z{Pmi-4se5}2hY(~KObvp1dj4&mu39EVem*w!Ha4gTKp523m5$r_v5FEAWJcaI>kTs z)P{KEH8uRhX}>=3PCY>CE}Ub%tMDIlAAYWKuLJ$Z)T!X71uuGyJCOV*QE7VZJ>^v@ zRe=ln%q#Y(YX3pIZw0u;w@-ZkehW)|H;Qn5!_crWGX?gmKB%7zS@;<4b!{nFU>8%T zZW`ECl0m{Y(2$Nzm*(d`R<3H!y7>BVH~%gTY0tr3kh7hy6b%s?1AJDM_22>cVIivU zZDy*klp5i_ulu@BtX-7sy#6z1UTM`mCR2tLH)#me#@!I7_s9T>|JyYv@QvqX^C@Tp1iv9k~-`F|B)FqNbjq z8p;vje&Ykk@+PbMF1}=aO=N%WdqeD<>?`fPT=spay)#wszoNn2X0*+a_O;dFXH z*`26PU)zq@9epP}^q^1UOr500OO&ODI(x(;bw_DRyLpsTy|&kYkV^ZtI$pO7>Kn_S zRuwm%ux0R(ra8sm@{gQSOsoe(pihGv|RZJ zWnmDmVE=`$x7I685zJ)cwxaeNk3kXasMyU)JuT%27EwG8K(PWlWo;W7( z!Ld%#bFkLm+x}vYUiv3M(>=Y03Lx5ZdWo6#04eZhqYZ+tNwlKOQp&agiA^qq*wgr4dO=etgs=-GSK z(uG$^;tm<#tq-@OmI8X}c_z{`Qs4{UHirc{V?UZJ7SU+wLVW-OM zBtXhpj}I=L*02C8;1QOc#$O6&b|{iQ+htVNWpTp&rBIy!p;f<(yYRvxx6Aj%O>LyQDr2~MG1XOKgH^!Gk{9h!~n zmbmOw!kT(4RM!AsZx36W9F$ug$TZha9OwaPbc&}!rRK&nYBEU@rWXQj&ozITKc&Xp z>JXe?YBxQJZO|N#>a0SrqT~MC3h*!Ho5NCA%pd@*DC^@N)8YtXxs3@KWQb%}-$2x+ zbK-A@z@sI}$UTMaLYE=LBJFUWMLKN@$dFP;Nhiw!J6Agcl|bgH#qobVTpE!&K~&uQ zK;u($@Hz^&)$#VYgF?BjM;R32q1??Dp!F@Vma>*P?a3XfGaB}f?R(zq3Rk@WR~!=@ zJQev!zA8+-Di+0^CMe%dw;b{uJqZ>FUQMI&LVC$T;Ed57heG{7dQ zV52VA_?PD>?l6pqTuKrir3@uUK~PQ~l$`)7V&A7nA*cxFp&kBEl;rfB;wiTw_NAX+`?bK`<{Gaci8_uG^#nm^S=v?$o2pG z&bpSD@f?r4Jza(b}Wh?{m;Uq9I2YP64EDMh%ZU)5k*v)yh>_izT zVWxQw;vDZS8jcHF*S zd&NfQy3sZM9rfX?&C*i)7qm_crU#sUSZVfyi_g7s*K_OB*@h|&f4vtCEDXuqU2^JyFNSkVGurVKAu-{1WG@>G%?A(Bs?NlyNQ@RmQU_ z*;V@U=*4nvul7@TD5}t1DXLJ=pD*HvAmN1y$1v(ArMEML;vzDr*qO$z$k=P9h4!*d zk%>}uzdPN9U&i-M4OngeOe-ygJO0M8-u8+_%i1NSl7xZpyXo4A$FY$&ucxECSEfav zy~a05((h|@rJ@&4g8WOl;czBhNqFzgkBcs^{UjGpQvK7w9?#@i7_L5t&HFe>dqc}5 zpQi0pp=6RfW;1N?6?{0Y*Qx|9=#C7pG#AZ1%|a4*-RQ+zj40X3X!i?=JtibW$wAY6 zK6t+{)a-kQ9pl9mgzYeZZ*k`R{vO(eP?)em zV}*5QvrI=?&`xwK)gbZTJ{eYAOea8cGXocB?wFtzoyHoIIo28~Y?k`#VywlhssOGp zZzW34ms{5iT61C6?=1Z+bzj^!X7|K4C8@=elhZZl!ui#{?JjM#t-A@O78h-dDxy9I z6-M*So2yy9>DNasyta9K zAZ)Jq0+d^nADK2*ZtxZ}#@q4UiE<9Py)pooiHB337AXVUPC3cy4W#)^U!Gr@m-OX2 zet)#YS+U;XGE_mj?}G;_j2Z_VcvDI)>EJ^T>|9o)2WZ}Y$tvF6W=xNslO0OF5bDtu z7XxF_(SU^dl?h{JKt|U2?*=z3#^KqZtJfwb&Awp7$g&4L82?_?=;{M1lxS^8GnK;x zDFdy1O#Fv+kbbai*M}(dFrM)>u{16ef9Klkfm_?ZL|6bsEQFd*hc6YUZgQX+mjm}k zlg~`PvE53t`RE-TFiVIHnf09trna&J$fx8o=Pn|#&6zwuq;wWDg;Fr>w90__DSl9! zc`EC5wa|);;oPMp?D45LSIA{nJE0z$mfE~OX%VQv3RH_(r@cLwC`J4H1xJ_7*)| z>98%Az(M`3o{Yk7v7w~zX7n)9vyg$BW{01O0_;khd6PXa=EmJ?->LCa?4{Br)L@VD zyPNEqqBigLpm3$aNw2wM(VY z;tE>EXaN&;6I1Hy(3bh#csTdLXr@L@r+yY$NJU3EqEJ=B__>^(G%oA#(JuiKe~?+P z{!uP&uh3=Qdo{rV-^i0CeJ7sBuVAG2f`7j=UA!oy$(~AMlY4u6O948HX&#NS)d;Wq z4LaYiC!7KpWb}M%&6Qtdq7L#0I^48Zt61&>V4%&~-!}dS*}ZrMNGZ0Z`_r$B0IkZm zxyZvZ{t5EB7!=?>Oz*?Pl7E1a>=poHf{s;+zg4jO$RF^3C|<4W@Kb=lao=!ZRd>6B zVXw*nv~#$jvZ|6*@S8+9(#hu+9aq{id$r*XdsR}JYJR^B>ktG!R$cnjh(rnvqlebrT}QRX+GGe5Jf5t7i%5scs29BnoUe!47qtV5K2LIotY}J z_q5C3(Zp?3wLvmq!i;jlJxX)v-(wFAOHD|1ytE&}HvaK94hB%a98*t)(YjH#vfkV1 z#oO8S+9mx7Z<7{^sTzcrs)OJtZg2#sNH^(C8$o5-bW6xEW^QQ_W^E+iCULBeW4`;& z`|^a(UYm-WLn}2M(e4zjs#j0;v?zTAAkd$jGKDo%sr=h$lJ@f1NC_Ab&J!wiKgWhX za?35GzR2}{iBVeKNoWo0ghGiRYw^NU&qHqBF_B~olG3rzclWbDI2Z97U6*P!go0NsF!wu?ZQchw&=Re``1aadedm(MPx9{ECRWwM#y%iktYJ5NB z(PAFv7JeR^*`EP1jxCz)Db6m}jY&3Ewg(@uiyColi#l^fP_y9L)w_peHD26Vd{wR~ zhg>)!XD`qptCE$MF^U~Cy1G5S0$4E<7}6HTRGal+vi&m_Ta0w2?duEW#+^=M)xg;K zS$-=jSBQ&eh31Meh(Fu`td`2`S{BF{4@-RJm;uA5(-*!{keSZkI}8OC*o#{PlkuQM z#s)?}tHo@@sc=SxycPsk3vFVV64fBm_Z9#--#iA}$UnGTIL;C&UN%%2JoPGQ9U;vi zksXyakKeCSZ>XoMD&;+7>4^j&h9By$*bYH<6P4PYkaw{$5!&W8bC0Dx1cfC;{ldf1 zGgB5OaOVz**zN%*l(i#7UGxvz<3ig9;P65UDA^-dG-)t6kBlbcm7J5F35OS%z@5Zxu@QWla`OHRBgvPcf%D zkgdFLYO3&j2&rf|v$$4cQ@9p%vCUh?zBLVm0+3O;;fP?-v9Lqkz3pTAOBQsaz zM)YEC7%6BcevtG9%j>{nw-}>F8y-|AdqhJI=btsVNg0*@n14)6d4w%lr*NucF+NaLNU~bZjYFNN+t%p}x+0DhWuWO6}B`nC+Ji z-KU|ulJlzlBlQh&ud?2W6X6jcn8tFUDAAl{)>^L^Z?E+q$38WG@pjifq7jF{AL6Uo zCq~n?0G2KXfgx?li75l}OA6A4IZH*6qKjw3LP`4LJemzjtId{K9SG;iH_mg@Tjb+P z;H#~i8CFt+7pBN4y^NgCF~{*K^4cqm11$>2D4Er^`lqw?*c!S9!i2qj`^AxxIxg#R zO0qcz%f-cw|6aDh>>R+}M1Wr6!2cTPQKDlANXY;)X}F;tpGp1X^#6$Q{+szKDBijv z`@LhW*@&E%PJ6B_PS$SQs)UlTS@fczQKf7j1b)=CL-phBtIPWd2p#5rMRGr(QuGe_ zu6T(}gxPO?mL^Jyd`guM(hs9b9J&2zY4JDl<)wK8?KW|ss#_5f6qi>{+LJW*@!rD_ zx9V@|!H#(egJx$qe?#%_c@nYu6!xuY3*m-z{3ENELiRcUHkZOo5niiOCNJ>}D~ekB zl%lW<5i5}zRfQSUT7FWCq=#N0U|;uts6cT;M~Ze?&;M)w>;DUo*T}`a+evX&`ySyv zJS8KNmXG`G@ZNAY>EsR|ur^SL!7u#2X%q|`9=dnZPrLGkP3yVbW}Xm~nrMiq)eXZ> zQYXTd6vSUe*;esguRn{ut&0IwIRYS026;o~O#wGZ9qhT{Y6%y4j6(0J$iL;;@pHYv zkR*8%(rEdVN_iIzjh0KZ`j#wG0&&!IL9Qj2`ep8*7__UjNoiYz`t@!^B$YQDVx%Fx*0Q`Y7Fv z@2omMSrI_zAzg=xR9D8@74j;*17*>QzQj+;nE%Nc21;DTU`#g-0Pfl9oDPZ!2w zK=c`htxCj|0+v7`jxd*7j9%%pP;g>*$K)D?GcBMRCMBR{jc8^IRL#@1^~;|WzB9p2 ztSZH`Q!4A9pTjGIzx2cZnacN0g#=}z?`bfvLX_h9$yf1TaUGn6+yBFuKAm!vUgD7) z!@_7NY!2I-Ts-~#=+RSatQ9hpKDG|J=S-|=rr+JW_2ERW{iDr-8#m9r)eaSJynBdf zXB|j>BtDbs$=KubqGAa$6a?3BsCh?I-+YM>nd$z(iDy*vdGOnWXik{e`^$T4#|-dk z$i@Z5-;jnqE4VQVa>Dl=jfFtqPa76yHlxOKbXvM1>7MUxyDyHrZhPXt{83|a$zv3& zOiJ{v*IJUv+dp<|yZ7=^ao=PwZC_`M|4m7aR60+q7ODSWD=Q+I9LzHl+~{8D&1k!s zoi^)nyEAu($>cUl%83|T|LSeo%5vkQ1ehdOECJ;S9Uzi-4ixZ(<{k5}t+$9;ye187IA8Z1X;YhTSn9#9wipy}9#WBMyg8xzm3xThX#)jQySIxHx`h1kXcsXdq6Y6Bd*r^U8a28;V2 za+zplbqz99i7nnQvo+{uKhqQAGERwMVl=&Pz37-_8IS@p=ta-N;lGXeJ&hw9x{^vE&THc1 zW|O{xo=Be@w_0N7SqognGCiZ~tz-9$#m5UpIT+`OT0hmwT`AFUq8xhTMB-0z7YpUl zyMR*GQ=YGENVkzT2Ub14EM#MIA%+p>w>-;2q@|aw7Pov;>wB{In^p2dt8x8VK25&i zw?AJGYL#}sDSYx#y024uW>Sa(6gg;J}1 zy}rm{zw@(@H1D&8^N*j>i!A;g{}fhG?Q!LcQBQZZ*?m9A@Z6bQ@8FEvD7oERG#LL! zFPf{r{>I(+w4uRr^3mzvX2T5r+eAjM4}uq~)_w?Mzi0jUCjUPQMY<8*ZzAo}Zx-%7 z4uMUiBR;>vWg8LR&EXC6)gOQ=^DltC<7X;f{{fJPCAXWdU;VkqcEEM24Ug>ppr#l# zKvfMsoZ^3coCwd>lpKXY&`^vb}uo$8uaCuca;K0^t|}W`z=%7XSLU4mD2?( z@&gw)bb^fERzT3=_cG(zL^bF3gLg$B|e2(wa2a-QBIuX)TG5hgCb>5i{5$} z_}iT*!Dzm5S5;xQlD&r@E|mF_Ga`@7zbm5l)U)tD+90+8z#y=OlD>?xuh$1EXA&Hv zMoU2clZ+W6pbNG=+vs##d>r)l1To`KVAYIVit7_>z;|@fML)-uOL8*Jc@En;)=n?l zfWqVyOOz+cXDPUL^n#YKl(w9Rd`+f2y}ZP>TWAQjXyd#MU!ra3lC z!8rVLii*yUsCas3$_N=_whHka^W6Qn3w7ND8gE=)4P>vk<|euaXs1qWrjTyWB+Fl5 zbAEkx(6OW~&0zR5UDFF9Ua?5TtEJv>Q~da}xf$asH*8HD_#;xPpzwWHAG*w^;%bE{<2slJ^Q~=FGgZj*Y z7(7I{K*}cw;p99UG!H{Xb_{+1#!H3VMiQIGb80@}`Qt8N+qE-)eI8>g^vPta5L#>V@8Jl9X z=Zi+7Of%#rVwP)Je=U}CvLGTy#rBCCRAFgYp8*+JO0jS|glJU~jC;f9ZmaSXdttsukfzPe|nXt&EIkh8p19du+!o6yl6*RE(5I^+H2 z^^#e+i1Jd6Y3%kzOV5}!C^ET(5O{Eo&4y$24XyAjI2F#IZ;~RV`F=b(8?1^B0G5>y zyCu$y)E~!4#_7&40U4xUxHdEva4mCc}x<- zU;w&L7I}&AiQuXms97Nx_vwr00{U%rS!0M8F$;D>ZQNA3)V;fFFNy{ok2`nb2J~o@ zozuN%`$$65chNT~_1Sjzc@AlfA1Uv*4MIa2h;IGvUeW`;P9}&O^aL&w*8a5CyF7Zb zCW{Kf`~)R4NF%;(d(l?Q8$p51f~Ysq6SFpJW^FIJ8NMO4xWC#!+4w)?wy-Wm zP2{v^qdRTGsHS$6obl=Zt!dmZ`%7&5K^r`W72$=67FAJ)_w(S$&M8IYVAAiYu~Qs;wpwqH1DjNs z_o;A^^J-h2K-;iIgFQR+u3d05|3*oTJ2~j}3^|^mb%}!FzEO5{XHiOv2R3V9&ZusY z)L-kxsiO3tcIW}L$|M1R!c#uI7lD6RhvQi8po3855p;7O5M6J(EZRr(mH$GG^K9VK zD%?$S5;)%~>wzS__B+Nj8DlXxDH5In!WX7?M&N5C_scZnTkFv@jCU)K*%g5UAn!it zPCBH1^vm*-A+t9pkXgh@7l7TwepU3ePB;h|o}T(12#XK**Md!4?-hZM$m&CR{gVS= znoccxD#h<^Zif@-12e}7` zyl-9yF^5;X_8^DKE91mRXKm^aTZ-mArdATJJe@0^*S7xaD4<%Oy9DXDY&CM0le_brF%tDKA zw@&jF$bhs}8KP16PLkozS+uQvt=0W7=SVSFVS$UmKox^}+Xzu?rg3rGYVCU)Imhk+ z2`vNwJ&D<}(X-(sNZym!G9ZqZQDO870Xzt?CjaBTMdr?lsuyqW{QUcV>xbu!Wf|uy6y!Rjy3Pyebkl+!mxMHsoexc- zLFy7vC1d+^j3>IXqz>^S*ghVwVv2JYWASZ1#SHAjpvUZL=|^_;oV~RrZ?X}6z}sO% z(N^@h^c_$*_FYro+6LnMu)~HhZY@-(su7!oN3Qxeuf{3@%r?$hYJ3Wt3w;;fsnA6r zkqJQgR=dm>QIf7p%qn%*z9L5||4f8@8B`HCmPC{>xjS?YIW@l5K)(@^dDs60rjDs3 z{MeFQe5fd4kO5kbDXV4r@DwwwiVSfq6$502l31;tWlR$;^i`-%4rnk^>)>$EV)jxZ zU|hB+GWHR5grn8GlDF@R0L`M=;=~*lWW@odFsvPlM2puo-ifAeA3qiKH2j}nrZM(^czbeh%CWF#2c&ijiCxHFS=3u`yVt~-;+)rHk+7z zf0hrXEqVRV{4_Dr{)fyb1_dNr4!spBHBrg9+@3Ztcu6JBA%8=gQjI78zF-3$RQGhl zssJELpU3E-`OP+Go$Qv6i2Jd4)MgC&cS?)K5)nfxMU?C_n4&wOtTD)vFtQJmHOZ3f%ZzM=v1A*KEn`h$ z>>^}0wvjbNHK8m+|If7Czu$SCC+Ep|a?XPuH0C?s&wS^zT<_(&E`j?XwHqwUy>lR* zzW`f5K)#l2EF`pEjn%SxvLxJSFs@(Yd^f)PvO-lUk)-M8B7~GDye5J)w82u2VN-;! zbV+~q&!9%07BOhLri#=z049U5sG^E^3sf^qT0fwG5~16khXUgU;Bfx2lM^M!t3pAH zYKmaJwY&Hu$|CCxP#_;ht&4rrOla36fn=lTOEQiWOVC?|qO_G&{o#Pz>ZIedZfh*r zgVo7HqTt*Lok)(k2AiPvC~CwbD5t-UQNbk!$;^4$ z?3tb`O!g=XJ}zQf))~zld+{Mu(bG0FHT_FZg>+MI(9foSDcc#@oyNp@OD9u?-UXp!@&PLS#KcKiU2O z_-hYq(OoIN|3KVP~8vakQoNXwc20b>s{Dn0(+Fao_qz^ANGA9Iucj5d&&vjh^%%v90O z`)e@uh3w$}CJl}va=-5T`^6)BmmtBQmX6|`1RRdF%Ch0{SHIQ~N4oyt=K&(JL2yzu zEiFwffFGftu*m4^Q<|M)t%t*vw8lpjQ>f1kYq&;c z7sOoxoXyx((a*BMNC;J<&hN>Mw%*>&=J$8RT`c{`Q2z1HTU$nHV;|NmP!m0&<;s)D zvz0T({bRf+RoJMK;UMdK*Nncc^P_W>$}?PNhjGS4Cqsm>+V2GpY6b|Q4#libkbyG6xtqO}aAGlYuDsP+T~ol!vqeSRz6 zSRt&E%^h8~u9n)!{8M4mxo)v&2GAOL_6wy~b9Y=_JUnFiD}jJCJTb8%an2(#IfRVG zVioSB2F;L~lnh(j+JYvUo3F8>bai!0G+Q*9KzZB*kV<#}vCqUPoDD(O2fu@8Kx3$) z{tF>5(SUGv3n3w)%(5v=Z=g|) zInVM~S^Kku^dK&ZM3q1AAlBF&#P8G1N`{syN@v5ek1c!WYPeoHM(FB;YWX~TShi|b zumqu&lcV#>$>kxT#Lmf*cfI&>Uu_$yEk!wd)Mz(UN1k@eKw#JrmGx-h6)XUPqrJnk^7>~@U4`c@WYPO?R3{skWb#Wiv7 z4UF7yEvcKQ*3)|e%$992f^1B}5!{HbyN{VsrCQb; zlchHA9#0w+9^6>y&F;UN)6`QhYIRec6t6gq1XT35thyt2D7nm9io%U;BFfeWpo&-W z>zN5hQa3mV#FnEMNKFzU@^bNer=fg&hZ#sXgO4G69`?Ll=ldW|)Hx7>J}22A_}ymz zZX>h6>;go%d6WT5wr-f+RL4?tBs#A4t$C?&lz@j#-~%Y3`(AW_qg}1I`D=s3ZKpYS zE7pJ&lR#Z)YEHpVhR4W1$kj-lJT4NfJ+c9-2rQX&9+m$vw0+;xt#Ct=BsvdoN2b)h zH5S{%^6LoBKQw6&^o(u;Nmbo)Z=unk&7g5p>Z$u+!Vwi)!5ogG$+pN2F^sO41}QC@ zMTYBY+pVkcr6d4P^6dB2@H6Vd^j<6~gs<_&U=)1ftJR7biGNnvy=FyqFWNEXB*N zF3bQ+ZS2nwZ5)-AUw+~Ha_!jq%S9GY(QatHzd1M8d|fR)OV^>bC5zfzjP`ZPp&r-d zMZTl=URSMcmrv!JjP!|L&kEHpgww;R9iZD~7PMDXOU~&&XjQ?OlDD&yCUeAPwa$`n z2*^E%w6?D05Y%#rk|wCua%2pU%9*y68)dsO`fbty*goib?nJI`VoL{UeF6LZ1AmEw zO>Hl?+hwg$R3*p>FHbLkn@BXzpiH3Os=SK>(*~q+;ai~3U{-jYJLRT&5%ue--IAsl zVe$yXd)5Ii{!#AA{2>tEcZb*Wv*6t~0wO>1rO=t7?U-txY#i8#h}I@M8)oM} zi90a`hGy9xu(y2Ivgf%}xV=cN?9u51ijT8gX=YvxK@|3jjg~hXSOYxnVcAL9q;sVw zdp5Fhagw?2d2xH00=0xcoMG9!j67?rQhQuWmPaEee)`#7y`=pwR-STDNuKZqhP=ld_m;WvjX_iS--;sLeK{L@tD{|^s)vz0Wz^NOXX(05i^X6yGwl$v^>wK}zb>H2R^M$rMVSsj zJ%b%OaFyY|wm@zg9XpvTF6(*MU*j^^Ga)m~sq+QYyTzy6nafj9Vt#t_l?p!RzpFa? zb0T~>Gs=}s&z`q&leXBwBV;+e2lXVYo(&o>m9d#p%MYdzY|^9n5>3PkEks zTH4p)gLFQ*C+Q4C{&3WVI9rVk{wM*7Ky2Fl)k8fcD&YqYpF-VwYEKIjoX#PgJ9xOJ zl;teHx&Q~~?zuB3eF^kKP!x7We>W$-HQt8u0d9zbc}NniJ8-W#M80$FizXWsHZl{w zKKVWjGSi=7H|x=MO#=R2cUeqkmaH$05+$lEJ0lbg+Wp@X^v&*A;nE@ zfLSO1RPlt8FJ)r4qNY^2@rC(%s1dSS5av#VZwXq9k_Z~(VG2fDB?KIade^s~(gH>Y zyCv)8>ffY;(jJuR#%vI!hfk6t%w50|&=#;J@W1TZAyLEGY79QB=e5w)3TJT!5uiqX zi4*7n{qj0^5=H8m@&l=+<``E2cSfpxphMYOtEyAdv~B_1Lu~lCJ1EAkMtSbg&dWFP zmj5i6Ea5BRhWN=B*(L40c#7UFtHZ+v4LYOBV0%T50*dK0p1<}6>odkyE*ZOtFX^4F zG6E$#PIc5zt7Zm1aA3*Gn;mUY;viLqlW%8`$f?HGAjpi6YZFvLWhm^TYWOp-mMKjH z$JC7{#_mgD=F2i+#Elt#1tseM!7VP<1}+FR0YFwEi?^i=H4z`l4!g5 z{T3TORq-%BRXz&sMsM-#q=~vtBYwT!&v<8-CFih|NH?YU1WdsbZ2qoC&HfA|uQ}oi ze+@;ja@3dv<>mDpHosp6J#GwbJ>R90K;vl3Uk@|qcN$bQs%Rp^hUB~X5x8UEdKAxg zC#lF$#C5tRUm0B>-9_UCZ&gPdj>tCtx=HlNtfccb0e8CG>29ASBdlDWcuJS-?{UJi z1l&hY7h9LDxPd6$5JocBF)L@m%XiyKVf|ocaGTu$=)p&&sQ-{xXTaXlKuP&mT>*r( z@3S>;=ao4MGJhkg^3#F6y;4;Ve_*Y^j^j9(pICI9&~o>`OOFRuGLW6~gfI7-zZk5Q zQ@$*)WM_@}>LybWpI~5G?;j9*C8hqw&x6qu!zFk4$R$fWzS{19c|T{*HWUfVE$*FxcFjXTC7{^+qWGA|lMFoiYtuZ3#ZKCQORc2>zsXQ@3TNdMSu zTA^!LalSNph0Yw)-hQJlB(DF*SfYcDz|5sY>*0K~B50-K8p(Ro=*3!db1)PNWeF3% z{i=u77w+ooJN`h>ihX87HHtfgg~Mid18lK#2%6{p`??nO=gQ6+O>-gW98UQ-S$40} z{-_qa4jm96b~mVUFSDzgOc`4NEED0EZyBbHYKa+;vT379&Z(Nb@g_xz(y%xjbHLY= zYQ6-DrFv@fyZ4eUd9AEaUwtjiKPnr0)fbU;v=6?W@S-ZU&fW*nr0)-~LVHqXdkfg` zyL%~eS21zA1<`qN(A?VY^)z3;m^^9QggMm670PSR?6EfwRNhXa@~nhr96;j;I>$pj zjI^yiT~FONl586TFtJ)%?v9*i>U*Cc)k^_0Klp1~(06YSEMe;czij4Lp)7(6)G+s^ zR5KoHcYA9*tT$LIYR9Zuff@;J0DQT=DOYyB`1(eLGR;aIoG`5<(6qH3UUFk|#+b+e zqCztX8}HgN18n5->XJjpE^g}Imat!i<|WV!P|l&$&`{iKGfZuNky({6`edO=+3OrH zWI$Y{J-pU%B?^$^QRQaYYoR(0KLIq=_DJbKrdHjlo%^oZi=}X!e{j*T*`;_**g4aR z?<2fdyQA31UkC%B{Y*u*AOS?8iiFWD4xj8Do8nB+82imN_-(dcN`y;uapJnL=QWl- zZlYqJkuO=Jhy5!dj>x#Zt4q9fWA^_8_5%CgKUi7sMKOSua32 z6vK8*7JhsaPpK%SS{~+X6?KT(d|t&mNy*bs!$-2QvDH|&;Tlfe-gl?;?hQBnD?zCH zz;U~W&62Xdwidja;P;QLmk0m83g69dAK=H%qZEDC7Rt>rn3pq&eD#3e2+wGI9`-&# zS&`3^pO^O#=R-w4FJk+?(^)tb6_tKahBqkhF!1D>)5<^@-@%Xv#;7ohNJ(wdsUabC zoR)~vXpAw^OR`0frf*q>YKc69T(mFAtiJ}reefus*@E`k&7z8f0De;DmbAA{r(_2t zQy*Vzd}iunR*5z#l>nGj^1`lxCPosp*h>UF$gC>hGyu|s6ZxsJfZ8L^38i>qm{X_&To676~g4Qvn4lW{7q5`i3UL7TY_!p$*LRvDt6IG zzY>jQd&{0k9GRLg*LnPIayS< zEtKBxsM0!`qc*W65~d2zLN4VkMxoUGn*=vO?pJQoWH8oN>DWh6lbSqA&n^ngt65PT zc3n-N7rIG`cF+R`aDfQ8VdQ2}vQKuMbbzMR93|f;Ua{j9rNhU%@L#5K2LKZQ!dVl2 zCH?f{67~ToPSX!CLxQmb=avPInw0%D>$+g;eZZ`o_5|zLefqpDpicTgF`;UJQMKkq za~SJ(4e~7*1aDx~;22)Q9`LDOPi>0d!j!~rj`{ZDolibLV{!M?zxvO?Sz6Ct*VDkR zB=G2T&|`wTrhYx{#=b*^%UQ?Tdby7rc54U#a_5JPSWP)lXlIK;3r;>53R(2c|2I+ zkU&j(L!cy4udWWz0U#^gQ{-@OOVI3JAl2?B6@YojH^H@P1}0Bf#2}2F;1-ZNX`JA| zQ;dC!u~!v-S-n{lNqyT=dh#u(5MC0y|6h|oA--pL8*=HKb1X`w&T3qpNxCi*Z!j4K znSrLv@D~+UP4BP#JFg;mO!#VVe6|a0eQ#RZyIXGY=3e3^SHO7yIe|fUOZ-9714qYQ zwe1;Q4}ieUxc zV^`#B!Up>Aos%7{RccG(ANS&C?>WZx^8lpi1(R6NNI#ku7bWK;O0rJ1*6P1wd43*l z72g2|IMe9|7j)F(8-73!!4?G&2WVgf76XT%=NYPjC}8`*{`7m+$den?zM1htmveA# z=3w2Z392#KpHs)60PNr5y4~wjOikjMVguCZarKBqSmw{U1??eN^(NR5z`TJ7ZbXgP zuL)NRX8fKurm?@L&DK>Nf6fU&YrzI2(#IUXL6y#s=YHK3FX4j>2A0OSa z33Ubxn+GccJ#Dk}8x297CEP<(H=znlHNYv$y5ay%nbAOnY{^`RL%ab;%{bj?IVy#& zc4319MlT+OwnYjsRK@#Hquf)r>rUKIzAxG_=`GB3Ld%m4K z(8Oi7Wi+T1{nMxmvtF9)RNE_@;wsj?(}&|jjNWNYvHb|AJGcj2vh5*Ia@}5CVzS!) zF7DEX6YqyrYvp3>Tl-hFK?qU#w%6SESL6nw1jmG|3Z}wCrI4uq&ZTml`v)-}T@rsQALsh{{bJL4Ni3~A*~c2t z0=F=1Y=H{peb`GKt8cjdU^9S}U0`G+!osG(#%r3sK(?u3FDc>M zzw6;=$c_Bn^M6FbB_RMm*J(0Nf0af69qkWNm>-A630VIDi61VV25$9D; z81m#R+69mQE_&_^uDLoUo4Eh4Ao*N@achOtuBhL*c0e6mv@~Nk^cR}~xY+~L#eI;o zh}J(}xc|mcZtX6Q=lMOF z7ctL8np$1O!stbp?@wI8K9# zv@c$*wx)ONc5YUzU>8l!+0j)Di*4adGtm~&T}Sw3{H0(r_q2YVzP%AP!XIVBWc9Jz z+2!87nomnhsfGdl$JUgu3)q$Ula&2kD&Kpp9>}(>P_H4i&!K#RuB@DPesAGk9a%Jz z*5y@K#>*?^wb(T1VxL2hAUzOegq5#o8UfL5Q;4i8Q{nuo<@JY0r<7@kVR)<8!Ml>MeVV$ zMNL9ga>^9kL&z_3GWScKTfq4RY~}E*{}MQNC=N@;ofvS)X#r@HF^R6{C7+8+Yc-RiZyJVYVY(SXYJP~F4+_9{TRV!H+6 zNZcr04PCDAI`;eU62z<>lPaW+0bfZ0)OlF50wSKl7PE72G(!;_kaCF{r+b0Ixc67Z z@4xc=H1w(=4Kbb~=a*VqUS3AE56~8LxmByD+;u6M*(HJM=B`}V4yVY;kZ%YMMen#~ zbl60CxqahmYxQ|&({$l@qqS$oI7a+&phDqCAH_O>Ny&gXHcm`0L;%K+zKKPP= zZZ58jSXGS@+8P4RD(UYZK{oJBT@4&H7*Yq+1s~1;eIUYxW9tBywyx&8Hg&t!_00eW z_J)9&Hl`#Z*=RAUk9+lBj6fYpH#ayuNo}VFffH0_C70N*tgJu;PSTqc>h>J2nVOn9 zd0p{{S4z~|aCXEsRbS0#7Y)yv@ja90P{xk+_s?)k+)3phCuURh1Qhv{D$r_bYFF(z zYXGdZ$%g3xRnK_mF8yA zQ|epz5r3Q9W8d%qz-?;^5_D#vZX^N@+XMB>ptt^Dki|3(k(UOiK5F_4>Gn#zurs*` zRFTQL9hX%?R8x(j0=GqT$~%KG5SRkW+3ZP8b$Ig|A^4AeTy)Gp)Rt6h1F?{+tsfLH zG~%6<_2jC(A@EGxjNlk0Pp-(PS_;JE4M?eDO8))Ws20CX6Y&d5wedk@dwV~T>A`_G z214k}BLTUaA{Fx<&#YnbK;a~!p#g_WVI9jNQcmsHIo*2S>3V^Hepr|;(+ z_S%?vDDw?UiVLH)y;s;QI#Da2=<#-96N{OrDZ%Y8ux_!VMt`(oax_^+%ZlE?OP5nd< zK;v29M+N0gNXqvwwcw03W(wq@N5C4D|_^DR*w~Xz|!Ne zgBcw{mdqT>vOJgAEW`( z!nv$}h?7IFEi*Gyvb|O3sD?=@9gAazE=3CN)57N*O*(RQBlloG7Zi2bZT9;0BucM; zb4qD^I}1(!#Z2U}^Kqb%C=9T0punw04G35^G9m6jRa|xhgI#L{HCh$B6HI-q|9!F) zMW~WF5~Vx{91n|TjOhr96UT2e$OEhze0EBnYzX?`#2O=6_HI3tBI_yNAwD+01PtDe z|A;{kLg7bVfpT2IZ?vgx77XV>`>PkcGSl?X?&EnWxj&#8+O{jY)Zv0ORZ~fc##dp+RsYAjy4wBvNgh#CZ9I(CR(VCKAXl4XhJy_p=eL#mI)g ztJ}J-sny=S1h{=4g!k9yV`U#tR1wJUSNO)KzFfPGISKZ^g`X*|q!;jHa$-e*(0c2o zAmexR%&9EkR3VOAfXePj9UA7n^DWj%~>BvT6eaXA6%u_0~?AkSm&Ak z3$nii$ETp2>|45X-9k~*ttA5!)B)M&clXTPXJ+bB-N$jdUg5wYZd%^Ogbz#bIVca(Z&LrqL%|AY|4}77cYx#AJ1U% z5S>W#d|b1-$T65H!9xp(-J&JET4xx!30w|Q23d2)%P*`8K4BGGf$FJM5%Oo39O#4k z2@UdSV`LOs$rWYPGZKVRa?<46h}l;O0bw&pHblVkd zHf*>}o&i8LDn9%E9z0L0E%$;?;^_?PfY2y>3uCWN0i>hE zma>-u*mbvzbo{Md#8xCeg&6pA)*kBTueH+Lv5W@*H(b}M-a6LhI>>#C%FIJXrOGzR_V4fAV65513McryGe*vG)#@UM)UYm@Y1pc2T%^J-Nv8aj@z=6;U)iN^# z=`JgCTi3vE^MFID$)Er}`dBdw0d_&|mpl$CXa#i>4xmOF7Qnkjci%FtiE8`D*BuAc zE0({T|Lpx;?vMW8f?;GiGw>k!FTU;t+=!4DIJ1}RPM*A?$hyBlsCD2&3+YM|w>^K1 zd47{+81@Z2R}?!oEnF~wi*^g*v*r?Ly zr02XH*t#XOayIIclEyMWjc1;(o;Zp1If zzG>|lfY$wBcJ))XG0s7kmKgVu(_S(JqPnDx&(Sc1 zQQ9>N;HXnZ)4}4(*%h{+yc8|ZMx&5Y9>u5&Cfc`4RN5aSPj(owRNrnvGlIBg+!uZc zQfR$q-Mu%>DFAEZ-}}VZ87GP^*yyD8LE4M}V^+RjLZg_9J8^m5<@KhMOD%cT5=8b4 zjCmv&*u@CCnGOyQ{X<1pUMvD@9GoWV2R84spPN9c>r2}u?IuFfq~(p&*?a@3+BE#l z!YY13mRud&3}YYYHQc#Pd>{pmNr>5E)2be3AO@C$1H-)3Lh9RXRBKA8d{TGLOF`@G z(Cu1|^Oan5THh=j?akp-Obr(GFGrv07DFH3w$dD{_(sVU^lNSV|w#Q;^o;I)H?wq5>H zEB68PYI*gy5*g@q5+Jmd9u4m7|1RnI%s`zJWyA7So?6 z!pe9?0;cUK*+0+7a^Gm$Bd{9--0I@y)~Btd6})xPxTN0G(^H`?FOuTQiud_)2( zz<_f{!Y(Q2&_h<^@l z>e^Wg%NxMTMsWaUQmgC=r!z?3ZUQwDZEJ>+MRo$8DDssQ-Urm7*O;u>Dp_>SzwAg# z{<4X!GggHgt^g#Xkm{AZGA;oXUSl%wig-A7?*J85{IH&aPAC)>U&a?AZ#P&!%JQt&Z6mfShJm@?+nHJ(x7x= z9pxYl@Y0`~Bfr=#7Ri4Zo`;j(4Qdtr}e}P8-xK z6Vb`lx!$xjGY$-_FHW6aUR*pBWV|Alu{qq^s|S~sKFX{l_DJA6@v-vq^&`zyciWE| zmIC>;`2>Ov)L4-N_xWxthePmGDs}em-T-TB(Bh)casYw|zHKD`^f+i^d19G;3Uo&; z8~LEVWIP{3Za7L{M7aaaVa73=?FuZQOnxXsJPTp*l|SGKYN0yBiF$!VTmUg8maf-; zpT#&A*QnMHzXoT36R&1Xh9ao1-fiW>vcXW$`azg6#v9s_F=~P-uND5mvkIbl`qPdn zU^sjb%isOOAhu3o6Dv=&&VQmi1FV5dCQqAySX=eQs>)`y<@0pZ@ct7U{UyNIxum8e zzN#(|39|2u+vjZd2T0p~b$9vv44CP9xqlPSlG=;HLr|r=zM3P)fQV$34`T8SC&O9} zv)^KFZ|EA^2C$UX{WA&FT<>Bj#!u41Uz>?Ub#-An$AEnO`#}EV+ja~^PrVL)o_q)@@35{`Yp-%gUtQZD#L7E8nJS+@-S>T0v|_R1 zwKDp7YkT-Z9Rt`O&y$^*zWqtt&D&AjkYCrv9M3mt{}XV_L@QvuQeM!u4s*G?lHSi_ zT|1>qNr)WyNdmf;V<`En~MAY;f>iGwqK^hhm7)oc|P z68Fp1uZ{8lc4cMFR@dF>4T1?sY-o`O>}W zAW%20bp`z|yc&fExq+Ed3W{pMibmvtR9=^$DcmEBrhu~>kLXO5q`_KO{x!;^_d7- zK3_FC2%@lNpV_yu^<0SGGVWQO>D+qTmdIl_2$Vxm22>PK%r#E|rE_~ivw$u9x3CsO z^-iYVY)b}e*}JFWn&1CSLPyX}mH1ED|AJiFVqtI%An2mB#h)&G0fN#df#T9KNs4L% zcF{|BV0GHgCztR4MP1hI+Z$R8lQA!koV8l&WDoC*LD`y`uYTJ&tvr%yj|5v_q(dQm z*|O0)AACkX@X@7Ue~WDSplFD`t zAw!_ucIp9q4CecJ*J(H)qBMtC8UYYtBtky?K0Y(F_M_T72r;f0AaXVT{{p!fWB_#a z2nsAP#Ig0KzmzwlCa{*QqyL{EuF&s12x7Ldt}Cc|xfD))8^bVp3MnmJe?tVu&Mwd{ zIdRi0QnU^9aT?HTZ2@|ZHH7cEHp9FRR4UzuL=sqGouEn%fRoXnpDMoRr`wva6I52* z@A#z6+0Rh}pt5jx1UU)Iuovh21T+>*GSMj>fKpl?{4FP-Qzn1yK#+BnJixt$0ZI(i z=b6W>s)EL$`=0mS)YaL`* zF!n~Srs-jzqC3BA-vJI5i!!l*#ybhv%O)h`~ zo>P0Im)q4JY>5r0)5%hGU^4m#GEckeWy2{wF;fE_KJlvDG<~-5g(SUyG<4JY`XI(%^EDPAF=i$qDUGVXf`M>Ko zb2?x@l$D1TMPY;0ycsUQWm4{64E1G3>8K#iKmI%@O*@$IAJL?@or?C zE)xCX8D;K|i@;{r=okD7g3t(u0UI);RjX$)YQAM)Qpj%>!|>x60@NjcHtZw#smfIZ z90Gc^BSm5Njsam6+%HFGFB)la@dUcRmH2u<7r8kjhN|(E8tUDMISsT~rEY+TkHF zU23y_#k7vGb#(=tf-L8+&j z!hi{tUN4*&9Etu#y+a%{@*zJu0kSIjga|477C!+4zvHr2@#e;Z2ab{6p{6p&S z?)WmQ6b-aPRE1_|xe4I4xOTzpx3Fv*KLrwX+#zo9v#QSNr$62-_nDz25od`B%FB@o zsZv6Tlb~CfQm>C8p;^RpHr3{=ZHFr=k7(Tq>~k}`2jP?S^?M&1K6J0RU?;C%PXxxJ-J58A!aBhn5UvK0ucb03r#E^jgbS>y-N%-&9VeGpp0}+6*ibT=l-09V5hH zz9yqI(17IhKV#HwVl=IEgl#z`w~8M|s46u|9ldf5p`fLZy=IjxBU>ghzod;i>(X0A z(2bSJFO7Y0+&{lluB0C*?r&TAxb@YS%#0$d1p_GEw*CcSqJUi)D2-S((D9ENDNmsq z0Alh|S_)5yMh+j0e}QaJ(Nvee;#(yHV}D_uUwPTCz!5RI60PlAG}x4T!mQtHW-MDE z`KlGHjp13VcE``OFgK#N;*GFlj|2L(N)#?uzKbY3F_y11*2}7+aC@u*M}V99k=YGvMQr!gK%FE9dO{MS={Nf~1xpr6UX znSw$b=;t?Un$gjVylO){?@MlCPNqtcGX4W#fty-aVC=xixE&KrIRU_*c1NXO|92zzeM@W0knrnWdUUXdp=K6P`DYGn2wu>1eb zoj`Wpcy-sxXvGA8hM+_>chYarnM&TLrrtLGc>?|#Oca-o-7Cc}F>{+NO^*Kq-5HPe zIrWPCgKs(b)YKzZ7XZMdEiEiu4-FA`iOkapnL!{BhF<(J%5}(+CcAutikUZ{V9epV zuS8LjfL6I@VTWw7&~DCUeG*D!rGW&d5JE~yYJz*cr1ws6euvr;5Hv@##PF}g-I7~h zw_EX*wSzPWk(34{!)e7zJk_>_;lwLC(T~Szy9kCB0P?l%<9FHhXJVV$Fm|tH$~5?= zc=?V2FAqL#(k&?+!$4owC)b3)x55@i?W_?Yy9o{VJIZ(bI?XB0W)1UY&2w3NmO_ zp!&MnQniDGYtTp+`K)}Gj%CHx)>fTdzR2$B7@Vv$L&A z=B7c}n<(@9_wTRpssHquZjP{oD=D2|uAx%zgn^7dE$?u5@4K?8MPu7$%RA!6H|uyM zAGq~lHx8ZKJ;#uNYc+i)9^>3NbVeo48F>)EPNmDq zsg6HeZV*JQmUeoda*YPG$DM75HBTm0@$#Nv^^#m!G+AEZ37veu-Xd|!7x5g=ao_D* zj&fap@9sntmk%_fZ>)JEco@IB`-XZ6slCm%4LhQ^9ta?rK$zbS&|Hu%gM=MGYA4>* z#LQxKCe`V(0rL&L7(&%SwW&5!AC_umbn#P3=Rmr!wf55EA0wO2R&R+8H6Q_117rSg zRNhscGkN-iZ)Un1cj^O%UP`mdd>)WV?+cA?vY8Qu9^C$ZdASl@M{%ZM+Rht-G_DyyDDdh= zBzo0ngo?V0PPgc^BC!Hem9MEEu*EjFb8re;$v^aT9ext)Ui3q6lbk$(RjMgp3=ixw z{HmBf?q&_v>&KSue~trT<}i#>c9R=s15A})g|s3Jm-YQ3ts}}JsU`mwq^f|xFBi9F z~`mWv&)Npo^({=wD#HW52OciCd_s+09hsVs-=(V2%zK)T^_ZX^+2Hbqg z=Q?m=TVq~kkT*X;bJ2%=vLW2tig5`2kmC+*3cdI*NERMfzsGgP#r-~OFdUWc85&Qu zcsnJY4>t*N$40VntsN?&s?j~6TWtds&|2y%oEp{gcIP0pTA58=u2PQsm z6(92~E`HK}yIxoYGYfqcy@^=uNr#bRw{>3nyr7f z>N)&N%oj?#Z+>TnWMYLl`D5oK3Wgkh=w$Kb7UpD6@7;ei_CI=Rn#zQ|QevIeox_9R zQ!r##@8K_Ue}(LvG5aH?txS zKQ>(u$!b^J%8`>+T;9>NJYOJ`xS6i?ll0`)S1E!a25t%HwQ!0VLFDT4J!8 zw?s$F8>V!qeQyHfsPH0jFDEKQ&-jrK7MS33j(7=K`%BWixVBmgm%7TV8m|e6N=nu4 z=Q@@7z6URuDvQ>_AnA^NAs{rIRsE)8;t)b_mCybZW%m&dGD3s3i>b_@_4FqraW>8x zz)vs-&sKptUcx+@k~X(5fkVW@-@32qykSW^%bi(SdhE}4ZW{y4js8`xO^?jJOb#l@ zDP(+m*3km=J!z7Vgmh?LQe0I;JkPofz4fBp#pxKuX-)+0B}h(FTDFYu*wH!zD3yz? zIuCn&?CtGGS<_H>)L|%HPnS6JZSI|+S0i&;c|I^%yFYEkyIku^ZFXryfc(vnjmG_#1tpZ@ z^S(Yyak_V56~47!+1)oLK;{I`T=gr@;zreqL*#CL8qfSI%Fqq77sH?Zv->UVo`0E% zp#eHFr1D9%FuzqceoV)Fn0+D~-r39CqRlWliEM&O<)5-26T za<_cqFP-(vzcBQA4Yv4FH#L3i!dJAZDdzU7!bBcehfwbAEH#YV<>*SFe?L(10Lc%E ziB2IK@rq9uq2@gw&rW`QsKcOOVcvy^V=~|^z~#o+0mVH z?YWEe_a?o0E8_RIn9infyeG605Xh%jmAe0hIu0doJW*f*oHE7AVrZ9=={&EBYNKPl zk^2!KueGPD%1X(6KE}NNE4%z+ zU(dlut%F)V4ri7h?K#I65xJ+N5L632z*bXp!n<#!_NT-Bg$4U>k1JByjFo0@CSA$# z4Pn}$Er0GRnJEs5I~2YV#1_wSJM_o(ZI(}>dX`ZFUk-mzJ2!se=9twdOs1lFn~p{M zK#MP3PmDxt!fk1%hj#d@yyASmKe^A_bz8!IZ-3ACypeq%W&g3-r(WWsGvAbna_Tc5 zZ3dfbaMmFqjIn zuzLUxZn9G!BeUP+Zl*hML`~NLEB!{jK|z(NpB@mA#;U$6f2muq2Q4<$37^%1hpP|!(2TFPr~D{0S_`!s zO7;!zs(zEYd4KfzsZYo+S{2=wYM;ifJ9NK(c?UM&<0yW4+v&a)A6;~$hdcA~rEGr0 z(pmJ??T6MYrl!lKBiDTJsC;tqDfH6o6Ipk~oPPMMJ$>iVYT6M5nc;kLG&jBOoR+(X z43Ce~K0IL&JDxPgvqQUm-Z7u5^YPxST#N1ZRWo~a+I?Id<vkf)}aQUUP_Or8UE3Zd3EyR8a$Yo90oXs1IE(=*y~ooyXMQEMXeNE-9w zfmq`XjW^wAEF{%!{LSWLR!L7Ihoh!-k?K}W$M@jf&A)v4+K{HPzwySw(AHe`JtEq2 z7u)ti_Am;fXd3Q8(5>FxpSC_4nI=4xY27wK-A=z}@p|UpALF{A@@dEZ0y%fJ4@<)s zcR~L#8<$~%oE17A%(+;awoH15{Dm1&PM$kNka5o&hKxV)fVpv~2s$y}1tqj$mi2k& z!^0xD{Y8NlDNU<9N#?7JwGvv^s}aQDNW^fxAm>&3K|H&6I}ff+XX%_fmv&)!Erml! zNzQA-`pz{0tB$+Uaw10wpdif6>`zHpMk;qDqXfz8KoJSws@K#rMoVKLs|wi;_*<(W zBVc8+lVRjd@1A^pV;wRbue2XYa#F3;Yx9;75g}(nM}vKC2oNzQ4Hn00UAyIfIITjx z`na=zUmgMx@T{WxTSut+!CnB>jzkuAWcLV!B{8l)N7P@O!S1 z=(F$l|2`gPUCWWUmd~C+OrP)j&xuv#*y$NRJob?eUH7N0B7=f*-axw(L%Q z*oJlYBSDzBth-qo z#Pc`qABQAk>odHTMRa({?#q$x%thp^33MsPDUfiSoZalDfX*Ks1ocI@rrLiPG-SMy zujEBXdKTt`3P6o{Cg_xgfiyJ2H1VO^x%j2-5B530 zch&s3wBSOinY_H(H{}jGw*MB1frc!yFA{ptpkOIAGv8cj9@AVja_NJ-27iIq?!`~% z>X7AL{AMkJUZyZWDC>+~oNM058Cwl%o3O*w4GY_@^x1RgF~GFt3C?gh`)FoLX<&Vg z!UNhKwe$bc7ufn2M;uS3AA5i6vv0jQ`Qs_GymZyp-G<-N z@VrozBGyxaI-pe1Z6uK4}o-){WEKdkOGxYHK+|7l`*f`1Dy zb*#>DAgKA;UmL1YDHcb1%uTTDZyi8}^*zYT#Xw6s(xdpv-v&B2%T-FyQIz|yOV;S` zI*ddAy*suSMT-q09Oee?S1)IoqV3fGk;R%eD3m}t9)U?YPy%|+4%pd^3-@= zW8H?1))+?}?S)QG;Gc^q{@sb6ZYt{e+gEpB6>!EBlMenZMl2rseRDhx|8F<9qc))# z@8ny}44|%_Cso*(tEfSrwEgFz9dy4SApE7}fW=sTPEL-)FO$DFc>#4OEFz+O0s{vK z`*!tSB`*itVhdLP`{qjhbRWO^`=Gg4cgpq76~zmvk^x2XIG{|{Y5*wZj+yUp=UF~*yzK!vpvWtb$p$3589~OFvSHOO7^MOJT z^gkYGf91zPJO{#)G*9c}Z)Lv>cCfLL!F`Z={toJ$e#BZeV(`-ZNLj?gweLS#i*lYc z11^p%9kIKM%cT*(mcSuuR=%`86A0X>7f|wDm-wMH&}OiKL&~wdhrK4_3}yG+m&Q-6 zebUl1Z+A#%o-YLbSE3A7buQXJBP;B)%hwwyX$D40N2v@^#8120sk2e zw%NkUESs(on7g>(*tCMpYO~R8pdAzejR?0MYj&E%#KMdsfK(`{cQwS3dlHX+r9#Eyl{BqWimgo@LXzm^;LZczJ z&8BaZ0M(VGNA@idji(W(7yvZM60*O1=Tic|3{v)zPH$oAnx$6i1fYYGw143X5W_b&YxMvw`DQSU+u;bzK7}}{(U*A{QDy}DCU#|yC#f%@eDC~vC_phk zKdTXw2C)zMc^KrvL5~L{3mK$gf zvr%hO>n+(WNs~Gg-11`_*Irzv{-qtcYD-LNTKK8@xV^NuGG#FjgtOXTTdO_0<^(v% zT}W;__*Bj`^RP!)rs;;2S|fPY>6e$v|M)=_z*c1Vx$ADYbOwZka1x`r?eAO@uD8>> zHZ$@p|7z}l5HNaPPJ@-H8Ls|;lks)gxpyHm4f27?M?JDtj;-|c^z3NA>d3qweRpJv zZ|$a-W%Q4FnCcQwPzTU!r12W$O~$7j1|qU0yRj0We14>PxA|XIj+SwP#q-cZrd2ia z<}J>l0Vx?^Lb9Qy(I^iTTxK5ulwfH@lt)J|i19Y6vbKBaK?1I@9!vrB)qpt8k7bUM z1MzC{xrb*NL~Yjizj5sT-837V<_&OPq1ev!y%s}Q=kM$ismUJb@omX5%`*;C)W0k$ zz$BuP=fHxy3AY^+2$d;REJQH6G zM}PC|*?&Xy7rfQLo_qYX79cqH30X>Rd+LD&QFVa2Yjl4K@Cm)uo~u6<`DZlJS<=-E zmM(fo@wYBoW>0Um7@#qo=I$A%Nw1}(L9C>PZ^D3AN58Nhs_YXA;b&1j2-kZYBzhuT z(*Y%`=3}EjJ8R1CECcC|2IZyg`vc_y^;Nx=Dh0>tQT zQpXiT2lGV0q^q6gtiN!%17NV;prtR+FQLk= zviX*$m8gaaG3vxcoBzC==P8<%{xxON?5eXOvtOSBEPLm8=ZIErkFZ7-SoY53@OT!@ zzsHr9XQFrq(6chU(iOKp1pvp}-Y1oeb+0eH9Rk9nPYQRlB(0&i_IG!BEdFI=rFi7~ zL#0gzbbqso0NbIhuUv*apqT)k8>28ootXx(`*nH17vYU;HQ>fmC^7U1!m=NzlPqlq z9LcBJl%G5X8m_h|fE|(7!jb_1{T9 zSk)s~K5N@iEM7ISHPH;(J*wRvC+C3>I`3MAr0bke(ZHK)_>GH!lSOoOua1EKqc6Mc zuj$NwGTH7z@+CfNWHgYpnV$g^&bplr*Ya+%Dt zUqS%&;q-@2Lqgb7r`WGzLJ7*rZCW3_Uu|_Ijn$o&wGoZ5?ksw9tI8g~8E0)$646;| zcfhbKbr2wG) z$L3#1m(DJVjy?aGjgRyxN_7Pqj#SM25M}cvW@W{s6&e>i0_IdSfva8Lqp0&;nLF8L zTlUgsR=l@AvgC1D@t zS+5qvjATLhUk$M!cmPh*s}8Zd;0wBR(JszMH*rjHx17(+`xA8!U3rSuzp-?Pv@E~w z4netMMXmn(TmYo6=VsO#V=r-p*O5C#HpwUMhLp_n{}}sx(Pv9bvvwq{gX%fzzM$T2 zeSf&j6QE)?^&7pWOlqEC3a7^IckurM;cL8aSPYXG#{}@zKatab%Swm&lK8J z!gxjXKdBR7FPb+A4MB7xhH)W19WF$WN7-4qU&0#Nq-ijAPQ!IVz0(a|{TGu5vM@O} zL|^+wssH=^XBT^5MDzzFxy`sDG?rAcXs$7Xq~egjc*GKX;%{_$e-~}%sN#BI}1pQfVh}5D8^&b zkTKj{JyfWIu#Os~*P_Z&2h*)L|5)8>Mzh$r(VE>qKx3MB*~~}B){M-`2J&|KvY$+Y zjY?XeZuQWKTD?2TZaVb(@8*8qE$YV?YJJfVWa1nK2v z^EqvLeRVRk^(bj>n{)gdiWB;*_p99SqV;IGZHY-`3-sVPvw2U58vMen;#r<=B&r!I zRn6}2vpP~NZEw%NVr{@|2&bypKgPD@J^C?%;&>69pyu5MeP!36PMydLdzY^6xLKEfmv9ez(P?AjBIzS~cE9f|MHd36u>js>g#KTPK}7C-qIh)c|{8#_|GdkXC{?}E0!g(mU!e6U-yt)~-Vb>djR7YG@ zN+zdl*{xwfk=AWXA-$3-nXlnE`Sx3N2VazDU_qVtFO%tgEYflF+>n#a*L5+=SBa0)HJs}`dQmz{`q=slmk&akcs zCx50gDwUDXnd}B5@tMbl2+OSOL}T2m8FAZ3^$K>uy>kw+)Q~faDsvFFWUux44O$4n zOWgj{g`<^QS4<`_I3;0e@B8JwMTfw%0l4var$}|GAqmdFjny?Zuc$$0CRGai#^gLF zkgl(J!qbv*hVr6Lz69So1s|s-cH_Ck-QVi@p6{$m#Y2;(nM=Pp?*1Mun>8sA7jpYc zKh`_ceNdJ5dHctCx+S7ypunM7hJMgTu7SC95KUspjMp1f3Qr!Fc`_C5noG(rbBji4 zZvTsRxlv$JT&R${7ZjvJPr#aQ*fq+GA7yHn!;sB(8IAX_C!M;r z3@`?$^{x$)f#1|&k`Z&WCf6H`#LKJ`94W~#c7jVBVRQ;Nhi*{cTy0-h!3r))`l@0C z%i2rx-Ql~<*q39YcWo4<9-$a>J?}B3UYiN@I;wB;o^EcA>;S0*DdtlStU?{m3i0kY*Aq^Y$n?*9cqi~-TxzVpFp@i`h zHH~BpFtUfMXllfYQ#g)K)<6VB3A?@prT&yE++$5&qSH0x7toeHwI zurSC)EzDL9!%tN*+jQyM!sg4k@*hvNP02HIY&7UB;So6rI<_`Riq#$Wo%9PCTY_kx zxnOO5Dsi~EExLt(*f~M+Wp?vS<9@v_`khk#Z=-fi42wPF3haocg6h!N3MeByg`2Rt z82&gnsbcWf(bITR1ewyA_B`n-W6qK3re)VvonVUOikYmMIi!Q03Kw zvvq1=(yuXtesI?%bj&GLw~xm01To3;m~lRF?;$w9{WgdT&J$epj!HtIGBJ|{p|YWL z9WY{Nt-ynTYCk(Jf@)^QW83|C0-zKF7!QhxgYNEbER@V6&HOqFGE;UuMOL@qZ)fwl z+9Z(*QzAnnBsDw-&Fm1C%9rmEXK%i;GIA8(0qQI3Pj;6gk~3h&s3G{ZLg#CH^C`Z0 zu;BHrm7Z+MsLExFqTk{b{~%V$F32KrI~p*H_<9IAZ189jk8|h_2y8t-$nxp{E(XI- zzA33ux9A(GHp|#iKx1&^o`kvy&haY}0wU7q#=UEvuGK_YuPJ907hupKVJ9prxHVD*YuSt44wz^SFRAkqe zOJ<@O#|)YxU1P5E9R}+(h#k1_s__^zLQwjdpM5`=mI)efL>}8kVlURH8k6ItWbH2< zNnzZSakQgvcO&ZQsVU>;>$ttzr?KII?2P=-I2z`<+>`3le;vALI?6 zavb8fvZz>vwR4DqKgfRpjTiuE>dGPfUiByJ3@6jO#R#UwHhRrE?B{pD*2TY=WO5^g#H4Rb?Uy3Jl zk-57cJ&3Bjhb~Z9fe)n{P*i^bTkXWA-?gDOwdhC#e)24~;$p*I=48`Q>i$5)Mb`~-DKEhmzCV0TN(55cN`_WIUm!OVsP2^y^DWvXib|K7M#y!*~!yl{; zb}X-K!#&*SYWJ+@Trm#f;gkztE~BvO<+j zW_eWW95NH5yNhXcYdB9_C7~5)P9$%4dy+kwJ8#xYR5_JS`z0^DF{qr?hPn^b zLy^4*x-ZlPNAhIf$S5$NbOx@mBc`pN5>Tt&Bq+_58#x7?Tufo~J!H%VDF$Jt9@}Va z4TP@4J#b=^Q;nl>k<{rE9=ZFCsgR#l{RP{T>%-LuMue-}>UOUtYOk^Cs!{IN7%5Gsea_j=GK8dyDCTAKz$F87jxnbq=`N13mIF zD5DV_6uC9u6@Z9@5*SMbj$5E3lIu){4fu08FQTtNi>|{trgHgm+MiW1a038m_`2as zO+e>DLnBD&nSYAXg+oy$!tE~=+!IcNQ3~$uX@FD426`j{w@1?shen8P3YC&*Q_du1 zrem-TOr;Jw_z+2rD{zBv3pIOJ@As70D9mD^aHtagy>AUFc{Y;%Eim|QI7MjwB{YPx zG+5wPu)!B%<+A;nx!R1Q^fRY}Xmi)wG?@oufK4{s3`fk_jAJIt6cQu2H&QS}bI(}_ z*qM`-(KH|D=mz%fUYST|`~=HB199CsTtG?@+Jhh^U(L!r8d_n@fvd()j&l_j)DGR? zaonU^0j3|@9?;!Q8=+24P0m5NqwDh0(Uh_4eBxprGIZ}!YOoH>xmBB)ACYZxi#bO0 z492=&}eV$dBLMMorbDK$m9*XfNiql|35deNLWzXe92vbCEPv9Xt^sW-`&0WKu7jTNLfu z1XR&=#7M-1RToO_4L7t1Lmj--6RIJW2-u^>k4rNb9Jks!{C46(&Un9AB;QDpJg6t{Ljw zOFDrExxkqTDfd&a|lV+dR` zRi4@FTc0G7YaP1M6HH4OP4?~`N>vaUK>j}Zp0di=7h)By)H=n28{zAfSfG!0bmicu z%ok3Om*O18G(p|pg1SM9mY>Acu*gVEQBl!Gw;3b0d41h+ux>I1w>cwf%Jr!DMN~>* z;@+8r5d)e6qflTyTL;g>b6>j8d+y`8q}6#)U`HK&eCa3#tysSG1qM0 z&ItdFyD;U}lh~6r-{yV!paODEu6EMt_dr}&sx!0q7Gv6A{1!hHaEMPyM9eG}Y(!Ug z)`C&gDyEYb`B6GBN1~88^N{hH{)}PSWhk`TuE<|Ve}{FQRv4ZT=xU5ZQM)yk%(2@u z7mBR-dWZ*4nPusW2j+@=yY8~!yUJuGkaY!o8h#Jsb|iH z9U3s8wI-f?X6z0W0{z0n?l|=6=9ati%%mYjGCHor3)~X3)uN^2g?~=l*cT46tX(Vs z7fK=9)ltCKFl0BnJFRe9O&M@3Ed;cuwWYaEtEK?G?vBZQmfUNzZO|kt9GIz~ zLxo6UYx$u?j=zQHBX_SuM3Qdv!hxyKw-fzjG_tL^D(ATOcrYHlV^NX}Hj;zy_-IKE zP>kRm#z9N;WwWg;F2(s^_L7^&!x_`H;a+KDK)qVrdq#@MKi#=b(qKf`93T|#!n`SiAbl4}5SZW5!)jY4Sg(m>E z1y0zhhG6SZ=hplBY$P@|wZ;+M6jBzf{q{1+ZZ48+1M%B99~Y!5PWHsNH`8uUU+p#< z_{C&T`PXSJ8DUvPVW6w)hEmyDtABS+MeYD)vAcHpwQA}1h}$&3J!jphbe#B=5^fSc2jMGMdE8V7wfcVI?!oxzzp?IFsY~_C!!+!yD00a|w zQB&CihYkgJdIHW&?$d%jy0PbO$^FjE~><0DSQ$$-5Z{!o|q!ctC^c#hWP+tpA1-s{Q*%)V9GSc+$Ui@pco4OYP2zI(&Ry zF%j8vajo6;5DoqLSvMjwI8u8??g+3A4l<1TNtNC`X3JpFs^{~EJ*WE=x~*&WqwBYv za!s&ACq2~e@A9L+5vy;g3fTz^eX6Bpm@sw(4|p2s=^t)EhlPgKn;x-JV>uudJV*+i zT?S^Td=N@u$yVXmu`v`{c8Lp*esb%k|&Jut6H>5ru8N2|JB| z6z-r#opu^P0~P~p3`AA|+ONJpx>lSiQz(dUu%#c6%h(Q9^AV ze2Mn60Jp9&Pk0h{3dB{N-Sw{y&F6y++lIw-H*K>ZFj9R+VqKa{HCcCudXazqv?mAq zDDpE_U4epe?Uy)llqFMu@z@uR_0uU^!LFWc(?Zf)GxyV|-IGVxU%#)B+vRg(1Xs3p zK{4;cj~?!}wm5H^LmR-AcWcFYQi)RV*S=_2u=%r@K_~xKEu2uSPdAjs1Sux$}Uan@1kIvfb{_x3s*5NY00 zMVRI9ffAJFdzXBkfE;to1Y*u1PI>aGuB8=ejT0%V@gb{8Z2)1zG@QO_By^783=Y$% zd+Qla^A3-^Fq1go+uStBFdESv?^|N@*C$2%4XUwQDH5ao@k_-Rl;_j>- zC5P?d*)sxconCEaEl;mW%PRv=?{s|Fd)>|E>)-6vlFI#i2r}~A8IW`Lqxt3b-Gc&d zTZ#T5vCprai56eryHJ}yG$-Ws_kqqX%e$*E6%2?8 zQFA8*zt9q+S&iK=m*0}ylsO0zFkw?%$}7t(J&rxr)Y4yn8k|QJ2XvO$EMT#q_ktCer6>;nj|Nntgy+6H z`iV!tp*!6u;!Bbb^XT<)1gzBG2`KdLjqx!?5EO3Q#^|RC&|BAh^O6pnKk5@T5MA|> zlG@u{>2(Ik$iEFgEfN(~SqBJ=(d+k^Mfw7aSyuD&Q*nSN z*!uacGP^6!ki$sEQ0TyGXK1qBi{D(>f2%(w%-Ks^kUyrnKxjz#w`1&W3?X+o8(f-A zlywzZKnz3yV_vpp0ia-czLEI)$(@J5D(Q(2xGiyxEB<%}+sPNJ`{a69Y?@brdG-?f zcreE=(?n0GEbNXm1F#az_e^pEg`oNVkr0{t3^yHff_#TLyk0Rvf8&Yma!{i?(#V1> zkSdpGDqzRSNN1ejy4++yOWKd!E6^Z#*#v)dM=H!1PZBFOMBg|nt5R%M5!W@AA!Jjfs9A`-<$ z!i%{@GC)Py@UD8QD&~1$nIWDPp~I%aiclATQzQRm0ZC_vZ*{*J5$S55;6!b~;LefM zNJpy=#^?Nya{(#*j^?N+6vLl+GrhlCa|*}kfR{ET2=biYRGTgo6HqA4loXw~xMt*O(4Lo3@+IcR&6_V^{A>qq-sIxHdG6tZ zdk-I6-J|JmR;ie-tIKpF2os(-1gs808miixC(T2#(Rzpj+RjnInwx**Eih%Uh}c?sU!FU(Z}qUxbA3yRdvfb?D_MbuX>k8AmZB$ zBFsaQ+&nD*1=|;=mRg(zO+R_9wQzZs9cC z+<#e(YBF*-=OkmO$?Yw+x7pL;2_Eir1huU^`n3U93_IXD=c(>ZOy4be5wS0!nxXf} z`TUQ#ymW>%+(Kmlw{$A!i2FGrWF(%SBO{#-Ql?b$t>H2@A-l^sw*LDlNg+zcCb}71 z0RHAn?;P~*JRc@k0Jn5=OEZik&*c;*YakISe$D;Tfyn z<@=>@Z^n2fnj@{%bU?IIbd^b#!5Vf0M^T3_s>m1SJ_{i@E@YjY9jKLcul9i&t8=P7 zsG<^$A7V)!fQI)8%tYrirx5ceiVBIU@+Ku#L8`Yt;8Pe$XgLIPdIf6;og!lf*@@di zrS=--6rjRFAKW7fW&FyBsKvbwp4LW$n05$Fry|V}t)_?N@UjPGGB9V0O2YLv z(9Sf(_uw<^w{KMJ<7W5okSI9mvK5^B<3YuBnBkt!RfH7yE6o!%Tf!6K(y^IL1!u$m zDMnW}cE#ecS%iMC-g5bu>#0k%hA1Ow3)z);u|*f}OZFYv0O14uTG^PH_{IHdJ4*uH za--1u1UIiNW%E5g9J2{OKxxU?>8E&HOU|B}t~EBR%&VY$bpv>qG6Z;34q%!^m8)!$CibUH8v9>i!PbEl z#Ljk9vy3vc);aRrFFHd^C^IIlpFE+{HFJXN>?Z%S(%qv%9=Du634*@e`YZ@?IXQNG zVAJMf+D8kK#*!7Kyz$%%&sJRa#sIG=Ey}l(E|xYU6>k}W8W0{uXT44~Ly!E1k`^Q6 zWE`6iVLL*PIvQD>Q5=Y*;O7Bif> zuP#`F7>=(F7KfGEGVxf1f!5b?$X3*ZZvvG8|8BrzY9#+L#a!U*a>QpEO&;Z9HXlD{ zOFR^a+CWc^sJ(543zESThEQ%RRFz>7BkV4H&!&3teH@brX72W>ORpg}-e=0}irGhm ztE}<6W_s+igjH=bC*YM8k-yby9Th>P+L!1oW?5f0Dhg&XAMOIGM1aO6=`1 zHbo*0Y5l}g40(Lby9wC{WHJ)pI{1kgWqg_lqosgz95K{dm4C~!eI`QXa~bXk-He;| z4>Prht$_&6WdbZuTa6xj%LvdTi5mm+JQ2K9Mq_ht6wJbMMpoc#ywK&Dxc?J8X839!KzbSW;rH zgci0y5<{Cw5BY|-A?Ofw>+S4LD=Lvl+hJ0ej`_TUs$iHQ)P_J91TD!;ID7ou>l7u1 z&~+9aGZP=-`f}w~)+ru0fm6o8jXsRL8|QqRSir3Hjnl`f20E@|u*tJx#+>ZT*%DYz zegWi{8De=Ck796Q?=3=KhARKqD;gf6V4_#{%ma8b4@tZTj|RK|nGX@im|_K(AKv_K zd0(q1)>EakHg6)@zed|pVUJRRMoi%zn3739lKjfv_Z=)V8rSLl;>~r&t>4jg{-`jI zL~do!IcGtxr~6X(&7*ex(Z=xaDTu=K>h!J`KhD;_34+sxCI*?*&4Mf3V_P&2dhR}% z19B>ar9*-51;#gW-#}?O@>eiB%qh>wyU;VCjgd13kmo;MTC*YbtN z;N`@nDsj>v$*0nSdSb9(h!o{#Lw8!_UKu-j<66V&g4b$@OoGink6KXr`%=xnz#T0g z5GuW{(kuNj1gbYNic))T7&%>f=Bo&TY2Z51l}LvaWVgQjdlU+=ozQ$_kQY-b%?eP!mK8dn=(DeOAs@>eD}XzK zzjam{5{jAql&dW;>SW|fKdRZ-WVle=R1aCVPt^mG1k53sxV_5|g`MbY9L$@vDE);gA zhrVyhcvweHJ+4NdCv;1&_57CV#f=G!c$Oo%$!xG2Puw zlzl#yNIN)I?KD!nkHWISL88kf9Es9~sQ6_S+~y9$Vkp{l&8MWdA5Ccyec4jC$lwOnFaeBWFp2yhJ$dj>@nxW?~ zr&3;>mlw=U_zpq+;`ekB648n_ck@z#c{6-&lgle_ycJBl=#{jvv>%*x0Icm-+azNIxV1*woOz8%! z)9_MpNyaInBLf|w>Z^MN@XC^E+;*?Gv$fkw_wG;h11zOYHz#f=b0JCb?&5O|MwklJ z3@Ts=7dWuj5$6d1##o^kRX8fh!n?FgG#8qGBNL;2{zoKo_q}z!d!2*-FsRlFE5>It zsJfwU+7|LEc!jDep6mJ0Ej=3FNOZ+7vL)V^e+M;BIqX$g4f~cvOS3gJTi`|~-j9xr z{;sp)d&OtUWm%oECZ~)=uKP=VjvV~qyCTteuK%$+onN=vu7WAAjMfWs>qhIL=&~hUiMxHUwbw z(bm5(`Vw%OTRw9#UAceh)!h-cP6r>nVQllTstj$>=<3^8vmLXL#0kO4gy1K4-Yds; zYn@IxkH#!Xl|20=`}*w8{{6XnFS=4VAyh`;Qj@>y!kZh9(p^IhUHVlG4sm;vxWKf7Yko?+<8vK{_IF zPFwZ)c_1NV1@Q%8U=egU&wjK0eHEwKRs>nAVk|?q9{5kJPbhM+PVKOuu6=b@#nwZo zes3~XGTE}PP86d5IrjGjo+@-?{h`94;68{lQUJ2_ z{Ye)GL_=od^C#u^O?1}I#TaHba2%dB1Pz~z&kqm{%^)V&&ObM6wk39|DxP)L(+lk^ zcG0>xfn{nEdn1wGM~i01eJU#|Rj8{9|MY$u9S#iZA63a4zmkG2p^OMs!zM^Qvq>Hc zk$<0gNX;pU3v#b|#6vU13^HThEEkKGJcx*}^&SB(EqvM8K%F>n^oyrd6IjEqOvP>K zZgl6h*TdZA8?WVx79f|N#+*d8>>m2C=|fr01l>p5_GhFY43m58v%5Y9Lrjm69-zGG zd4qI5!g5?19eVnNkC zdg`;3i-RL*yHTTDF=H#J`k4LeF^=KHfKF%kz=)lHvSz3xLc#9(#Mp@aHLUmcLerQ0 z+jsRHan%T(B4hu4ebqdby}4*i!)F{YdHk+A@NXW==eXs}6!YTuU!1|-tDE>x+}=I+ zPNDT&aayB5RmCN(znlM5;b*Sv`=;BtyYs`~25Qc3_Lr1E22~^}mnO^E#Lbk(7TOZ01I}^QWTo{_^hh8K*VLg2K~6?g6sp)ha)_t&Goc{D|t(xMRsK zq_GdQhqnK9|1?^hrbpefa}XXmvI!XuEPd6t+KJ%aVtHE_fD`1JQd>JbG`Ts`SJS>fWsXd*J2XdOu$pxB|p4m3k|A9 zz=+EQlQH`P{`ZS!%Rg$3^)~LPr7YYhgB%4CPcGCWwr?nLpbWKT3C+5%u~GH+tdOHu zV5fso(;_E>?S7!;OUloywbW$lrd)CsiTAnXZ;Mll&U3J@7@~%w+o&&E8F+xty_2|P%~J%wm-l@&m72O5vLoz>YqE+TM*H-aqOD# zHyy-LRTo6Sdkyz*(V__Z#uJqL_AWJIR{nZoRIVrdsy?f*xNqwi3L9M%% z@3cx7`YBuGb&Lf^pbeW)~ zLIZA!Eu|)-0XOsH^5d;?;9Z5JlnS}&QX$;6_ELn3^UJs;SG`^x$G6zlvDmX~xT&Lb zJ&PxO*xt+tN_b6iF-o!-ZfdASLEF;9^H#qNFWyHP7A)b|5>7I9m(tw#O=lE57%NRN zGkYkk`N$51nN}q|1bE;RCp4WdKEKV%t0ay-@;cCTklzX*wY(;gI@32G;~bfFSFD_? z;MH6fw7gCSUGGO5kP69Hub9B@`4xmZh?2~VNZ)_Jy&-ezDhG+smx&|;9>a9i3u_5B zKdzMJsc@h`!M45U!;XL53X6J`ehd-R68gpa;K*DHNs7|4|D@>mf~b$Tx@R#dS=Ad! zU?cDzjg-TQOqSuN6n5eM9v((Q{#+8P6-$ZF)o#R}X8-BzJibr;<6v@<4ePAF=l82slFJ4qnNj9`Ivsc4AxJ!t zqAb0Zo!F_(_-I$tG;>9Lu9EVBHup8c-!>#~bwJQQPzHf;DXa~#vdljYa`6vW>CC|v zg~PTJYM#Hv-Y~gN<=cb+!n)&zDu7u8gc}vQ8$8I53bk|2!qz@}V!sry4D3+Za$5>y zGzmjb#DC9`D=3BIGCryFKcSA2P@rJJVZ%J=oZj@iVRHEWbliL4&!dX-3Q?L8VFG|qpgm3LlbD|-9G z^AH}y1=(8Z3p@H{;}A&(_$s4!3ZBpC3LFsO zk3T!HHNuWT8GYFtv5nuv|G?+|>`H_Pq}X)pIMN)6MG21W-uUhJt@3{{o8VC(4A-3+ za+VyBW#JUZj=L(DY+ z{!r+cAjf0y=QJ9T`2B+-D*yivvND$c+anES|E_wpOM<}Fn6 zuu-8Zu~y&3{bez_7h@nhduju?IyeAeE=VnoevZMG&@%wSNa;KPhz2fRI1k{QI^4C0 zJSl7KrGyONl+Hwz(8D8YF5{KHp?qgTss=MP5D524@39;+V{>zdF^|$ys)nG1k`1(h z-(DA90D?28@1#!r?;JuzGu}fkP-g0k*P8$VZ{nt>w@$gXEFZW2anXNtWP67f;QcN< zuI*En_@0;%q0%38`yKhx>t+@Yls|!r4l}S#P`7V$1ffLIMn1z(Rb^1dAm!$~R z2ZK=yOo{>h>UVd28RO6oqPYckBOJo>EH4+UVe?Z$iM8(kxZp=)meNA?U4X~wbzLlu=J?v`QQc*{aQyCI6vCIZ?l9*!#QT&A zFiSPaH}PdaK5$AIsXzci1g&BX(kqxgl4Uanzdbj#d=Tfo3mG?}=A>QbMseHEeEye+ z-Yo%^0e5*S-Gut&+#1f}W~4WOs_^iqd&`#@+S)9fOs?0)9(AZ40{VK&6pPE>Pzfd2 zY~vmHy=DMejaWxMgp8BZ@#AZY4=^5P_mX_q6*~t$4UOV7m=o0R-KZ6vK}p|;t~?nL zkXu$$)~$3?*AI!;e3XjLji%m8r-+<9E_Zwwc1Jxf*+c(wo+$*SdiXjW@?G(Gf=#Nu z_2`S$m%(>OmyR^r`7i$*+4&_R9buIwZuTQYuXtx0Cu2Dpn0fzL|DyE?oc#g&vR6L& zH64T z<3r%OP|8B+)(k?+8(XbP2Cct9`ls~_v+%ir`euWGuHAIHt7m0+UM&Dstm8C@pm})u zcx+y6$h2J*&eU2oqj}ImblL8k#IKf|Z)`XNb!8iiPw6Rv5P1X`p1#5Q!cBxHO3fP zY5elzwxq7bS#5lEY$%~cDLr#CQ zQ&ShwBqQB>1699ocjJcME6*}cU+OL0zj+t>RQJA)wHNNSqZ7{oZN%X3JT670?^c9H z>CC@~LwgNZoH%!HuyTTP8og(2wMKRZqw+AG1oOiZg%@wWh|4Rql<{Rx$TLAlNO`Qe zv>a5dPBBJVgRnzEg%6uwggVbXWZb;qZkA&o zjL^qViFCIvf*pQ6ZkHmU99@gYtX|qLc&#ThcE@)enRa=L_g&ZE;j^Mzc0=@mVoF9+ zasJEfuEm`b>~kVFO=h*Tt7ASSyz0#GNp@ct>KrVn-0H(O=*hoWFu%Av3$LyJn=ZPZ zvTJ`zT?qXij4dg508UkgHro48en=#cb!618l3pn(pJYQ?7U4_6=)kjyrjh9BwMk=0VPOY z1T!%OlklhNA|B)08CpDG#JFX6TiUgG~9wL2OUlpHc_lOW3e*uPGaip9M=U zeX|=rn@H@YLijaO&Z;PNue*L!r3`N9?80NzZ9MdQ-*uavB;waVE?T_tmZT}Bet3#K zS6^6``siD zB!zCZA`F2x0B+u{={*{>iJzjWx)Ex5qxtX`WLl~?j|r7ChzD$uums7T{Q3SAa@5+{ zuvHDrVBVG&YI(5eKnvYaS>Ey6j=;PnS!BcJEPDaAKl-Esj1;s?qa%PqUAFX7wYQcc zW&n-U^~!q>DAr=WUg9LsZr#9}ew(}>*9_n?lw{|BId!0HG#tLuGTf)LXN?cWFJ1&% z3%x@v`!kOeScj+Z>ePX%^70<|UEG1!EF17x+`|@^8&*S?$L@FwOaRa45;Sa}c3 zf99Ad`7U`7H{)P;~LP>K2w_jtrHna4W-2hq1CsZ<kNA)4Zd zwp(!ZXW&=45@0IibwgX#HWWc=)`8knygN*1w3u8Xl!(f3PA& zTcTLHx>(SlvduKo;@4}3IMOtKEWE8Avzg(q$0jb*$$y&=SG+J>lGUc5JJRqMh}&&H z@B>u;g?1a6Y%`nbhS4;+Lqiilrxy%}7Kr5tv>l(x(*G-jlWqY(y(*5*t$zVs0a>6R7w~s~aqk_5(Tm0Y zw!c6Hsjt!C?c|${2iR@mm5-X8n7egd_m|Pbi)4`w<`%FqWT3|GhV5XkMVx=DHC2 zmyg>-Z#v#8q@wnxqf)|tiN2J=yD^qJ>Oi+gem(Y2w}*+|C$9N&;oHC4_Mvyy$D|SX z?_n9y4I5r@U4JTOK%I56Am?9{?HPL0tV)v!mcKuwqkj;uQkahUXF3&U01hk85PN*4 z1{~J7;A{Wiy>9(JpMq6ovcRz4{cPU^Ph-^LxFwYq2rK&<9zM7M>3Z{^bWsdgq#<`Wqs&#PP97Em?#vN z96W6HzD6l9NI=gow!8lu<15UD7+_rGPA~yIDd{_1LjG}2kwpy&eV%YgFB+gPh*cN0 zc>K%QATlC1H{JccK)Q4I6&7C21i*xFH)qx__#JM^*DcXN9rIPRAD4%xjrCJ}pong(q>C$}o-MRoC}5Ui*Q zR>!@N*ZjX00!4ve9jP__LYJnx-!G77DRve8?S4Eb`z~iew8bKEr?Es4A1Q_>t0ux` zzOkUlXW6WFEVn@3{)&5m?y=W|L2`u^Cx`WttJKI6&=w|<-y|V<9H01{k^CryhwT!d z*@F2_xSYB?GDbO8b`RrkjV_DRlM|WVd(XLMn*s>h>VX6I_r^jSW`}fmIy11l0-hDk3r}h!`e^!du3iKBuEmc3cfq zPMF(C%|i7knj4Y5BI4e|w^F`T(+5cc9ZfiZ0a{!~(M-cO%;3uNPC5XTzLxx!y^aY` zyXq8Idi$##fqgBWTq|UVZi2gsHW1x)AYCnFPHhhIKahO{rPh=MG?PJRGue@nZ{{3F zweziK28)ZQo#fG=f{>lr8%ys{$y@6G>zSUm$iLMOw)_s?tyy>gb>O%pstFN^7BVP* zWq4>V7r z`?09idYtcUMp#wAXGl85`!Cu@>N_smvH;lwN$b>>eq)d4E)AsR=X3N8m&7Kbk`Y%X zhx7XkK|RS6cms>#FavOdRtJHum-hx<7ccFV;ErE$2b_>GEX(Z(K_yKY84Afg1}{Cw zCFxue-Grcj(eg_9yYwXCCHb3T7-3@J9pA5Ar@~`%X6w@wY&>ngYp?W`D9-Iq=1<-o13LM9qDKAxDSU?r?P!mo&<(zX)6f{7wj5! zQ4q}FRl7mMUB8~Sxm__hZ}^~3(aHEyAgH6Zn;#MS%VSq%nRA;`Ck(P26p`ylsnO#U zp1V)@F9rJ>$a+Mjvy;SoTV->iMnzWAxCrU?glRH2l2)%16~92unl#ci@XZ)MXY+gW z!UM@sA#55+5+}#LngSwOg!>-2y81lDJJ|cQ3f9Q`LWAQHK&5sllir6)LJtO}5r*vp z-S=jvNW@DYKw_0;Kt4M#f#H>s=zHYD~4 z#d4#yPM%t=(>$c82Kfzch7IcNG65yDpG7w=_xy!scR+L0PVC`D)`d<(gs%#Ij$wGVVgp4CS)Q+(o@HG#_40;VKHN+F z3bUXgAXxN{oi1JWIDD)-XbP4*?$vHCCzV^D;eDI_-eJ~hQg0HQbT()Zw+?X@j(G4) z3=~Q9=ycu#Qt^tS=4sS3+s9Aa706{i{wb&XZu!nYU`_QGzZy~kb!+_GjtdO*(%e=* zsSr$6lpAMn@pV?;z}x#^2VeUv&e=Km*}gR#F2F_nDBg0??oBb@bM>p2WGO!}{CZ1r z1Ma$E+Sc_9Bn*0;RE)bcAExCz=u-E-KJ|v#d#e+PatxPLAcuk_E8|usy{{$<43J+9 zHsf@9XOWqlxwo6o`yn6`4eaeOfdO-?r-}_4ay8p~(tX@@%P|kt*(yKwptT*Pz9hEF z8;2R!mm|fJnAq%@M|3~bkoRjw%RJOXuP+Z%JX&~aX654{H%TUB=~#RW!MTZKc>m4G zZn6u~64!OBB_#kRxh90UTQMN&Ft6&FF5!36^||UnMxs#*#cHy_?o7FQmmRO`V_m0v}8*^RCRN1REF|l(Q zQ+;g3?wf3nsPI@v7~qpLevT-fx9g%CkMzD=%As#?-pQZ8Tm@?sYW+T&&`6(!T(9;9 znVAiLIx%NKvDO3~4`@u9WpCpAK|;+~4G}!yiv?CGm2?t@s#n@Sr9I~j-*9?qTjsgj zGYiJ*47zq5_r?hf&f3(UYd`ccWT8nv4~KYWq*?dVizM%g=l%toQbFa<&=yJej@JjRK3pQNjM5cavJf4RUe=2lOB_EOvxVu;u`nr-A+t?o^Xqi}D}8QRcmUay$}hNc`yYhCfZ$Ql82vy zl0-;1;rV!5Ts5xEBb(ViVf1sbEZ4+r+BqHRBu_jAMDK5Rn&ES3i&#dzA+ia zK_+?XH#S)pTr8;?Gg$GWyH4WG{jRYUhoAUUQQONylj|(;<6d|Snk%lC{=|~6Bv5Bd zD%k406VEh|(S^<|>`gs-ZDJ~3=uqb{w)t9N#+X!g<+wfUu4#9Z9*liI|kxY_dzszW0O zb*N41(J92?$)Qn?UxS$61D=@Xm@tvDe(36_UXbEA#NEt5Ok}Es926aSZrfM4a{OsK z6qq|#D|Y)baBP6@4|s9ca&{ZploUr7Qj~_$Bl{P_pRJDW@dXL%?SIs6e4BR}MR$;n z8Ng)T519uLqe`Nz6-+JipZ8mRrOy1N%*m5=pJEY^Z|fQE5X{KGAI9Sd6;#8(oI14S zBrt|uG{9y!P2>YK&HT>lYEl9#4X(xwtjRIC2&b?1>nEFjxzRm?$DkXVQaIkahYf&# zf0g%w`nBXV};vM6yk=)%Vxws@01J`AOv26o=q?$$8}opm6J;J=7iGU z$CDxL8*))#;EG}@@xjuG7L2tWjFah0h;0j6ZwO8Z?4ENNZ0i5vAI{U{xHiO$y8_@t zjJ5oKr0XFq)J(hu7;Whi8qaH>*8`iMax?NEESA1r?)s%MnAkP3mm`VIW1M}KSf2eH z7?*g&)QnxmlHM3<9!nSeDQP+)*y~iT0KTzqTaC@ z0#7{98Tg{BKX{6r@#o3Prd+4^8xk44Ec(@~P4fXOFM=E8t4(`$E|}NVb_2E2B`vo^ z9879Cyr=J;l`@SY(Eu8bb*}N*QLfaSBX>CgqvxJKgB4yR&LehWah6t`hjpd8l-w`r z0th5V1cB9%n3ia~43BaBIWq_1arzAT>$?uE7pIfWCsjEtZj%l3<5BJ18NY{w9Z6|> z>$81ET4!%2en1_z-$_IB)`t_DNrrTpn995d5=~zw!@s@Edna5{gFg1@3gb;Av*Kv< z?JEjq7LqOSRkq}F*rrR5&270(0qP?Q#Krt+vL3OObiS&>R4$B_y==7jHlW+`B>pA4 z-dz?rH=kyh8R~_-o?lS>-jDf1JZfe+IZRZ^>cjmKjK|v#LUx0jE420C0&1e3XB$Wn zu!~ShV&hRh010*35c8_JLHPm6vg`xzztAp#lbha?c0C&I%7=KbRp<1UxSofuvH2L@ z`5|z?33@`lF~?1zSdM3+^$Ft!eSpfM(OHCdm&j%vgM3q z>+$Hbm~qf^kU4x2dbwJ?nuc|wH@@#Uj$y@>zJI{odcd^a^<|#44}!(VGJ^V0o#0}1 z)5J5^0IbbwtX=?lml)`U*f5S?dXAaW$V^Fc=y={=v0+jmnGufEyQ;EZ35*n}^aRaL zJ*D)$Df|htRgze7R$@iTl^ce;ep!)&MsP7u#Tb5p+_^WRs%sZ?&zuWBPH*Vyc1H){ zlIS+7OX59Urv+S_z2k1{x{kNGyNi8f;nBaJ{~2B!E(zo3UFk5AhjQH^51|YP3*gYB z67Q=mn#b9?&=m1#&hix6&6`arwVR390y{^EQFmpqU@2qF((_z}Eb_l-ENZA@0{a-L ztRBCLd-PN}2x`UuM8TYdMutdCiR59=fEegUSA@qFKBvga_Xv{u8BA>Zg9?F&>W9JB zJ1s??vRb$#LCgu~|6;&iXy{eM$43CV%)($%d++wLa~Sz2TL}W~Gji^LEj2Rf7P5XZ z>&lB21Jp{8fjq|NIs1brwQ>E7RMO_zu^GUQ42AAIAYv?S_3XbK2HcqD1D0wU*A{&9 z3gWqqM=78k(N;sU6cd!Wq*d|8N1v^N=9))9OSdh*1q*$80f#GqQV6^(x6G(E8tbig3JVx-bDXKC2#JNADIep)g z*mcv8?c)rnYjL8C4#Fmp!<+NyD|>`J1Z7z=*Ng)rix2ON4Y{pX&ZAChcy{vX`ctme z0i?S_!B7dK^$Y2SU8-(5Wyy7!jtnA5uJO1CVvQt&KFVU!xDWdj#e6eHTq$1O`-tsK| zi#f|3d$&Le&QXloI~Z6rckW*a$H>8Uv(%rR2<~pbLg5E6jKy9xY?T>mPB7%N2g zwfbv}yZ_4nRSfxb6hk5AR$fuoq$K>0itIj?fZPHQi9gO>e5LC&@rlQ(v(tKJK>yy( z4jCSg_tdyh?k5yx3!g^SgR0qp>o752!y5tp_tbC70qHx`uWj3WXQ!1gFf?eWrAzTv zPU2kS+#b%aytA{?{5YEBMv(mkZ{-xd}}_^F3B#$s&7 zr3smIY394K9w=<*qZ1#?%LvdFdc4Pc9Kpbvk?6x_s>FLh%0W34-`#E5RdV|$*!vKi z!q{fdbHbf=t^+J(eLPsQSa{ty2fn;YemBX_cJ7V_3k#88_QYUd`56!E8{BPRC&4vg zBeh=!_i*^tH0@aTzm+0wcV6xsz>n3tDlp8?4A_@>UFN|2L4y{dP4Cg8(&;b!R@vE% zj!`-(>=Ak(c$UEQHsrL!jI9h~9j$b?+1~NO4gpgHpq47AN9I4;WGPOR6iavhF>JTo zJ;8?cho{8YP62#VpV5Zpd^(kw%fZu{@eVdCx;I@bh85i?T*c#* zoQNOMOJbvEG-*t0)0Az9L>BNEBEi33(E78@=v#pwmaa|bDHv^BHJ(lSBvP;R>bA-^ z+X$S;B+We21SRQ@x7KPpzFd;zCF><4&VQW}2_Gv2=m|-QWIKpUJiO-}Sq(i4w`^NG zb6HMag=%78X0$I!UM>>z+`CAqY5ZC@9;NrywZpn*?&aJo#K1^S4HG6d%ADy|FzJ`Q zK8euxplns;P36dNmvfSpClCI|FopZj)YOkFP6wDin}6H1?A%O#(9Z{*q>#4NY`J_+ z!W`2)k*d{3fc?_{`b{aALdakOJZjWf+M{9UuQq`^`no!;E{w+=wGTN-l2x&KuHM%g z2hbP}cr-hOI=9$rZr~lvR9cZ4bc1lX4$&#aXBthct?R%_k&SCtGthn034V=9zKweK6-<(%91F(^bW z#reca{W=w5yKrd!IlHWjx4m?EbRvQ)v3;Z;b1kCGewqEqXRj<0T3GjC{Kecn(9{SG z*VoPk-d>8lK8vJLeBt>719RSnh*|hEH@6kRyWwF~-U^WzlbhU+&2oA4pw?n}g_n{5 zy}x&BR8kwO)31nOw2K45W7tMA1JbzH()c+TCY)+5d(r2=6h_FSd<6M z)ap3v6n8k6{B~8n5SkhR;qrb(ABc5WoHhV^s+>y3^liqWC2~ilX=U~kompYWb=&aZ z;1>);sgxAsR{>=86#f~-4AW-|{>01`Xypr+VxAkB6|IFx>b$`YNAp!G7e) zk#+ve@wwcV;_1Bh?)&rC)}uL_F`+#9kxe#`<+ou=412rE2hoD zBwZ2&X|W8&b!LjBb6XV;jv_w48h5cT_v>??RUDqJ32xKWfNy0%+~gVz5&% zltJe!6N=mmQ2i>DaU6qpy1H1C0O>?^JtzoCV|BJg;yt>$2u9O%hP@M?0rEeFW&{?k zrMO$1U7M5Kxp9_F1n4T9!kWDSSw0OCEw(rHT}}7!(w#dUy_qktb(1E;VPLAC(z%mL zr*oqG<>c9vmWEr@iU1MFc85j-h{@dtdb`z6EaT^E)&&$c)y@&Q)+?JUjv4zIsER?! z0-MO#mqI>^E-BPLtJd`4Q_!N?q^^TnMap>9COOrv_w_~Mfd-P%+(&BhqdHwu z?q;H{e{4*nN#6_WvAsgh6gmFi#5Le;0Ve+M;zOxJa1*+{ij1pm(rap9u^8fsvV?NS zc$Lp-k1VmiZa4Pt@L>NQmgm(D3lBYu*15gdH!_eWmeS&ffFhcm_Jk!&;(}ufve#r5 z*zQO(8rvK^f*m|c%k7C15aght2oX_Au{`4vRz`TX!UF|d^HjQz`zhcwjXbqMb_6+k zA-8E`IYr#Ni!*#gM=;QNhC z+Cjo{8HJ2|9wGYfMA&64hZClD@}>VL!rj6;A!YqAqr15v?U6|Z(()7{TY2CujKk5=Q54um(Q5kp-8M^ zo7P7g>_uBtkzK5?Pl#lml$##p`OPo+)uSg}D*8PqF7+}VF0vUQM-r2z{k*r2=2m$Sj+3sUKDJu_HEpLRL6> z`f2HuH#Ems6e@A+Cw-*{yjOKI6;&C&hPi$ycBJ_iX^b`wPH5e(8aW+|Ht{l|n{pvl zQrbjSnkX6R4b=;iAV<PLUraEl0n<=pD#dwLQQNV5O5G_ zDN1$)W6|vDSrlCs&7ov3)n;zy$X)_ewlDD4P)j~w?)(X10*bjYBGB^rt2|g;PFBWS zON(nXi9LomBNCqy{f=1I>Pqsty@4Ld2rZ3c( z8MnSTTFfROTq=Ht>0_#Eglobxond$l}X`=R}Qv33>r zef9wBZYBQh?Lvwv&g!ZRw@jYSjy^48ug&DKV$aD{A_9Gz(P1zfCsi7N!=rs^xabN; zeMu)O(o01O#Nm@kY>nVoGFTUcrW{hLq)FQ981!7WJ#mrovopS}?i=X}@H}xnY{nwo zX1Ap?oF1REo=_5CTOHRm=l-~Ku7tf)jI(IAF0`F7Ld1G3(IA8?FtBXoN|02+3f9&S zCy~aqe*rC1x(|5ew1twA3O=V%h z3@t@`Zj+1BXI%@`o84V|r*`&T;|g>e0@!6*ZgS6m4$-Q=12h&Mz|v*Ed_fA;mp07k z$-Q+nmEX1<*17Y0-SQRT@G&ey;0M%d)Zz%{;>v9c6OgVr(?%n)@W^+Hn@*cP7()>bG)%c$Mq>Ksn`c>GIDqs7DxGQ{#(aM+&kqz=p5choT{ndMNml>qa<7(sE zJmlj1;uRds*h6tu#n&bsh}W|=U+esy^2YLL2~q+tRvJ6z&J)S=jaweuBuo_b%X~@H zT2Wj#U_RT0Sa_XMGT7JwM4Ox&UE!fixa;3CTxyu=uTI3abOgm;A>ORFA>+PB;HCgU zXOhRkV9%Z*a71RB^K_nyaf6*05Tq;C)Y)?`5d-4YALhvO=)tnLC4xWj51(#~wCpa3 zkh$NJXN(WB`a%pECf|f7F0)fOnXp4y;n+FbY_ipIHq@#chAe5MoEuw*V7D1~ls~|h zE+Xd7bqtprw3WS6!Uo=)>70QX9ySFjmUJ)yM(62E=m*&Ti;~Z%iDDM0K6EncrM<*3 zJ5g&;m}r}Y(sj<&Oz2i|`{&7@ji->EYDTa6>VL8TDE%xNfG@k!^quU8xo^$oe17A- zz%Uu-brZyzBsyo?Mdu=vd(K^~u~8>aDq=mg20r@6;_`H!)l@h)f`j6kOfYkD z?Oy_R{1)Rn3{txoWU5ty8lN2zpQL?d04e@>LuaTah&}QP!9&5U*KLyci5>0s9xV^;_X%?%ttUvbxFdXFYf9UJj# z7yI}~j$@dv1<3SKF1Rc!lgLm>UJUSgc8Tv)vno=&WzFcYH0iZ9EfYm!#S_2Ej8kHx?+;#m~6} zSsl^y&#P#r7!$VUaMgT(SMmieRl*6QEw^;#R2ShVDNOLnm7up|wYTH5wU{YNRzuUJ zj4ZodcU6qCT`cfGCP3`5{pZARz+0e$uwTZ?kW4emK8@PfkICX%rt?$Nu`#D>pZ{z> z95gyn_WakdB11v*RhqljtMD}y19zu>o&m}LwT3GwXqb3LW!gkD{RvQZ$b#%$bLN|z zqI@Lr!EJT6JT?79G^JH7*+wV!zDQuSdT^Ovyx`&4Wm2eIx8@2Ld^wVW0Skjdk&}Aw#CsDef+YP@O zY3DhoNv@rTx1ijbC5#`eIEWad+)f)1bK4UnEhOL0I>F7ua>6?cwhd7y#gRjw{?usL zSU-pu@xqwpWgJPuKX{3)u78mxi5uFWd*XJOf|%u;{Sh2j%8J|Ote?TPm$DALbpmuy z3Tf$Yovi+!J)K{;lKb^=WI117or13%kFJ)G-X~(LL1RTPFpPB5kj(%nbvV4m%F~pO z&v?}HpIi<=+W7G}aY#0Q>hB*=OkxJ?4>~>^HcbyM_}=z7r0g;2x-Z7yMC@$Q_Ztyhvl_|71h?0<=6-2ow0gp=q45$N(RP-?HIk>FQqLQ7 z@KO{jEXKI6V9nQbyRKcyxFl@j9Iy-s05Lxuk_1lbC;5=v1+CHJG2JiZv(CR}r)FI^ z$%mpkVldjeBu~mr6+d(cHkifdjt+;cKb2#f%bv-4{f9$jV*;`@7UnCQ#o$oerEoAv z&cAV25%A6e-H+&bbxo5shmTJtye>%ioOT(TBLoA>-tYdWr_9o9i93x)x3J+tMkD!< zif<)SRk3OrA{@in8Sg5xGaZ?fk;=YA4HDhKdcDyGL#;arvouNEC$UDkX^bD}#a@c$ znWai6vA^R;Ce{9FeU&BR3g#B>l(CGa5c!JX48aWB}T@vi>7Z5&OXg8Pz3M*T zeRTSzlI%WrDV**A5H=WYcv*;k__MmGK5lsny$JAOiO@&hhJHjG8N}@3;4?>$XY`o0 zOd>X5o(WO(ZX{&T)IqP&Q;r|s1rHv!f7g_}V&PXvr$Y+!e@J#|5Qw7ZZ=QL5^KHB$ zZ1*VIk3dpI+W_k1kSq<$S4C_UY#7CQU+7Oc;tM_)gx%pk@ks321@>0#*b8XhS&~=& zRnu3<8tUJ`6TT-&(eOMiu4`?N4j;xx9N)EiEA=KKnz-ap!Yim^Q4i$n$T}!pDx!Yg z+sYD8LtsfiotOG|wY-6~>W+N!M2g}nd$1V{8PiZk${)6zh-L^iC-GbqH60bW+<@X(4!sK7~CqCK>-T~z5n2eLP9{^pw?Ty+@CtmVS zT}Ihh0`0p`gYVG2i2JO1`b&Q!RHS$C^tT~8M@HJ<>#i)}k(Nw7TYTU*MqQ*5k3Gsd zG0;Pf`Td7DGge_#9uO3XUoO^$ABfir=&Z7l@W8?+pDhIk3sGv`_@LPBXNiC^3+5&9 zbZ6F0hVHv0M04Ud7Wh{%@{$r0Gr(iFsYJifE+r&1k$gS(ng8Gdd$vQ9MK3iondrV? zs!8&)V?IvZ@cq37$6Wd1KR43qK6amRwn3ywM%~tzyAET+=cSkG4_r|)eMM=hE?aYW zw_=^_+wyKg_iHg8>p<2I=ImFqcKCD835ns$Z&n4@`y*8We?~6XNX+kx1#x0^hqw5W z;bGwen2h>#Pmnp|D=cEa0_W!QZI1@7*$Y0U@kT64lX9L~{vNMmM1zaL;dJ>s2M1jz z&H4XzN#wrl8RGR?PNO+wTfv$(dM_8th5{~3{&mA+VWx!4QP0f|Hrkm%sS#YRT&N3m z!&VDVhqvrRsozRJ4{*8mgV%%r$A-R+X_6iww+PZ+Me{}I4g&|9g!#S_2BuxP%58l6 z=VQ-YV|Rq3NV6=U#?@7LwfEggzc5O~@mrQ`h_Dn5ET#9mxtW9+Fq|;(C!`ClTcaTZ z4r$frJox7KE}r`N@U?lKQNYgR9SX8sf2pP_m=6X+Yv@drslJ z`T1?M_cbr`mR|XpW|oFNMXI*W{OO-57Kk%oz`SbC{*>;(n7M%HOcjPQCK;-}(#Qjt zBL?F*6WvF28a*Agpd#8d*)A>jujc-%3=-aBJU|CLt)HFx`MC`%FP&zWvkqZ&Y>i$Q z6WRlASWgP?Yk>Vujd}!h%&;fk{u5_{AN!+FKsQ}cOFn}%g%Zh@R7PYcCG-vt7Xt}Z zfXnnHkbRWW0(bf6%t(Fh@RA4!?uQM~SZ5tROk)p!-7iKj!Db}5gqY}qT(F2DUEYCn#C$qU;K{)B;aG(L*Lemj1wpK_j^Lbsig zyEROgVKS4abpKPcMJ?_{Rzx@^owuK*9G!nQ;8=xD)8}aJqc?nAGIYr``mr0DzD-Ob#T@EbJC9GF{PF!2uDo<%OE=1<-44 z@$iO=CY+@-Zl~sWk0M-gpRNP8)M@B706!$4$l*g9hYI^(R6gW?Sy(#7m&Cl-7eTE; zm*nDoYsF*fWQ&Bt(TU|3q_-zlsn2vmXd|d*$upQI!7gSgqRIZ}s@zsP6=dGV>`hEJ zGn&UbpU<~Er-E|Sa(Nmz^WIKbdQTF0bg!EP2XGM74F8A%(xI&L_Sva!Jn&&^>NWfj zY=qUwGptB%yFCMF&~8X)6t$S!24WLZO4b{ONDxeyMb8iu+6_nO}0h-ut*O_<z`T1!waN80o?!QH=>QL0v4SrDA0sG^fcC#FltwqWbA=V?fbHIUAna zdrNc3%+ljdk1KU(hln~Zz>a6J5@5_150kgHa?MQwj$QN37RpTR>-q$>et=p>RBi)U8=3=NP#lUb8b zy=j`r_1a5!RG7e(-VR)KAoR^$59x^!O*nxZ#4L$PCL#fEiKi2grv5o%Upy0iZw<-F zhQ2MmKZaPXK#q{Qn~*)jHH8D<&hBIV9~TJkuZ~6=08ga-3gHffRk^{c-u-rfECVWf zSyYT$jve(H3k|K4IR+B|GwFelM3C&khI3Jo5=m6`EQX(Z8?Lv1f32J8GYlD~?o2FJ zlh>b@ZdvhHqM{CO4Ryz>-uIEejpsw^#58%6T4I|J3O(1!`I||JzOye#q=Vk}5w^+Q zIq*CC4$aztm-Z_XttW$ah-_!w?0mUlC0EU$0J0;4H6f>lg;Jyf&}({veG z`Z-dUQ?h4pf|Pk`mHH?zL))ND%}`nYVMk6lhscg}HSy?zk)yJe{QV{uR{IUe(w$pC zBof0LIrMD>W{>OJXgkh)HDGXuyAWA2*%vP^>;h(pi#N1@D@P+c;_KwzgWo~(_3MPH zXzPPu^nHq?1R(3dy8E(m_cmEAJWEFIE}MVT)iKLpsj~h|?5c0%aB+H>`bV+}=nF_O zZ}4Uraau-NTT$|ZI$f1*x@+MRB1O&Um_u2sw3iVPEv6sRmZwF*SUIwL_^OMQcS@-= zyIM@~(l;O^NvT*`B0-h%7u574^pBXp-zTbpEe~)(vYU#u?EpOn2v$}yvU4qd;lNp2=VVa1xULj z{hf9>@&A){3EWi@pxo#q*?#^{5YZ~S-s(>=lqUp^_^~A^@ZXLv7HwKJu{ucn=a_~p zOu#vWk4?Xx{QDD7ECmsxgN&y6EdLs3dAra%jG$pxQ~AdyYl=<@HpO$!|0fyE0qsIv zRV!u21^!juuCvl|-)=(dav&@P4Pz^6yVT{89T&w2SrsBmM}j z{z03HvBh5eZHx*<&^PFi?bV$dz_!f1rcA#nC-mbmLF>V&QZ8BlIBps5z?INv!BXWs zA@uhrAT(+5Mh9kqS-M+}sQt2%mSs3Yi6murRJh~ieiyiWfA`7m@=sQcywpaePuer4 zi2rh>Ca`>g=yZ{#pUPoC(vR``C+{P(D-w(uW|cK*Mi@yk_y8%kK?>mR3RQ zI_h+z2tfBSp8?9*fD8uahKCyj>1qLAjm(CdTs!x<73Qh^EIRJ}%}t^D*fV-mVa(ZofF{p>aB* zVq?$nw1Vrn8kYgormJ1Jr{oR4M58n8UB7IGC24|&&8^<(EE+TD{3O@9jS>zYihEd3*+Mo+0jkP*= z@nY0gd#4it@W)_a5e35J^0F;mlTm6{>n}>aWs5p~wYUJkQ@AFt&VkX%yQjj=JN~Vo zNqvFX03HIb++youzBpKw$iwDWZ9?mW^EI?K1-DlXS!Y4O_bGt7j|=d-0@*%t#8zWk zx8}9mtZ&e~!>*xYchObziwwK?Y@PH`3NYx7&o_Cbl&Gz106yQ&Oy}m|LF%AcbimKe zXLk0vsrJ3*6KhvAn5?Y`)UD68oXFaL9KA0Y?`Ss z)5vaZX$B&Cf<8Fr5sECObTBS$0MSy@jrGfyAkp-6z{TA!JPSSoQ6^+K9k;?RMNn8*>-)dfwluUIM1CcNehkBl}@{|QZ7 z&fic*(j2S%Gr=5I>&6hn3a70J=DL=kw9rjRF~M=z3C}Uu^#HuXKM2@nov8sj?GC_a z|Fwy76?Xs@=&Wdfrf$x&Sq?gZAgQWjT;_mU-nu$q!|S|C4@_JOj7?7Q5Y}WHeSmbx;Vy9=BN``y;UG|e0tWhR_+(nnYqk%+>7=%wTZaOl+sfG1T zWKF-(z7FLtV9oVhu2&NdhAV?cNb2HSfH3^!k3J;4_@fQ2IAPoG8wdorw2i18W{;ISW_Ys`A73@M_qME*?cwHpbkJ098bp+m#ZV`;-yaH^b5sL(oz!vS< zR~BOkW}l$}fnNfuODitW_l=z^k-LvOJ?@LkF-vjC1L-n3aj`WOQlSRaa4%fX_fHpQEu_Yv?OQaTiL^24@)}s zy|hMPfrIgH^Hm$40H=PV9WLcSC;ct_QGH;v@`pwxw&N^PXf&alyqYSTNPLH<{i2{( zM%+4!<>S2UyG|RS2M-8jjB{O_Pn^nQkJivy%0E4sGLzwDC|`v{I&z>^n7d6XUu^lU zxRd8d0S}WokQWsPzaIu{?RdqVA!fQ%Tbb|A9qk?;)>c-;18Ze%gsS|+0C ztL_bu@QsVH5^SwkfVJ5V-IEn<-(M4;*;r=K<0$nd7ICUvn97aRJySER{|4xhfI1a! z-qqrmex)|kB_xFI22wi_>r1jeuXDhG|&;2x2T$vLyT`#Iv9F#oT`y)zAnZK4Ms? z2#?L^Ds`v)Wlm)9B7QB=>yR*QK$ubosT-MvVCey*gwVMGjeRc;duGZO@jrgr9}XtX`m2j$4GQqBRK zFPdeCQ4?j3OP*o`vbp1_58?4>^{jJA*ZA&2&T)-9{jmlBL30g`oQ4&yeq94GoHa9L zbbd*Z1ny%;c?%@6iix#8hu45B^X7;5beurs@u$j!hN&_3Mgt%q2ff zJ6sz$1%`Wtoi=}o6X1+PR{)~7Wk5pc!$cc%oZ%N&+EHrHZ)6RB_qs5YS1=#U_Ot#s z0Rv!9$hO{K0Dz3DQ(8acYIATumUZ2V}W1%)DG0C!YbRv7)6 zs4l?(rdiM7`jPOTNmRq&rH}2I-~RZZUdLcy58>H^Jiu4<01MjnAC`jv|GAdhS%#JrNQO*`KGklHfZtU=ehZ{yAmfx$QM%h7K@;FnW@o_tl-cwZlz*FvX~TN0(~rvkni+-x zM`0%L{6D`4VbafR=0V(Mz@^%t?uTrDaa0=SW)Ab@mj56nEdj>a^<`qH{!d>3j}q_& z?*E?%=7bP7pu+fp`#cerstQ21XOAli|9kf(1_U3^xLbSuZdXBQE6Z>=AcgtLNN~m( z?S&zq*iH~z zoV7B?h6AL73V?}tq*pgSXoJ@>7L*}2W`_p0*zb>Okju-)kima4_2PCa#U`P2F=5N~ z^IIYX=&voZCcd{a54H;ttgav7-b>Pdom{|(cH_D%dC`&&7&nE*C9b^Er1^%Zv>tWw zk8^U$jjKvBzaZ7`7|H^wQSFfW0aDU;WlTiE{kQVqQ=<&)cCzt{sh&2_n~ zqHb)H;nIGtBb$f+sBW@pkVuS|@!bSlumgIO1=)>==2#*>b~i%%?6{wqu0NhN0aQ(e z(;6^X{!)z=Hz#_-p*VVfv=*#Av#^n}v9xe>^0hV$zPT_q+<&ZS+*g%5_)D!)TC^m| zMg%Qv2}p3eeQ}9sX^Vx~h#V2MJuW7)6NtvpYBVwKN7TYZc8m4x$djbs-`{dMs%>FP(H_5s zXufBN`nth3RLyZP>w?Et%inRCdFng8oq+mo?Z*TLnp61(xrl9yb|l6jWely%@ZQRc zl|}hxXJRSr_Hky~_LkhjsJ4(=I^T=(g9N8W0$(BvJ8JL#2K3IJJSD5Zv_PI zOrpY*0Tym39fS0jfKlnLRi8K4-Rj=I)BsUsc4w4L89?uqr7|W`?K?I+x7Ad<1f=Fq z99B0DrJ}De%Gkq5=F6F`9=*bIsh^=Ub>DiowsDvCF}RUXKYbpxIt4t zQhWdPfvIHvJR?_a`tk!%-!WBIr#}!bU*YE=X1dQ$DFG<3Xx-}v6j2vZ}f!RU{U(%3kHO7J8oTPkp{Qc7&&D)UQ;}Qd)Y!3oid5K^;yDe($4yN9r20pf}{A-DVhC5A;|o%-U>#3$8F3Z0mHI(vFijq-kO?hQQLN~ zwd8C9xNpCuRsh5OIX+19ua6Q)(>~x88IXv-DT2cgVSIcLUaZY#lX3S@%z(AqzvZUl zCRAm~p;m1ma=^OpDL|QAbO3y@DFcF4YJima!4us@b3@OBj{gIzR~i4OuhIhOt89|m z7sLq|Q-^OlRXHi537;#82+Id*l}Fro?0iE97l(SZ<{vq{?-()jD1*o%x8w3zx2 ziUs{u+sWs&%l84f97Z|nw4|&G4dR^aDW)WLXTW=W#CgGkXnCAQjv~Pj-`y-q9(OJn zPyr?a&^0OrsPFX#w5!VqzRd->p(;Qp(uGIiyvH}I5^(eX`t8uadofOe*)8ce2~}fx z*e{`gC=T{0;CDV!8wF^<07YITthp69_41(a9}oUPYNZFH->+%U&E^G5@E5gf6I=Zk zUfJrZkMu^_*GdntM=LNS>>-13C&g!7oHjOS>*g{9LPp~j!%M-oX4&DN6I+_~ZwsRw*CeBjfsi>9`*?)NwW3%{WW zj&G^KN>e=lfmv~9*V7HdoYP6mw-#|AR!;5b;ivQGmIu*5B0L34Li6TcVl&fC+xyte z%u93Fw;#^?>{0EZmYH=2_jWTBos2ye>LmpwB?a~FNY0J=RXo^!sXfv6t$r@FRhDW0 zxFo<2Szvs*m5|rGLcdq*a=C4M&Gd2FCB1+QUvE~Z{4Jzf2~miT)ywk!w9iVuZQH3# zCXDb6=TDT|>Zu^)yF3_ivhBwF5B^>3P#NG49Uq8nafMs!7DVn7>3z@%30Bz>M*AY2 z#BW1h97qFq^VoF^7q_*P7`QG`X0nhLblNSaej!Q55$Q!f>@Dq49OdGdG5o5MoTR~j zdehVSJYD9ETkfPH9z>amF1_r5+HK5})1EA1lG_tx9K|z1?P~VU$cANykA5;x{}93yMsYh}*ClhNZpf{;f_12=i^sm~pV2-4(*|(||3j$9 zt}9%e$f;xxsnd8JCfsQ1dHD%X@(mKm-#*^2dfY)f$ha_4Qj~dh1Q*xv{*nAq0P)h+;&%a2JHbuNAVYuLjc_@=$t6^7HPx-}jLnvv0A ze}k9eWOp!QN0p(T2Wq#j-BS49VDI2yr^-y>krqV#9&Adc#j#5g|NUTQ$fBY%J8AWS z%-l=tCGyO(&P~s=lbV*xAz=JV(lN1htE01-g{zYx8$eQsnUeBwt77?5r*WC0!^Uaf z59l&xUWWNMR~I{0(lfut;8InG*^HNOkTk=dPY?TyjkK|s_;g`MI;k=uo0R`t@&UtR z9@^^kjHx!ceNVL3@DSkMEIMv|zHD0rKQDaok(%-AvZSy(+bbHD?!qpaz5gmv$1(vpCy@+tnLAJgT}i zxK%CaB4U~+&Zw|=d$ulb-^C19J)1zOi4ts6efN|8pbs6}v=Nc8IR`2V+=D%77{x@H`dOJK@6Ym_*t;DM2qWD?Tfy zS{+y8y!^EAfM&8TWB#JhU81-9nuEh`=9as~aTd>!D_)T9qz#Fm_&FeSHl?APD&uGs zB+l=fp12UaFQm9qB9{-6i}r2Gko!c2uZeGXQb)uS*BeINbCO!(YssVf!CRM#~@Li$pIJFHQV3y-3Ari3Qd!qa^uwpU7SAzy=&8kKQ(flz~Wban6 z^rWbM{2Y+za!?Xu3ROp-4d!5~x8PrRCx7$^!k?0e%^u|l(=#Xx1?fs=T7VJ&(H*3C zhd~)Y(2oh`y)7!e_%iV3G~J{4n=jVWe&sN%-jEd#zNrR2(tIy!J0i?D=ny(owZRvogKp1*g2_{D2eRhj!uVC~V@fj{9cC2w~APw|IkI+{5aP5B0)=06p6nZ3{ zIHX6!Q-c`~sby@sIs^(C6rq9kNURG4OKnyNVTbs7#HiRPiIDH>qEdg%CkgCf-~;8RKsm+ERT72g}l?*tfRBT?CqrIK1C#nAMfsZ z#eiGawZ$*igVJD&s3u{zLme~IGCIj$jFX8}3qP6taoTLIH1y5h_;VbTPJw-V1#Rye* zb#@TSYuIOg(WFAQ_rtdfCmC?jqv>(kr{JSaKq+d`)^``J1Bd_ykCu(}Smzt-!wB&@ zeu?Q75=$2*RgWQG#f_4Dt(2xy9?F?*m_IHag$5y5vx(vW^042Q%+B(FcvfCNuqTHH z#@flo53bot=)b8rDD0s8iOKKo$Y}_j^*Hv~y9Dwm`85oobrx|SY$6nzZ5EJ9@uCks zE2iT=c`;crD8+gWQ0+5Ebm+98$Cm`%3W7;q@Ogb{M;4QV@`E+@VK$rXR%g6VYGk_u zl&F=I&{!)58et2}*^->py`ip5Vc>ms0s|liH6eR+x&h9HU{kQUFG&CjdDeOkm?J+W z<&DhiO*uY`HxD3--XUYP5`YfWAZ2V>%4Cxc{!U?B-6L1r z$Vi$$sWIg${==?Bej`b!gy*bS#q5Tjj4SCK7mCgA#ppAF7J3t@kipa5TJ8P5)B9xjN%xtV_{kolVHw3Fbu^%l(oF=Q=9uQv zb=E{3^hgaSF!#(ImqMwCFMR+(MF}?j+!q8PuVuC@|7SvNL0A%ZI6Ey*UM0!23LXfQ z<%W}&oH1WT6j+n*k?U9cYR5#7FK2o}MaIKEol$$;Cc6(lwBtGicvJG2G5<6AYSD0+*MTgGOi$w1ioj)%= zfOpQhwoZlG%ru(Evntu>Z3jjrBlR;?EF${p$6O4H)o3%2Y@}=~mA`Wnl)n5ditO*fT>T9BWFO^Jzjw3ngf#+EIwAQGkPUKRfc$zWhURB zGhzXd@EyNwGElrVB^yV-HxyEK|{QrVW}1QfkEn!nujAaQF1&^R3(yVZ-Y zq#}LzX_LKy4LG(jPzR+%vn%G8LClfZF5?$MHSC)Micjz$2lt)}3@6Y;;)dXH$*Mc! z1$p1p>;0g4o+zYIB~SGvM&bp_luK;j_h1JBheKNY3#@cD!kea2@}I{-ACGYN1-t^B4_yw7Z_n6Zim0mIpuwdL<) z2HkyZUx=3tLsa>}?q}#(I<|NLIFYfQ&6&BMi;4S;oaH})s8B@e~ z=NB_!J9htZ2IKCY$o{UCWz(x5iRoirXEEvvV$Z*a2HMP&OMj5jIkj8w(kr zAW)RRCwLRK4+wMK!K3GfBqWv~89?=9_%S?B6u^!=0_7M&QY$aeC}9Z#fZnW<>mJ41Ty*14YD#EM6@`+ zo>x4x6_Hw@8K!>J4tt&|x5&n764y5dr4?1MbeU~@Z%|5OH^fA6ft@r;`I7-Ze9$?h z=YsOCs8&fa7!vqKBvRmne(TBX8MPh$1u6V2vs$erS!NL@k?86xPZE}>+mc{?JW_mm zW3LJnk!*KC-4fz@-ws>0Jb8De9#K6r=|YCTx-nRDkmdN(O&QqkK=H$=pu|RYZhy6s+ZUeQJhHMUoM^~~XaKzDf|A{3_aEiaBBs<)KJ|oG6 z$F^ue87;yNZ`#-ts^j`8`MC5voK8P>mQJ;AXzgBce6i~k8yFF6Ndj)W3s&x4uAPQn z(ZpBB_w>!jn9uZxo=kkRyg-`Zj2ij4pz2*lV4n-Dyt_5>T(qo_ERw8~qdk>)3&Gtl z8M~*B29^|@o34tw?lNqyJdp6Kw)Po)Z3E|Qo1YSa#f})M?8>xKbj7N_TerxsKM;kU zNO>&YjIV?&P*!h>LG_kjt}xGcHtjcXN^U-b^9|GE6Xz!?aL*N ztxB)6^7l=)Q=Tr9;`46~Z%b!0`md|c(M>__%yVMN)nJ4tf~6#FbY1h2z~Ne#5v#ck zx2^%NGyg&nJcLr2J`z@BzuQ$a@!{^_d+9P+US7xaUqe>UM5dCL8Ixod89NQ;Jve0> z;tG09A4MwBUNICKzC0@jOg`^?D$|?ol^M1>8?JAK2_972s!X(Xb~x6)IaTLEi+A?$ zAskkslVrZ1`o?NT%j-Lwf4tsPV-hjJ$0^&xobi}nuko?J@+QaktxD5ri8b8a_#C_% zLp^P@_!(RL(oVp@buRz3clk|id^y$CYYB;%WU(b6VacdA>}11splY&$xGn=VI(od6 zTi|#L?8;tZj9?YlGOKabViCrJa;fsw*hIWn)l$O3wF%+DDNn@?fAkFE!7pyPJfZBM0sjNtmUE$Dn<)~dsKn`*3r-Nqs$^*l>zHBf^e zY4H9sK;W$^23?JcaB}aC9#Ap0)78F!}W>T+`e=A|r z{puGovsu3L{2+N{;b|!c8*^vNflDv}0c@}E4 zwS0GIZNI0zeUGAc*j~ANFcK%k-5H*NfU@vM;EAHR&^d#7Co$<#KeXsYf~#8KO(x3f zKBb#$_xLSU5X_Uwp#DZB#$fCC;%=$5c1<5m=hD7LSTIqYNphJ;+{tUgW5E^ap7|*{ zSoPfeqpNPGxF$>9_SbPuZI*_%l{Dh0D&ZAHd(ErCv+*YI%dVd zXNB*K$l2wBR@CoEVzR~V$Gl1M$+{VNgXr56O2)4(K0JV5C!2yQ`AKQpd$SArur_^q zHgf6Z&-~_$%ks1Fv6kv-;Z!L5cT0KAKYJ&obCj4wu*91M+mK*#c2c^^GJ-e3(Std; zhmCWd)4ncDB&Y1==HEHebae|6y8^lnPWt93Vi5Y&F|$%{7~|Cw2JN_ffKQa#Cg^K+ z{xf}qByp~}Bi-)dX)(7Fenzo(Ae0p18&U@Y1-TCdgx7b|&EH#sg2zz%8Ppzn5`}|o zq+`RJ=x<-Dr^1sfSI_BcT|DaBIaOYK=eqjGuV~kd{2Y7PxlD}=|3ZweGrQl_#_jt% z@KLO^{q2_bjL#`cRG98N9>uZ|bNob}+}+sXUOXCYHoK6{{K)vcIvne^AMkE)2`O<9mfLnH zX8D4T;CGqv9=qN6KxdhAE11cu^oAwN8xLh2rcq5F#D{u+<#=CS$l^O@^~335fA@K* zOWzU8kO%>Gh{+Ax$B6GpQou>P-k&2fa_sv322EJgql6Q2uPWU}91CaH>kT%^qO#qJq?C&9bk zH2vqoA7uD5Y_TBPG2|^03LGqW!YihRrSqPusZ&N1nw$~d6N;$s$*_~61w{Y7>Ow>J zq)%-^=r=^e2D%(n#in*+8B$68_i9zuecDoBCmU~@(jWBF6yFJYC#8PpaazJ?u^FMM z;J9M_N0qjeI14y`Xza-bAc&OCP-h}Pyz38ze}fIXLOAle+D%{ ztSnT*M9psLs)fhA&D@#lIv zFJd?uHf2G>$ z7adBYbZCJBS}mQ)%Vsw36wk`szSsBn#FOK1QRyFwS|H?h)f~J>TPM2$PkP@`Gy`Xk z=I@4T%X`(U+~XTl9HbX~;IZ%>&Yz~fWKEk{L%x zYF20$O&U;ZUdRdgMC6A&Eu#7L%DC(xhaBIQ-A39MsF}^p!+^3`37Vn4?b!<5dD)mt zd=YC<`;?D_RbI!g0?&N#>H8ur#Am1{-$g8)q|Z(;Osd?{Gr`oO05Qs;>SRX3o>slR zzu&e&V%TAKEO5}yqS`=?FEdKe^)#ILVSed&C=1V2@g%`5H45@)J&^EDYBm($p;2W^ zx4Qe^>M|jlk#X%`t9A55qB3&%A;~fc#}!$8++5HtaF%8R+)q^1o5hYUOHHCL@PHma zB9*9|uvV%Fxa_&B74}0>g1Fbu`#RG<5=L8WH_0uEu(T4~eq*sI>TuXoAv#z?U_naX z+{aNl=o1p0tZ3`ot>fGYM%ww$)EcG8I5zznl8#XU7U?&3Qf(fFXH5G62$}__%KMN{ z8f15mG;1{PsfRv$or{O79^PhtLGcu-%G7$3d649$@@pp5UEd8gKvp5ylhUP+Vmsv& zd`$5aZQ@7EN!tBn+HFN{NX+)KG^1S5X6U7?R6<4}+_v1xZ@^obSRL`R_hV(Dp-rlr zZbMYFUdQxwzF9_^&V)Z|leLbkI7`yb5;e&ndF+(mdKYX9^=Ec3SWgo(mE-jb$va5f zVl_-oc}}vBHOPf2?2c~lK33WTmY#Z0Q>aA;#ya5^J0f2Dm}l<9Hh-h@u|Y0#?C`h< zxTFL7=wXknMAISch;wD9HIHE$G;%ZSKO8Bhx-45;Pa(~>yK5VL+( zUCzGl?DoP-7p* zmxZImDyDrVZ1KuFVNs`D$tQ(pqRpW#ks8aazRf@giiR1&e}d)P z6`i^3f0}{xsA{Mu@1T2ZmN)OI=HLs&qy4HO^AFG5O+SB zL!1`*O*HK%oCwzPDl@I#^FA{u%yux-m-5{r4(YWSo$On>OV%`Da zp*A@iAbH_rs_^5^*;Z0yqXguM=QgzP4iD8 z6npT=7pv8=Dn`q65O#U@$jCGaxA<|}n?;jD<@MoiHn@8N0f-i=?(TStuDI~vv)nM3 zFIC^T4`5TCwk}&-Id-n+2c0<<;-`ofF+E?e{AHKHOh5f)E#an8MEEI^gA}$eQ=7m< zJGW&B)|q_9v}zFbh>eRtLC<*t%!-ny+m%0KQhjzfPiFr_v6g3{_{Mi#u z>qaDZBITT{X;b;xiEZGBgWmJ_F4~+4&Q6)WbII*xPf4wXyUgFaJtbpjAJMX8hnywo z6n1QO>~|+gua*-xbix9SHGI$;cZOu*F7lUOiM<`&7EOB^NA#V~&tN=b*kIvAz**Ce zjk}b&%hf;p-5@np99dH~Ac zaXibUAbi8xh|6W&G1_|Pb-twC8}6wm_TT1vEr}U#UQd{5p1eNd<>@Z25_aEeD!f@| zpN@0`);_Ld|7{Q9-6km@>VX$GQ+$9#F~oGdr<{Y7W)gt#c4sB`9v3dWEES0G;CZmF zH*BEKroTr4xa`sRQ!lBmqiF12oEy`z7ayNvnZ4|~dS4<^k&}Ut6xm+PuWD_iAc?l> z8UQAI=jWucWhdx-zgY$FR`eH#Uqn>(J{paTEi3=^7aj$MfYv^Ud+C($kZPHH%1Oy>+*pO^@m7LLYBdCtLSKV!;b?<2%>LMVNHpf8e z?t!~c(@&WQv|rscm+?+zs?PZ?KU%836nY@Wtc3A-ZZk9v^%{2t<8FLrDgNvsBDMm z*86vAGkMwvrzvXj*Eutz!@%*_uJl7TXPsL7%5&?IuCZ;=+FeCP@`Bd}o2B-8!jQ$I ze4_illnzzQ@I^f;)V$svDP6{zdT?+fPMb$!^mF=&w!}Gwr6(v)|JFGXEiS-?KFG>+ zvPQ*rXZE>CMS6+jDTMkVG*7)Y_ z%i7-OrF<_=N}ajF#4K&uF~51(q0Y1+42#7xK#7Wcdh;-8KrdBhQ6o05L~a>LpXQot zpG*Mqn~Fbn9o-gg>e)^{eV6Kfle8VQ)VTOP2Wu5BqK7 z#XALmeKSo05K0HrnZG0Lw;;)pfw976ZyU-=dC7o9LkDZ609@lbB%HSC8(oH*mV(dH zJ;@k6zk4t(x`OLryxl0rf9k)F;jPRxtAnh7b^yUs1*Yb98tA5kEgQv|n zR?AukrF9Qzl(Y#^aqfLM{touo5W)ou4HZL#`?AsO$IFM%jb`wyPjS^LyV3fBcXNA0 z2}Tb_vhxx=>i4yzB+f~9uwzot8oE1^AoIy#_ZzaHtDTtUgpJfp^49~l^SdYa!Ray) z49C8%q`4qDq%J#zDH%NgRFxp)qIE#V`r}{`IJ4+gCz)4>cKvdaP$GqIxvM1`VnfUY zy%I&sf&WJ;KNXG}MbdpCXNEn|r@V|PueQ5#;s+1d);jr?*GN^g^=&#PT3O9&)3@cH%<=0@x(wz$e zjjuY(Pkg@#`4>2h(BqrwgexPK`IVcoJ12dYt7|osmn~6iiYb2U#D?X|uTkf-9J)}M zQoRjgJ>qia)MoSO;=Pn;47dF*mt$6qC#|;K!G|dW>CQ9rOP8Wc zEGNMhE-Vw(&Z4Mh(HmYRK65rog_X@BKhYc+6LG8k`6XhfbqD%22|}-4#R>Ty2^wGBe<6(W1O9EM(e5eoJ-B_Gnsn;Prw&P)MiEdiu=8Z2HM* z13q0PW6tuEilxr7Tu$kYsPD1Q?*6>b)#k+PMrU|Sv42UK&2dcK_x=|0%|-~}u3Pp) z)Hp!6fRUEgzWTzmfsga(2jw2LW}WI$;HvKZL4}ZRE?hVVENvfAu{x*FU=f*Fx&htO zJDRC)TGvRR_m6;~tEPvH-B!oax@ed`+vtxiy;E#n9ox-m2#krlz$sTWnv1I6+=R?B zg@O^siX#gbpWZ#m-S)oS-j27~QF}%hhUV9TUxh4I9Y6GGX$sSDPyd{*5W=zQTH^m) zGF9fyNXg`1pM7iJ6BB82{Mrvw!=`tgV4lQ$%59slN5@)J;H=+FquB&v3+LK_YtPK7 z5gmCnqwzr2hcTp$(}DEySyX)WVuIOo*pKwvo_S)Lo&9FUz6DL$n{HX>xX=Q3Ttg*0JS9sJp zx5^DEC2UJR_Gc#rKc45{NA}XNxb?%9!^UV}Qpg@I=SA07Yr5dCI#rtZba)_A;*c9l z{4ElD9*Iw6zMYZTRbnBG5XuvtT!79e3qs2b>xV(5!WiBKKR!q@75Q87=1c^FY{l^XY^DmVo2f)50SjjD1<8 zW=hcHQh#sf;)H}Gb2imv^KPpE7?1FS_kTn<5j}icee5NREaRqs@7ceT@X7Igumjh# z^5y+1F-;tgxQOt%#FqC@i1ZHjjm)tSLp@$_YOpJ1 z5@l!}{$W?o$dCJ3>kUHSq4kDf(``9P6cor2%p4s^kVQLbMR67qK zrBp}NiYK}pq^ixN6?W+nGv?S|pZyM>h6e{WkdSgL2-ev(Bdl+8vYl+7vSS_x)-L)@ z;=|CCX2N8a$LxL)h1hk#kA7R(#V<@ulqaRUwwe;Q9mWz5!{*`_N^?Q&2c;XkAnc%y zT#B&O5f_$ZSa=`5;?Qwo>_JlI10X4cpjIu}QTY_z`1|9N!)`G0KoX8EY0->96`9g$ z;~b=jbzEiQ!az56MAvk(y1Z|4~X|TXAf$r1Oa2a|DdLhDx<+J1fA_;oD87iQse!haL^QYE zDz8bd$1?xm3-ah2S1YFJQ}2TKB0_yU<>QBzLVn%KzI>&ziOjmnOL7yLToQI!-GKQY z_0~17RgVY(Uui@|>ujw#=W?cB%FHN9b$sC5u+ZQZd0U$z^_M?y%je=V;)i;<8G{tg z&7ZLyi#Zkj^LyJ9-Q-f2?STSHx#V_+h>;8;u5M8`KW=@%X#e?^V3}6z453l<`Zo0L zcFKZouT=qp!-{^$dutazKF^H4iubkTc*e2oThy?3zM(}sx=7MbPs`r!bFj18%8wFa^jn&T7}Z=E1EX5!yom`ziI%SZag_nC%8RR&`FwT1|LDrv#z=; zpo2xEZM`q_*IE2FKh{ZG3KtXQK+A=vR>hMro;KIxLgUR9lPBC)t*-Pw!9>@Tsy?V# z14QuVvr=LAw@u#{9{jhLJ1O2!>`>UJ{bBx$oTBqeR==!f;clJ$wf=VMk$>m|%1ChrDN16nj6DRp{la$c?8ik7{ZivjCFGfg; z;8n%PIbs@j=sDrU-Ezh7Lot~l6Ph#|gOz*1vnjGz=gZN247fVtnv*5i#LFWk$ z*6kVvk=vDS%4KmGZWDTj+j(vW7;4TY5tz1@LGxx}X$E4fEaNR7l&Zj@A|pxX$2`lU zk%?e~O=Fdv!X?dBb_1M+KyusO&^Og~l_gbpw024Q?`^)5C_)Aw$mQDUwm+Uq*q-~2 zVa9m9BGzCQ59PA0glBH9U^I+*0YB*8Z$D_6$!(FhB~5J{(1{sahg!$(1;8OwW8ztY7iE*0FI86_b%;qhHez>#N=_$Z;xnfz+wI5yh+DA87vdz6AffRr2d(fa*MUB zf!Rwek=w6|mn!y4Gd%Cqw9yo1ErZMRJSc#Yvi(Bd%c^!E*~<=|ETR(jT8&D?*X_|P z;VmN``3cztR_D`bMRzTqtoaGEXyPZsjI~U<^&=ViC4lmh!idqa^X-lh+T+?@08_w+qGggJ<-E z9=aC~{2qm>8WV(#L-e{?e84DtV5#nE(BP49FSMrZ^|uyl&d3`mz@yg8 z(?(7~f#}CVgz?U?!)j%Z|G&;O|7T3Cm6P+mBgxmNXtpV+m#OMe4aW8L+xR-p-f0~v z^f{~k;Y^gtjthDF}G2`EM1w^^gqA#-<3zij}G41=ISYPQr*>J}0mweIAPaApM@fBsS5FEl0_^ zJmQ2=2EE}UdAYvh4dr3N;`;pmFhF=@;4z;~S{2WB-f5A8`%EP4>e!hGwM2+`#&~S1;up@qz19VgA zc<;zD)1|&RRTut;4#@+#^}DL9!a`Jr4M6m|2mC>>r=^V6{Ly4fk-0;uwO>F<0PFj* zh&dR@XVl^HH;?xB&O_$`+JEHBU&d`OxPGtcfJ?MdmU)z11*pPouHGoai_)t&;CdF# zU{8BRX)ix{WZcxR+;3O)UW&ItYR`t#?`U2ONQW;l`@GBe9Jl=2-QWfJQbX}~tl|n= ztcnxzBS!H6W$(i$&Y$xonA7LKufzq!3c99VRlj#DGYl85%6LsbZnTHc7%hzWhTD#E zr)Fy7p=r_K)(&W!U?#DL48Oc<{zDTC_=~&%SD~a3G9kalFR~?O5L_(Thcn4#$LRCR zr&hmoGgZGv(iw4!Q%{I;jsTR(@RbF!c;|b3((YHAe5nCtD_t3O;;IuU@SB;puR@Yl-8Eh;eq z)M-`$)vp$R-Xg^e{NRWEGob*W-ZPWP2>m%6I$qqtKoQ23Ez`dX;(IWFt-SxqxB2ru zaknv#XJFMM2w4$`8;}08NANra7|Hq)B41zqy|Gjl09U25r3HC^E|FIRE(w|Xp?8``T^B*V$(C9sqV?5j_Hy>KJwF{f5{Lp`*{;VZaKk@m zn>ie*7ow@|ZfX4;IY)^*rPV8vn5>C#;#YWw``xgr06;YwJh?`=yd& z3#HokZR+gW6;RIEU^z%D^k>5)>H?@OO3N#_fhlI|QS2DXT}VbNbq+9cTUN4&Ws)0y zq!vHsIt6GbP6_9unOBdgN3}}4$J?fITot-EHb3}lPHH@OLG|BE@OjdTeh*-@6CkU@ zJ=bZ-`=gs@`f*C3dr_oL-8Zc;H_x|zW5kkuToVo?Y_GLsWnPK;jjg8`)Zz|(BKFif zhbw)w3ASF{pb4s1)~S6%V)e-wU8~$}1yrOrAyw-qrrfJVD9B8gZPbeEc*f?18`8}qB?+jM)fL(TC z4bB<_`1!n-Ljk;S>`*jkv8!=BA`t}$=3#uF7lQ^qql*5l031ZAr&7{hDl@`YzsC%DVSdHlue;}XO(vYFL7zQk;&Y2js?%_kHZjMWsI3;k@x*i~tKq3a~oged4 zuBM8*B&v$XLH9K`kp@0CYmXSii8U?=z=;R5nk+~}U0QX${k_p67j;I~3Vf(;wb{Th#= z)&hDicrXDVgyWmEt?Z3f(!r(!p)s1=r+gIX5Qu5(C7uIEwF~|(E1}BtQ z+K`ELzHGK`ph{pl90p!im@aygiJ0SP5;oIQVE!N;& z0gAx1H%cXV;mh7_{hw94r|z(n1Rf4d1wI|x*19P>YNXDuX4sNnj4u3ZC8tP0wv85p zmBniofo_BKX~Wu83PZRlZt8xka_u>*h~u%Rq;+}6BlSg+D3%h$VcM-*1~cC_v%&Dy zN<|Hu+RyP5R~c$R**iPbW+pOEju!^;-&{$di<8v>hy?1#iT>S24a(gu@c5.&)( zwmFDk>r(3(Zl4BMO^y|kQM>9I#~HUBI|-`kGudfcI&%l3o@SCC^8*Sl@(sSPFtFSP z`Evbg4E8AgQTS*N!!@OCO!%bB4iD$IA4VksHf6wyBJP-9_Biq-27e9_0cPbm65DDA%NzrI3 z+JS-H5GG!gcJO)c|57o)kvE)!-dGS-s()Q=x@g&{GbA@01?;T0`>waL5yr;)Af~y& zE=P1V!iw&5QueO^TWZu`ef(0f1ZJZ@4H!dnX+`_FlMO`m^i0p?TL*GK1D#2?wG$jo zx1+dFo5^vvQD;{};FMn{3LgFDC8_8>I#oC`UmM@#K3WZrGZLMwF5fo$M%1G7W&Ns;iow_&p0~6nPYEqSeBhbTrpm(wFfrV8^yd{gy)UY|J{>@A485G zo~KfUVZ;3C*YNPbRmlHi?7gF!THokT1*C{lr6|3Nbhw1j5kx=*R78;8lwLy*A=0IW zVnIVuK@g<(-m7#$5<)K~Ki~QpKfATAnM3H9yH4pKu}3YJ{S1k zRYtUU5hWHo^7ub}2-X2EW1c_Wmr(h?$-qF_-A)duETyi}zXL45drLZj7g@(rh(y{@s+Gg$kH>=vh%m=(kj5F($Xa9SahgKmw!~tGkMD7^@0{JFl zo(Elj@ePht8{YI)PA?ZP5~=<`_zQnq8Hx%HEaH>v%BgNFCAy#QqiW4;i@l;kR@hw< zVjAPS;pX)(jNE8)fa8$zAOCA|@hfSy;BlY7|2m2uHb5%>xqWorzUS_u&A_9uXJv}| z-`!AGUKv%C=%kbOpBYOvV14%0D8sz84odn-7*0O$BessV!@{JNm5uG1%+Z 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�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 literal 0 HcmV?d00001 From f11bbee0afa9579362bcb45bdcdda1f821d8253f Mon Sep 17 00:00:00 2001 From: taehyeon Date: Thu, 14 Nov 2024 13:41:06 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=203=EC=9D=BC=EC=B0=A8=20=EC=99=84?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../3-4\354\235\274\354\260\250.md" | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) rename "taehyeon/3\354\235\274\354\260\250.md" => "taehyeon/3-4\354\235\274\354\260\250.md" (74%) diff --git "a/taehyeon/3\354\235\274\354\260\250.md" "b/taehyeon/3-4\354\235\274\354\260\250.md" similarity index 74% rename from "taehyeon/3\354\235\274\354\260\250.md" rename to "taehyeon/3-4\354\235\274\354\260\250.md" index dbad4c7..8af7d87 100644 --- "a/taehyeon/3\354\235\274\354\260\250.md" +++ "b/taehyeon/3-4\354\235\274\354\260\250.md" @@ -56,22 +56,37 @@ - 복잡한 비즈니스 로직 구현의 어려움 - 확장성 제한 -### 연관 관계 설정시 주의점 +### 연관관계의 주인 + +- 외래 키가 있는 곳이 연관관계의 주인 +- mappedBy 속성으로 주인 지정 +- 주인만이 외래 키를 관리할 수 있음 + +### 테이블과 객체 연관 관계 주의점 + +- 방향성 + - 테이블은 외래키를 통해 양방향 조인 가능 + - 참조를 통해 단방향 관계만 가능 +- 관계 표현 방식 + - 외래 키로 관계를 표현 + - 참조로 관계를 표현 +- 데이터 일관성 + - 외래 키 제약 조건으로 참조 무결성 보장 + - 양방향 관계에서 양쪽 객체를 모두 관리해야 함 + - ex) 연관 되어 있는 모든 엔티티에 값을 변경하는 연관관계 편의 메서드 구현 -- 연관관계 편의 메서드 구현 - - 어떤 엔티티의 값을 변경할 때 연관 되어 있는 모든 엔티티에도 값을 변경 +### 외래 키 제약 조건 + +- 한 테이블의 필드가 다른 테이블의 기본 키를 참조 하도록 강제 +- 데이터 삽입 시 참조되는 테이블의 값도 변경 +- 데이터 갱신 시 외래키가 변경될 경우 새로운 테이블 생성 +- 데이터 삭제 시 해당 레코드를 참조하는 외래키가 있는 경우 삭제 거부 ### 중간테이블 - @ManyToMany 관계인 경우 사용 - 다대다 관계를 일대다 다대일 관계로 만들어줌 -### 연관관계의 주인 - -- 외래 키가 있는 곳이 연관관계의 주인 -- mappedBy 속성으로 주인 지정 -- 주인만이 외래 키를 관리할 수 있음 - ## PK(Primary Key), FK(Foreign Key) ### PK(Primary Key) From 71ce78aab67589ebf503bef73285c1df54e5caf3 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sat, 23 Nov 2024 19:09:50 +0900 Subject: [PATCH 06/20] =?UTF-8?q?feat:=20=EC=97=94=ED=8B=B0=ED=8B=B0=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 --- taehyeon/onboarding/.gitattributes | 3 + taehyeon/onboarding/.gitignore | 37 +++ taehyeon/onboarding/build.gradle | 32 +++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + taehyeon/onboarding/gradlew | 252 ++++++++++++++++++ taehyeon/onboarding/gradlew.bat | 94 +++++++ taehyeon/onboarding/settings.gradle | 1 + .../onboarding/OnboardingApplication.java | 16 ++ .../course/controller/CourseController.java | 4 + .../course/service/CourseService.java | 4 + .../onboarding/data/entity/Course.java | 46 ++++ .../onboarding/data/entity/Student.java | 52 ++++ .../onboarding/data/entity/Sugang.java | 42 +++ .../data/repository/CourseRepository.java | 4 + .../data/repository/StudentRepository.java | 4 + .../data/repository/SugangRepository.java | 4 + .../onboarding/data/status/CourseStatus.java | 17 ++ .../onboarding/data/status/StudentStatus.java | 17 ++ .../onboarding/data/status/SugangStatus.java | 17 ++ .../student/controller/StudentController.java | 4 + .../student/service/StudentService.java | 4 + .../sugang/controller/SugangController.java | 4 + .../sugang/service/SugangService.java | 4 + .../src/main/resources/application.yml | 6 + .../OnboardingApplicationTests.java | 13 + 26 files changed, 688 insertions(+) create mode 100644 taehyeon/onboarding/.gitattributes create mode 100644 taehyeon/onboarding/.gitignore create mode 100644 taehyeon/onboarding/build.gradle create mode 100644 taehyeon/onboarding/gradle/wrapper/gradle-wrapper.jar create mode 100644 taehyeon/onboarding/gradle/wrapper/gradle-wrapper.properties create mode 100755 taehyeon/onboarding/gradlew create mode 100644 taehyeon/onboarding/gradlew.bat create mode 100644 taehyeon/onboarding/settings.gradle create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java create mode 100644 taehyeon/onboarding/src/main/resources/application.yml create mode 100644 taehyeon/onboarding/src/test/java/jpabook/onboarding/OnboardingApplicationTests.java diff --git a/taehyeon/onboarding/.gitattributes b/taehyeon/onboarding/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/taehyeon/onboarding/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/taehyeon/onboarding/.gitignore b/taehyeon/onboarding/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/taehyeon/onboarding/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/taehyeon/onboarding/build.gradle b/taehyeon/onboarding/build.gradle new file mode 100644 index 0000000..5525444 --- /dev/null +++ b/taehyeon/onboarding/build.gradle @@ -0,0 +1,32 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.3.5' + id 'io.spring.dependency-management' version '1.1.6' +} + +group = 'jpabook' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + compileOnly 'org.projectlombok:lombok' + runtimeOnly 'com.mysql:mysql-connector-j' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/taehyeon/onboarding/gradle/wrapper/gradle-wrapper.jar b/taehyeon/onboarding/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 GIT binary patch literal 43583 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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 GZ~q4|mN%#X literal 0 HcmV?d00001 diff --git a/taehyeon/onboarding/gradle/wrapper/gradle-wrapper.properties b/taehyeon/onboarding/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..df97d72 --- /dev/null +++ b/taehyeon/onboarding/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/taehyeon/onboarding/gradlew b/taehyeon/onboarding/gradlew new file mode 100755 index 0000000..f5feea6 --- /dev/null +++ b/taehyeon/onboarding/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/taehyeon/onboarding/gradlew.bat b/taehyeon/onboarding/gradlew.bat new file mode 100644 index 0000000..9d21a21 --- /dev/null +++ b/taehyeon/onboarding/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/taehyeon/onboarding/settings.gradle b/taehyeon/onboarding/settings.gradle new file mode 100644 index 0000000..a4dc2ac --- /dev/null +++ b/taehyeon/onboarding/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'onboarding' diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java new file mode 100644 index 0000000..79b8274 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java @@ -0,0 +1,16 @@ +package jpabook.onboarding; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import jakarta.persistence.Column; +import jpabook.onboarding.data.entity.Course; + +@SpringBootApplication +public class OnboardingApplication { + + public static void main(String[] args) { + SpringApplication.run(OnboardingApplication.class, args); + } + +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java new file mode 100644 index 0000000..d5a41b6 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.course.controller; + +public class CourseController { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java new file mode 100644 index 0000000..45bc23e --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.course.service; + +public interface CourseService { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java new file mode 100644 index 0000000..5bcce43 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -0,0 +1,46 @@ +package jpabook.onboarding.data.entity; + +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jpabook.onboarding.data.status.CourseStatus; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Course { + + private static final int MAX_COUNT = 10; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "COURSE_ID") + private int id; + + @Column(nullable = false) + private String professorName; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private int count; + + @Column + private int grade; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 20) + @JdbcTypeCode(SqlTypes.VARCHAR) + private CourseStatus status; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java new file mode 100644 index 0000000..a090b89 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -0,0 +1,52 @@ +package jpabook.onboarding.data.entity; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jpabook.onboarding.data.status.StudentStatus; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Student { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "STUDENT_ID") + private Long id; + + @OneToMany(mappedBy = "student", cascade = CascadeType.ALL) + private List sugangs = new ArrayList<>(); + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private LocalDate birth; + + @Column + private int currentGrade; + + @Column + private int totalGrade; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 20) + @JdbcTypeCode(SqlTypes.VARCHAR) + private StudentStatus status; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java new file mode 100644 index 0000000..2006cf8 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java @@ -0,0 +1,42 @@ +package jpabook.onboarding.data.entity; + +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jpabook.onboarding.data.status.SugangStatus; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Sugang { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "SUGANG_ID") + private int id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "STUDENT_ID") + private Student student; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "COURSE_ID") + private Course course; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 20) + @JdbcTypeCode(SqlTypes.VARCHAR) + private SugangStatus status; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java new file mode 100644 index 0000000..7371b3d --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.data.repository; + +public interface CourseRepository { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java new file mode 100644 index 0000000..976e0cb --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.data.repository; + +public interface StudentRepository { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java new file mode 100644 index 0000000..c53d018 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.data.repository; + +public interface SugangRepository { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java new file mode 100644 index 0000000..d62ce0f --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java @@ -0,0 +1,17 @@ +package jpabook.onboarding.data.status; + +public enum CourseStatus { + DELETED("삭제"), + REGISTERED("등록"), + EXPIRED("만료"); + + private final String status; + + CourseStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java new file mode 100644 index 0000000..12856c3 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java @@ -0,0 +1,17 @@ +package jpabook.onboarding.data.status; + +public enum StudentStatus { + ENROLLED("재학"), + DROP("중퇴"), + GRADUATED("졸업"); + + private final String status; + + StudentStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java new file mode 100644 index 0000000..4d2ada4 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java @@ -0,0 +1,17 @@ +package jpabook.onboarding.data.status; + +public enum SugangStatus { + CANCELED("취소"), + COMPLETED("완료"), + ONGOING("진행중"); + + private final String status; + + SugangStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java new file mode 100644 index 0000000..14577d6 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.student.controller; + +public class StudentController { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java new file mode 100644 index 0000000..a0c4a4e --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.student.service; + +public interface StudentService { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java new file mode 100644 index 0000000..42fdeb7 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.sugang.controller; + +public class SugangController { +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java new file mode 100644 index 0000000..2ae4179 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java @@ -0,0 +1,4 @@ +package jpabook.onboarding.sugang.service; + +public interface SugangService { +} diff --git a/taehyeon/onboarding/src/main/resources/application.yml b/taehyeon/onboarding/src/main/resources/application.yml new file mode 100644 index 0000000..0adc2a1 --- /dev/null +++ b/taehyeon/onboarding/src/main/resources/application.yml @@ -0,0 +1,6 @@ +spring: + application: + name: onboarding + datasource: + username: root + url: jdbc:mysql://localhost:3306 \ No newline at end of file diff --git a/taehyeon/onboarding/src/test/java/jpabook/onboarding/OnboardingApplicationTests.java b/taehyeon/onboarding/src/test/java/jpabook/onboarding/OnboardingApplicationTests.java new file mode 100644 index 0000000..e018ca7 --- /dev/null +++ b/taehyeon/onboarding/src/test/java/jpabook/onboarding/OnboardingApplicationTests.java @@ -0,0 +1,13 @@ +package jpabook.onboarding; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class OnboardingApplicationTests { + + @Test + void contextLoads() { + } + +} From 8a14bbbf0db91d869fb4b8558686e4456ce24ec7 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 00:06:02 +0900 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=ED=95=99=EC=83=9D=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taehyeon/onboarding/build.gradle | 1 + .../onboarding/OnboardingApplication.java | 3 -- .../course/controller/CourseController.java | 8 +++++ .../onboarding/data/entity/Student.java | 7 ++++ .../data/repository/StudentRepository.java | 12 ++++++- .../student/controller/StudentController.java | 23 +++++++++++++ .../dto/request/StudentRequestDto.java | 20 +++++++++++ .../dto/response/StudentResponseDto.java | 33 +++++++++++++++++++ .../student/service/StudentService.java | 4 +++ .../student/service/StudentServiceImpl.java | 26 +++++++++++++++ .../sugang/controller/SugangController.java | 8 +++++ .../src/main/resources/application.yml | 5 ++- 12 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java diff --git a/taehyeon/onboarding/build.gradle b/taehyeon/onboarding/build.gradle index 5525444..8cb588a 100644 --- a/taehyeon/onboarding/build.gradle +++ b/taehyeon/onboarding/build.gradle @@ -20,6 +20,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java index 79b8274..a01fef2 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java @@ -3,9 +3,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import jakarta.persistence.Column; -import jpabook.onboarding.data.entity.Course; - @SpringBootApplication public class OnboardingApplication { diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java index d5a41b6..6211cc5 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -1,4 +1,12 @@ package jpabook.onboarding.course.controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/courses") +@RequiredArgsConstructor public class CourseController { } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index a090b89..63149c1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -17,6 +17,7 @@ import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import jpabook.onboarding.data.status.StudentStatus; +import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -49,4 +50,10 @@ public class Student { @Column(nullable = false, length = 20) @JdbcTypeCode(SqlTypes.VARCHAR) private StudentStatus status; + + public Student(StudentRequestDto requestDto) { + this.name = requestDto.getName(); + this.birth = requestDto.getBirth(); + this.status = StudentStatus.ENROLLED; + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java index 976e0cb..e736240 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java @@ -1,4 +1,14 @@ package jpabook.onboarding.data.repository; -public interface StudentRepository { +import java.time.LocalDate; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import jpabook.onboarding.data.entity.Student; + +@Repository +public interface StudentRepository extends JpaRepository { + Optional findByNameAndBirth(String name, LocalDate birth); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 14577d6..081bcdb 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -1,4 +1,27 @@ package jpabook.onboarding.student.controller; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; +import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; +import jpabook.onboarding.student.service.StudentService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/students") +@RequiredArgsConstructor public class StudentController { + + private final StudentService service; + + @PostMapping + public ResponseEntity createStudent(@RequestBody StudentRequestDto request) { + final StudentResponseDto response = service.create(request); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java new file mode 100644 index 0000000..956760b --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java @@ -0,0 +1,20 @@ +package jpabook.onboarding.student.controller.dto.request; + +import java.time.LocalDate; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class StudentRequestDto { + + @NotBlank(message = "이름은 필수 입니다.") + private final String name; + + @NotNull(message = "생일은 필수 입니다.") + private final LocalDate birth; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java new file mode 100644 index 0000000..a0ae359 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java @@ -0,0 +1,33 @@ +package jpabook.onboarding.student.controller.dto.response; + +import java.time.LocalDate; + +import jakarta.validation.constraints.NotBlank; +import jpabook.onboarding.data.entity.Student; +import jpabook.onboarding.data.status.StudentStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class StudentResponseDto { + + @NotBlank + private final String name; + + @NotBlank + private final LocalDate birth; + + private final int currentGrade; + private final int totalGrade; + private final StudentStatus status; + + public StudentResponseDto(final Student student) { + this.name = student.getName(); + this.birth = student.getBirth(); + this.currentGrade = student.getCurrentGrade(); + this.totalGrade = student.getTotalGrade(); + this.status = student.getStatus(); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java index a0c4a4e..9f5208c 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -1,4 +1,8 @@ package jpabook.onboarding.student.service; +import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; +import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; + public interface StudentService { + StudentResponseDto create(StudentRequestDto requestDto); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java new file mode 100644 index 0000000..57d53db --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -0,0 +1,26 @@ +package jpabook.onboarding.student.service; + +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import jpabook.onboarding.data.entity.Student; +import jpabook.onboarding.data.entity.Sugang; +import jpabook.onboarding.data.repository.StudentRepository; +import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; +import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class StudentServiceImpl implements StudentService { + private final StudentRepository repository; + + @Override + public StudentResponseDto create(final StudentRequestDto requestDto) { + final Student student = new Student(requestDto); + repository.save(student); + return new StudentResponseDto(student); + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java index 42fdeb7..33423d1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java @@ -1,4 +1,12 @@ package jpabook.onboarding.sugang.controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/sugangs") +@RequiredArgsConstructor public class SugangController { } diff --git a/taehyeon/onboarding/src/main/resources/application.yml b/taehyeon/onboarding/src/main/resources/application.yml index 0adc2a1..4fbad0a 100644 --- a/taehyeon/onboarding/src/main/resources/application.yml +++ b/taehyeon/onboarding/src/main/resources/application.yml @@ -3,4 +3,7 @@ spring: name: onboarding datasource: username: root - url: jdbc:mysql://localhost:3306 \ No newline at end of file + url: jdbc:mysql://localhost:3306/onboarding_db + jpa: + hibernate: + ddl-auto: create \ No newline at end of file From d7633c97227530cacbf96137392672ae5c96b452 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 16:57:27 +0900 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20=ED=95=99=EC=83=9D=20=EC=A4=91?= =?UTF-8?q?=ED=87=B4=EC=8B=9C=ED=82=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jpabook/onboarding/OnboardingApplication.java | 2 ++ .../jpabook/onboarding/data/entity/Course.java | 2 +- .../jpabook/onboarding/data/entity/Student.java | 4 +++- .../jpabook/onboarding/data/entity/Sugang.java | 6 +++--- .../student/controller/StudentController.java | 7 +++++++ .../student/service/StudentService.java | 4 +++- .../student/service/StudentServiceImpl.java | 15 +++++++++++++-- .../onboarding/src/main/resources/application.yml | 12 +++++++++++- 8 files changed, 43 insertions(+), 9 deletions(-) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java index a01fef2..5f74504 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java @@ -1,5 +1,7 @@ package jpabook.onboarding; +import java.util.Optional; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index 5bcce43..3e6f861 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -24,7 +24,7 @@ public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "COURSE_ID") + @Column(name = "course_id") private int id; @Column(nullable = false) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index 63149c1..c973341 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -21,14 +21,16 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Entity @Getter +@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "STUDENT_ID") + @Column(name = "student_id") private Long id; @OneToMany(mappedBy = "student", cascade = CascadeType.ALL) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java index 2006cf8..036f1a1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java @@ -24,15 +24,15 @@ public class Sugang { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "SUGANG_ID") + @Column(name = "sugang_id") private int id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "STUDENT_ID") + @JoinColumn(name = "student_id") private Student student; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "COURSE_ID") + @JoinColumn(name = "course_id") private Course course; @Enumerated(EnumType.STRING) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 081bcdb..1ed5b69 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -2,6 +2,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -24,4 +25,10 @@ public ResponseEntity createStudent(@RequestBody StudentRequ final StudentResponseDto response = service.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); } + + @PatchMapping("/drop") + public ResponseEntity dropStudent(@RequestBody StudentRequestDto request) { + StudentResponseDto response = service.drop(request); + return ResponseEntity.status(HttpStatus.OK).body(response); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java index 9f5208c..ee1c417 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -4,5 +4,7 @@ import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; public interface StudentService { - StudentResponseDto create(StudentRequestDto requestDto); + StudentResponseDto create(StudentRequestDto request); + + StudentResponseDto drop(StudentRequestDto request); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 57d53db..458f4a7 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -8,6 +8,7 @@ import jpabook.onboarding.data.entity.Student; import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.repository.StudentRepository; +import jpabook.onboarding.data.status.StudentStatus; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; import lombok.RequiredArgsConstructor; @@ -18,9 +19,19 @@ public class StudentServiceImpl implements StudentService { private final StudentRepository repository; @Override - public StudentResponseDto create(final StudentRequestDto requestDto) { - final Student student = new Student(requestDto); + public StudentResponseDto create(final StudentRequestDto request) { + final Student student = new Student(request); repository.save(student); return new StudentResponseDto(student); } + + @Override + public StudentResponseDto drop(StudentRequestDto request) { + Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); + if (student.isEmpty()) { + return null; + } + student.get().setStatus(StudentStatus.DROP); + return new StudentResponseDto(student.get()); + } } diff --git a/taehyeon/onboarding/src/main/resources/application.yml b/taehyeon/onboarding/src/main/resources/application.yml index 4fbad0a..c3ec120 100644 --- a/taehyeon/onboarding/src/main/resources/application.yml +++ b/taehyeon/onboarding/src/main/resources/application.yml @@ -6,4 +6,14 @@ spring: url: jdbc:mysql://localhost:3306/onboarding_db jpa: hibernate: - ddl-auto: create \ No newline at end of file + ddl-auto: create + properties: + hibernate: + show_sql: true +logging: + level: + org: + hibernate: + type: + descriptor: + sql: trace \ No newline at end of file From d4eeec80d5d7dfef6fad4ad3c310bb4c7d074dac Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 18:35:37 +0900 Subject: [PATCH 09/20] =?UTF-8?q?feat:=20=EA=B0=95=EC=9D=98=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../course/controller/CourseController.java | 14 ++++++++ .../dto/request/CourseRequestDto.java | 19 +++++++++++ .../dto/response/CourseResponseDto.java | 32 +++++++++++++++++++ .../course/service/CourseService.java | 4 +++ .../course/service/CourseServiceImpl.java | 22 +++++++++++++ .../onboarding/data/entity/Course.java | 11 ++++++- .../onboarding/data/entity/Student.java | 6 ++-- .../data/repository/CourseRepository.java | 8 ++++- .../data/repository/SugangRepository.java | 8 ++++- .../onboarding/data/status/CourseStatus.java | 2 +- .../onboarding/data/status/SugangStatus.java | 4 +-- .../student/controller/StudentController.java | 4 +-- .../dto/response/StudentResponseDto.java | 4 +-- .../student/service/StudentServiceImpl.java | 5 ++- 14 files changed, 127 insertions(+), 16 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java index 6211cc5..0e9cb48 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -1,12 +1,26 @@ package jpabook.onboarding.course.controller; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; +import jpabook.onboarding.course.service.CourseService; import lombok.RequiredArgsConstructor; @RestController @RequestMapping("/courses") @RequiredArgsConstructor public class CourseController { + private final CourseService service; + + @PostMapping + public ResponseEntity createStudent(@RequestBody final CourseRequestDto request) { + final CourseResponseDto response = service.create(request); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java new file mode 100644 index 0000000..f0839ee --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java @@ -0,0 +1,19 @@ +package jpabook.onboarding.course.controller.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class CourseRequestDto { + @NotBlank(message = "교수 이름은 필수 입니다.") + private String professorName; + + @NotBlank(message = "강의 이름은 필수 입니다.") + private String name; + + @NotBlank(message = "현재 수강 인원은 필수 입니다.") + private int count; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java new file mode 100644 index 0000000..4e533c7 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java @@ -0,0 +1,32 @@ +package jpabook.onboarding.course.controller.dto.response; + +import jakarta.validation.constraints.NotBlank; +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.status.CourseStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class CourseResponseDto { + @NotBlank(message = "교수 이름은 필수 입니다.") + private String professorName; + + @NotBlank(message = "강의 이름은 필수 입니다.") + private String name; + + @NotBlank(message = "현재 수강 인원은 필수 입니다.") + private int count; + + private int grade; + private CourseStatus status; + + public CourseResponseDto(final Course course) { + this.professorName = course.getProfessorName(); + this.name = course.getName(); + this.count = course.getCount(); + this.grade = course.getGrade(); + this.status = course.getStatus(); + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java index 45bc23e..25238a0 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java @@ -1,4 +1,8 @@ package jpabook.onboarding.course.service; +import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; + public interface CourseService { + CourseResponseDto create(CourseRequestDto request); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java new file mode 100644 index 0000000..b03c00b --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -0,0 +1,22 @@ +package jpabook.onboarding.course.service; + +import org.springframework.stereotype.Service; + +import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.repository.CourseRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class CourseServiceImpl implements CourseService { + private final CourseRepository repository; + + @Override + public CourseResponseDto create(final CourseRequestDto request) { + Course course = new Course(request); + repository.save(course); + return new CourseResponseDto(course); + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index 3e6f861..8af0006 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -10,6 +10,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; import jpabook.onboarding.data.status.CourseStatus; import lombok.AccessLevel; import lombok.Getter; @@ -43,4 +44,12 @@ public class Course { @Column(nullable = false, length = 20) @JdbcTypeCode(SqlTypes.VARCHAR) private CourseStatus status; -} + + public Course(CourseRequestDto request) { + this.professorName = request.getProfessorName(); + this.name = request.getName(); + this.count = request.getCount(); + this.grade = 3; + this.status = CourseStatus.REGISTERED; + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index c973341..767acef 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -53,9 +53,9 @@ public class Student { @JdbcTypeCode(SqlTypes.VARCHAR) private StudentStatus status; - public Student(StudentRequestDto requestDto) { - this.name = requestDto.getName(); - this.birth = requestDto.getBirth(); + public Student(StudentRequestDto request) { + this.name = request.getName(); + this.birth = request.getBirth(); this.status = StudentStatus.ENROLLED; } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java index 7371b3d..9301d07 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java @@ -1,4 +1,10 @@ package jpabook.onboarding.data.repository; -public interface CourseRepository { +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import jpabook.onboarding.data.entity.Course; + +@Repository +public interface CourseRepository extends JpaRepository { } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java index c53d018..fd16dbf 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java @@ -1,4 +1,10 @@ package jpabook.onboarding.data.repository; -public interface SugangRepository { +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import jpabook.onboarding.data.entity.Sugang; + +@Repository +public interface SugangRepository extends JpaRepository { } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java index d62ce0f..fcd3a58 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java @@ -1,8 +1,8 @@ package jpabook.onboarding.data.status; public enum CourseStatus { - DELETED("삭제"), REGISTERED("등록"), + DELETED("삭제"), EXPIRED("만료"); private final String status; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java index 4d2ada4..047a5a3 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java @@ -1,9 +1,9 @@ package jpabook.onboarding.data.status; public enum SugangStatus { + ONGOING("진행중"), CANCELED("취소"), - COMPLETED("완료"), - ONGOING("진행중"); + COMPLETED("완료"); private final String status; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 1ed5b69..4183c9b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -21,13 +21,13 @@ public class StudentController { private final StudentService service; @PostMapping - public ResponseEntity createStudent(@RequestBody StudentRequestDto request) { + public ResponseEntity createStudent(@RequestBody final StudentRequestDto request) { final StudentResponseDto response = service.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @PatchMapping("/drop") - public ResponseEntity dropStudent(@RequestBody StudentRequestDto request) { + public ResponseEntity dropStudent(@RequestBody final StudentRequestDto request) { StudentResponseDto response = service.drop(request); return ResponseEntity.status(HttpStatus.OK).body(response); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java index a0ae359..b6cd257 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java @@ -13,10 +13,10 @@ @AllArgsConstructor(access = AccessLevel.PROTECTED) public class StudentResponseDto { - @NotBlank + @NotBlank(message = "이름은 필수 입니다.") private final String name; - @NotBlank + @NotBlank(message = "생일은 필수 입니다.") private final LocalDate birth; private final int currentGrade; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 458f4a7..0d74058 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -6,7 +6,6 @@ import org.springframework.stereotype.Service; import jpabook.onboarding.data.entity.Student; -import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.status.StudentStatus; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; @@ -26,8 +25,8 @@ public StudentResponseDto create(final StudentRequestDto request) { } @Override - public StudentResponseDto drop(StudentRequestDto request) { - Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); + public StudentResponseDto drop(final StudentRequestDto request) { + final Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); if (student.isEmpty()) { return null; } From b3bbded99e056fe9c4ef15b9475f8580eec7606a Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 19:24:29 +0900 Subject: [PATCH 10/20] =?UTF-8?q?feat:=20=EA=B0=95=EC=9D=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../course/controller/CourseController.java | 11 ++++++++++- .../onboarding/course/service/CourseService.java | 2 ++ .../course/service/CourseServiceImpl.java | 15 +++++++++++++++ .../jpabook/onboarding/data/entity/Course.java | 2 ++ .../jpabook/onboarding/data/entity/Sugang.java | 2 ++ .../student/service/StudentServiceImpl.java | 2 ++ 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java index 0e9cb48..13907b1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -2,6 +2,9 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,8 +22,14 @@ public class CourseController { private final CourseService service; @PostMapping - public ResponseEntity createStudent(@RequestBody final CourseRequestDto request) { + public ResponseEntity createCourse(@RequestBody final CourseRequestDto request) { final CourseResponseDto response = service.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); } + + @PatchMapping("/delete/{courseId}") + public ResponseEntity deleteCourse(@PathVariable Long courseId) { + CourseResponseDto response = service.delete(courseId); + return ResponseEntity.status(HttpStatus.OK).body(response); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java index 25238a0..99f4fca 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java @@ -5,4 +5,6 @@ public interface CourseService { CourseResponseDto create(CourseRequestDto request); + + CourseResponseDto delete(Long courseId); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java index b03c00b..8a7c78b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -1,11 +1,15 @@ package jpabook.onboarding.course.service; +import java.util.Optional; + import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; import jpabook.onboarding.data.entity.Course; import jpabook.onboarding.data.repository.CourseRepository; +import jpabook.onboarding.data.status.CourseStatus; import lombok.RequiredArgsConstructor; @Service @@ -19,4 +23,15 @@ public CourseResponseDto create(final CourseRequestDto request) { repository.save(course); return new CourseResponseDto(course); } + + @Transactional + @Override + public CourseResponseDto delete(final Long courseId) { + Optional course = repository.findById(courseId); + if (course.isEmpty()) { + return null; + } + course.get().setStatus(CourseStatus.DELETED); + return new CourseResponseDto(course.get()); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index 8af0006..eb82619 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -15,9 +15,11 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Entity @Getter +@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Course { diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java index 036f1a1..554ef6b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java @@ -17,9 +17,11 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Entity @Getter +@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Sugang { @Id diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 0d74058..3d59596 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -4,6 +4,7 @@ import java.util.Optional; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import jpabook.onboarding.data.entity.Student; import jpabook.onboarding.data.repository.StudentRepository; @@ -24,6 +25,7 @@ public StudentResponseDto create(final StudentRequestDto request) { return new StudentResponseDto(student); } + @Transactional @Override public StudentResponseDto drop(final StudentRequestDto request) { final Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); From 262170fb321ae4532f3278f64a25fe8a471f74c1 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 19:30:46 +0900 Subject: [PATCH 11/20] =?UTF-8?q?feat:=20=EA=B0=95=EC=9D=98=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=EC=8B=9C=ED=82=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../course/controller/CourseController.java | 9 +++++++-- .../dto/request/CourseRequestDto.java | 2 +- .../dto/response/CourseResponseDto.java | 2 +- .../course/service/CourseService.java | 4 +++- .../course/service/CourseServiceImpl.java | 17 ++++++++++++++--- .../jpabook/onboarding/data/entity/Student.java | 2 +- .../jpabook/onboarding/data/entity/Sugang.java | 2 +- .../data/repository/CourseRepository.java | 2 +- .../data/repository/StudentRepository.java | 2 +- .../data/repository/SugangRepository.java | 2 +- .../onboarding/data/status/CourseStatus.java | 2 +- .../onboarding/data/status/StudentStatus.java | 2 +- .../onboarding/data/status/SugangStatus.java | 2 +- .../student/controller/StudentController.java | 2 +- .../dto/request/StudentRequestDto.java | 2 +- .../student/service/StudentService.java | 2 +- .../student/service/StudentServiceImpl.java | 2 +- 17 files changed, 38 insertions(+), 20 deletions(-) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java index 13907b1..22137e4 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -2,7 +2,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -32,4 +31,10 @@ public ResponseEntity deleteCourse(@PathVariable Long courseI CourseResponseDto response = service.delete(courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } -} + + @PatchMapping("/complete/{courseId}") + public ResponseEntity completeCourse(@PathVariable Long courseId) { + CourseResponseDto response = service.complete(courseId); + return ResponseEntity.status(HttpStatus.OK).body(response); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java index f0839ee..54ce24b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java @@ -16,4 +16,4 @@ public class CourseRequestDto { @NotBlank(message = "현재 수강 인원은 필수 입니다.") private int count; -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java index 4e533c7..5065b80 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java @@ -29,4 +29,4 @@ public CourseResponseDto(final Course course) { this.grade = course.getGrade(); this.status = course.getStatus(); } -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java index 99f4fca..3238b6e 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java @@ -7,4 +7,6 @@ public interface CourseService { CourseResponseDto create(CourseRequestDto request); CourseResponseDto delete(Long courseId); -} + + CourseResponseDto complete(Long courseId); +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java index 8a7c78b..9127409 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -19,19 +19,30 @@ public class CourseServiceImpl implements CourseService { @Override public CourseResponseDto create(final CourseRequestDto request) { - Course course = new Course(request); + final Course course = new Course(request); repository.save(course); return new CourseResponseDto(course); } + @Transactional + @Override + public CourseResponseDto complete(final Long courseId) { + final Optional course = repository.findById(courseId); + if (course.isEmpty()) { + return null; + } + course.get().setStatus(CourseStatus.COMPLETED); + return new CourseResponseDto(course.get()); + } + @Transactional @Override public CourseResponseDto delete(final Long courseId) { - Optional course = repository.findById(courseId); + final Optional course = repository.findById(courseId); if (course.isEmpty()) { return null; } course.get().setStatus(CourseStatus.DELETED); return new CourseResponseDto(course.get()); } -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index 767acef..e173c1c 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -58,4 +58,4 @@ public Student(StudentRequestDto request) { this.birth = request.getBirth(); this.status = StudentStatus.ENROLLED; } -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java index 554ef6b..7073566 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java @@ -41,4 +41,4 @@ public class Sugang { @Column(nullable = false, length = 20) @JdbcTypeCode(SqlTypes.VARCHAR) private SugangStatus status; -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java index 9301d07..239eb71 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java @@ -7,4 +7,4 @@ @Repository public interface CourseRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java index e736240..07d8dee 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java @@ -11,4 +11,4 @@ @Repository public interface StudentRepository extends JpaRepository { Optional findByNameAndBirth(String name, LocalDate birth); -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java index fd16dbf..fb4313c 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java @@ -7,4 +7,4 @@ @Repository public interface SugangRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java index fcd3a58..d6beb5d 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java @@ -3,7 +3,7 @@ public enum CourseStatus { REGISTERED("등록"), DELETED("삭제"), - EXPIRED("만료"); + COMPLETED("완료"); private final String status; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java index 12856c3..2af562e 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java @@ -14,4 +14,4 @@ public enum StudentStatus { public String getStatus() { return status; } -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java index 047a5a3..5bd8267 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java @@ -14,4 +14,4 @@ public enum SugangStatus { public String getStatus() { return status; } -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 4183c9b..85e91b0 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -31,4 +31,4 @@ public ResponseEntity dropStudent(@RequestBody final Student StudentResponseDto response = service.drop(request); return ResponseEntity.status(HttpStatus.OK).body(response); } -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java index 956760b..579dce7 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java @@ -17,4 +17,4 @@ public class StudentRequestDto { @NotNull(message = "생일은 필수 입니다.") private final LocalDate birth; -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java index ee1c417..8db6b22 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -7,4 +7,4 @@ public interface StudentService { StudentResponseDto create(StudentRequestDto request); StudentResponseDto drop(StudentRequestDto request); -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 3d59596..fce1f93 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -35,4 +35,4 @@ public StudentResponseDto drop(final StudentRequestDto request) { student.get().setStatus(StudentStatus.DROP); return new StudentResponseDto(student.get()); } -} +} \ No newline at end of file From de3abe6644899c2bf86de0f05cfe42d0ea643282 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 19:54:53 +0900 Subject: [PATCH 12/20] =?UTF-8?q?feat:=20=EA=B0=95=EC=9D=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../course/controller/CourseController.java | 17 ++++++++++---- .../dto/request/CourseRequestDto.java | 6 ++--- .../dto/request/CourseUpdateRequestDto.java | 23 +++++++++++++++++++ .../course/service/CourseService.java | 3 +++ .../course/service/CourseServiceImpl.java | 17 ++++++++++++++ .../onboarding/data/entity/Course.java | 9 ++++++++ 6 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java index 22137e4..f9b5ab1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -5,11 +5,13 @@ import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; import jpabook.onboarding.course.service.CourseService; import lombok.RequiredArgsConstructor; @@ -26,15 +28,22 @@ public ResponseEntity createCourse(@RequestBody final CourseR return ResponseEntity.status(HttpStatus.CREATED).body(response); } + @PutMapping("/{courseId}") + public ResponseEntity updateCourse(@PathVariable final Long courseId, + @RequestBody final CourseUpdateRequestDto request) { + final CourseResponseDto response = service.update(courseId, request); + return ResponseEntity.status(HttpStatus.OK).body(response); + } + @PatchMapping("/delete/{courseId}") - public ResponseEntity deleteCourse(@PathVariable Long courseId) { - CourseResponseDto response = service.delete(courseId); + public ResponseEntity deleteCourse(@PathVariable final Long courseId) { + final CourseResponseDto response = service.delete(courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } @PatchMapping("/complete/{courseId}") - public ResponseEntity completeCourse(@PathVariable Long courseId) { - CourseResponseDto response = service.complete(courseId); + public ResponseEntity completeCourse(@PathVariable final Long courseId) { + final CourseResponseDto response = service.complete(courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java index 54ce24b..8676c76 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java @@ -9,11 +9,11 @@ @AllArgsConstructor(access = AccessLevel.PROTECTED) public class CourseRequestDto { @NotBlank(message = "교수 이름은 필수 입니다.") - private String professorName; + private final String professorName; @NotBlank(message = "강의 이름은 필수 입니다.") - private String name; + private final String name; @NotBlank(message = "현재 수강 인원은 필수 입니다.") - private int count; + private final int count; } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java new file mode 100644 index 0000000..bb8bf23 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java @@ -0,0 +1,23 @@ +package jpabook.onboarding.course.controller.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jpabook.onboarding.data.status.CourseStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class CourseUpdateRequestDto { + @NotBlank(message = "교수 이름은 필수 입니다.") + private final String professorName; + + @NotBlank(message = "강의 이름은 필수 입니다.") + private final String name; + + @NotBlank(message = "학점은 필수 입니다.") + private final int grade; + + @NotBlank(message = "강의 상태는 필수 입니다.") + private final CourseStatus status; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java index 3238b6e..45587ca 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseService.java @@ -1,6 +1,7 @@ package jpabook.onboarding.course.service; import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; public interface CourseService { @@ -9,4 +10,6 @@ public interface CourseService { CourseResponseDto delete(Long courseId); CourseResponseDto complete(Long courseId); + + CourseResponseDto update(Long courseId, CourseUpdateRequestDto request); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java index 9127409..d8d7846 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -6,6 +6,7 @@ import org.springframework.transaction.annotation.Transactional; import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; import jpabook.onboarding.data.entity.Course; import jpabook.onboarding.data.repository.CourseRepository; @@ -35,6 +36,21 @@ public CourseResponseDto complete(final Long courseId) { return new CourseResponseDto(course.get()); } + @Transactional + @Override + public CourseResponseDto update(final Long courseId, final CourseUpdateRequestDto request) { + final Optional course = repository.findById(courseId); + if (course.isEmpty()) { + final Course newCourse = repository.save(new Course(request)); + return new CourseResponseDto(newCourse); + } + course.get().setName(request.getName()); + course.get().setProfessorName(request.getProfessorName()); + course.get().setGrade(request.getGrade()); + course.get().setStatus(request.getStatus()); + return new CourseResponseDto(course.get()); + } + @Transactional @Override public CourseResponseDto delete(final Long courseId) { @@ -44,5 +60,6 @@ public CourseResponseDto delete(final Long courseId) { } course.get().setStatus(CourseStatus.DELETED); return new CourseResponseDto(course.get()); + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index eb82619..bf25338 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -11,6 +11,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.data.status.CourseStatus; import lombok.AccessLevel; import lombok.Getter; @@ -54,4 +55,12 @@ public Course(CourseRequestDto request) { this.grade = 3; this.status = CourseStatus.REGISTERED; } + + public Course(CourseUpdateRequestDto request) { + this.professorName = request.getProfessorName(); + this.name = request.getName(); + this.count = 0; + this.grade = request.getGrade(); + this.status = request.getStatus(); + } } \ No newline at end of file From 949b2f82d57d511eb46d4da1e2385af271f2ac87 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 21:38:23 +0900 Subject: [PATCH 13/20] =?UTF-8?q?feat:=EC=A1=B8=EC=97=85=EC=9E=90=20?= =?UTF-8?q?=EB=AA=85=EB=8B=A8=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/repository/StudentRepository.java | 5 +++++ .../student/controller/StudentController.java | 13 ++++++++++++- .../onboarding/student/service/StudentService.java | 5 +++++ .../student/service/StudentServiceImpl.java | 9 +++++++++ .../onboarding/src/main/resources/application.yml | 5 ++--- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java index 07d8dee..94667cd 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java @@ -3,12 +3,17 @@ import java.time.LocalDate; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import jpabook.onboarding.data.entity.Student; +import jpabook.onboarding.data.status.StudentStatus; @Repository public interface StudentRepository extends JpaRepository { Optional findByNameAndBirth(String name, LocalDate birth); + + Page findAllByStatus(StudentStatus status, Pageable pageable); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 85e91b0..880dfb8 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -1,11 +1,15 @@ package jpabook.onboarding.student.controller; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; @@ -28,7 +32,14 @@ public ResponseEntity createStudent(@RequestBody final Stude @PatchMapping("/drop") public ResponseEntity dropStudent(@RequestBody final StudentRequestDto request) { - StudentResponseDto response = service.drop(request); + final StudentResponseDto response = service.drop(request); return ResponseEntity.status(HttpStatus.OK).body(response); } + + @GetMapping("/graduated") + public ResponseEntity> getGraduates(@RequestParam(defaultValue = "0") final int page) { + final PageRequest pageRequest = PageRequest.of(page, 5); + final Page graduates = service.getGraduates(pageRequest); + return ResponseEntity.status(HttpStatus.OK).body(graduates); + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java index 8db6b22..ecb7dd4 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -1,5 +1,8 @@ package jpabook.onboarding.student.service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; @@ -7,4 +10,6 @@ public interface StudentService { StudentResponseDto create(StudentRequestDto request); StudentResponseDto drop(StudentRequestDto request); + + Page getGraduates(Pageable pageable); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index fce1f93..11d00b5 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -1,8 +1,11 @@ package jpabook.onboarding.student.service; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,4 +38,10 @@ public StudentResponseDto drop(final StudentRequestDto request) { student.get().setStatus(StudentStatus.DROP); return new StudentResponseDto(student.get()); } + + @Transactional(readOnly = true) + @Override + public Page getGraduates(final Pageable pageable) { + return repository.findAllByStatus(StudentStatus.GRADUATED, pageable).map(StudentResponseDto::new); + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/resources/application.yml b/taehyeon/onboarding/src/main/resources/application.yml index c3ec120..5a1400f 100644 --- a/taehyeon/onboarding/src/main/resources/application.yml +++ b/taehyeon/onboarding/src/main/resources/application.yml @@ -14,6 +14,5 @@ logging: level: org: hibernate: - type: - descriptor: - sql: trace \ No newline at end of file + orm.jdbc.bind : trace + From 9f10603aaa891299982361600df31850efdd3fc9 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 23:49:42 +0900 Subject: [PATCH 14/20] =?UTF-8?q?feat:=20=EC=88=98=EA=B0=95=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/CourseRequestDto.java | 6 ++-- .../dto/request/CourseUpdateRequestDto.java | 8 ++--- .../dto/response/CourseResponseDto.java | 4 +-- .../onboarding/data/entity/Sugang.java | 7 ++++ .../dto/request/StudentRequestDto.java | 4 +-- .../dto/response/StudentResponseDto.java | 4 +-- .../sugang/controller/SugangController.java | 16 +++++++++ .../dto/request/SugangRequestDto.java | 19 ++++++++++ .../dto/response/SugangResponseDto.java | 25 +++++++++++++ .../sugang/service/SugangService.java | 6 +++- .../sugang/service/SugangServiceImpl.java | 35 +++++++++++++++++++ 11 files changed, 120 insertions(+), 14 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java index 8676c76..7bbdba3 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java @@ -8,12 +8,12 @@ @Getter @AllArgsConstructor(access = AccessLevel.PROTECTED) public class CourseRequestDto { - @NotBlank(message = "교수 이름은 필수 입니다.") + @NotBlank(message = "교수 이름은 필수입니다.") private final String professorName; - @NotBlank(message = "강의 이름은 필수 입니다.") + @NotBlank(message = "강의 이름은 필수입니다.") private final String name; - @NotBlank(message = "현재 수강 인원은 필수 입니다.") + @NotBlank(message = "현재 수강 인원은 필수입니다.") private final int count; } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java index bb8bf23..7402c3d 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java @@ -9,15 +9,15 @@ @Getter @AllArgsConstructor(access = AccessLevel.PROTECTED) public class CourseUpdateRequestDto { - @NotBlank(message = "교수 이름은 필수 입니다.") + @NotBlank(message = "교수 이름은 필수입니다.") private final String professorName; - @NotBlank(message = "강의 이름은 필수 입니다.") + @NotBlank(message = "강의 이름은 필수입니다.") private final String name; - @NotBlank(message = "학점은 필수 입니다.") + @NotBlank(message = "학점은 필수입니다.") private final int grade; - @NotBlank(message = "강의 상태는 필수 입니다.") + @NotBlank(message = "강의 상태는 필수입니다.") private final CourseStatus status; } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java index 5065b80..6c70853 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java @@ -13,10 +13,10 @@ public class CourseResponseDto { @NotBlank(message = "교수 이름은 필수 입니다.") private String professorName; - @NotBlank(message = "강의 이름은 필수 입니다.") + @NotBlank(message = "강의 이름은 필수입니다.") private String name; - @NotBlank(message = "현재 수강 인원은 필수 입니다.") + @NotBlank(message = "현재 수강 인원은 필수입니다.") private int count; private int grade; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java index 7073566..c9d8c37 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java @@ -41,4 +41,11 @@ public class Sugang { @Column(nullable = false, length = 20) @JdbcTypeCode(SqlTypes.VARCHAR) private SugangStatus status; + + public Sugang(final Student student, final Course course) { + this.student = student; + student.getSugangs().add(this); + this.course = course; + this.status = SugangStatus.ONGOING; + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java index 579dce7..731bfe3 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/request/StudentRequestDto.java @@ -12,9 +12,9 @@ @AllArgsConstructor(access = AccessLevel.PROTECTED) public class StudentRequestDto { - @NotBlank(message = "이름은 필수 입니다.") + @NotBlank(message = "이름은 필수입니다.") private final String name; - @NotNull(message = "생일은 필수 입니다.") + @NotNull(message = "생일은 필수입니다.") private final LocalDate birth; } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java index b6cd257..63e1310 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java @@ -13,10 +13,10 @@ @AllArgsConstructor(access = AccessLevel.PROTECTED) public class StudentResponseDto { - @NotBlank(message = "이름은 필수 입니다.") + @NotBlank(message = "이름은 필수입니다.") private final String name; - @NotBlank(message = "생일은 필수 입니다.") + @NotBlank(message = "생일은 필수입니다.") private final LocalDate birth; private final int currentGrade; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java index 33423d1..0cde342 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java @@ -1,12 +1,28 @@ package jpabook.onboarding.sugang.controller; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; +import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; +import jpabook.onboarding.sugang.service.SugangService; import lombok.RequiredArgsConstructor; @RestController @RequestMapping("/sugangs") @RequiredArgsConstructor public class SugangController { + private final SugangService service; + + @PostMapping("/{courseId}") + public ResponseEntity createSugang(@RequestBody final SugangRequestDto request, + @PathVariable final Long courseId) { + final SugangResponseDto sugang = service.createSugang(request, courseId); + return ResponseEntity.status(HttpStatus.CREATED).body(sugang); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java new file mode 100644 index 0000000..7611522 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java @@ -0,0 +1,19 @@ +package jpabook.onboarding.sugang.controller.dto.request; + +import java.time.LocalDate; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class SugangRequestDto { + @NotBlank(message = "이름은 필수입니다.") + private final String name; + + @NotNull(message = "생일은 필수입니다.") + private final LocalDate birth; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java new file mode 100644 index 0000000..bc8baeb --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java @@ -0,0 +1,25 @@ +package jpabook.onboarding.sugang.controller.dto.response; + +import jakarta.validation.constraints.NotBlank; +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.entity.Student; +import jpabook.onboarding.data.entity.Sugang; +import jpabook.onboarding.data.status.SugangStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class SugangResponseDto { + @NotBlank(message = "과목 이름은 필수입니다.") + private final String courseName; + + @NotBlank(message = "수강 상태는 필수입니다.") + private final SugangStatus status; + + public SugangResponseDto(final Sugang sugang) { + this.courseName = sugang.getCourse().getName(); + this.status = sugang.getStatus(); + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java index 2ae4179..bd70fe4 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java @@ -1,4 +1,8 @@ package jpabook.onboarding.sugang.service; +import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; +import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; + public interface SugangService { -} + SugangResponseDto createSugang(SugangRequestDto request, Long courseId); +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java new file mode 100644 index 0000000..40bf758 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java @@ -0,0 +1,35 @@ +package jpabook.onboarding.sugang.service; + +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.entity.Student; +import jpabook.onboarding.data.entity.Sugang; +import jpabook.onboarding.data.repository.CourseRepository; +import jpabook.onboarding.data.repository.StudentRepository; +import jpabook.onboarding.data.repository.SugangRepository; +import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; +import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class SugangServiceImpl implements SugangService { + private final SugangRepository repository; + private final StudentRepository studentRepository; + private final CourseRepository courseRepository; + + @Override + public SugangResponseDto createSugang(final SugangRequestDto request, final Long courseId) { + final Optional student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()); + final Optional course = courseRepository.findById(courseId); + if (student.isEmpty() || course.isEmpty()) { + return null; + } + final Sugang sugang = new Sugang(student.get(), course.get()); + repository.save(sugang); + return new SugangResponseDto(sugang); + } +} From 4bd2df2b907224e408ac724fc277dd996575f454 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Sun, 24 Nov 2024 23:59:33 +0900 Subject: [PATCH 15/20] =?UTF-8?q?feat:=20=EC=88=98=EA=B0=95=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20=EC=B7=A8=EC=86=8C=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/repository/SugangRepository.java | 5 +++++ .../student/controller/StudentController.java | 4 ++-- .../sugang/controller/SugangController.java | 12 ++++++++++-- .../onboarding/sugang/service/SugangService.java | 2 ++ .../sugang/service/SugangServiceImpl.java | 15 +++++++++++++++ .../onboarding/src/main/resources/application.yml | 2 +- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java index fb4313c..6127b52 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java @@ -1,10 +1,15 @@ package jpabook.onboarding.data.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.entity.Student; import jpabook.onboarding.data.entity.Sugang; @Repository public interface SugangRepository extends JpaRepository { + Optional findByStudentAndCourse(Student student, Course course); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 880dfb8..23dc0b2 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -39,7 +39,7 @@ public ResponseEntity dropStudent(@RequestBody final Student @GetMapping("/graduated") public ResponseEntity> getGraduates(@RequestParam(defaultValue = "0") final int page) { final PageRequest pageRequest = PageRequest.of(page, 5); - final Page graduates = service.getGraduates(pageRequest); - return ResponseEntity.status(HttpStatus.OK).body(graduates); + final Page response = service.getGraduates(pageRequest); + return ResponseEntity.status(HttpStatus.OK).body(response); } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java index 0cde342..0c57568 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java @@ -2,6 +2,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,7 +23,14 @@ public class SugangController { @PostMapping("/{courseId}") public ResponseEntity createSugang(@RequestBody final SugangRequestDto request, @PathVariable final Long courseId) { - final SugangResponseDto sugang = service.createSugang(request, courseId); - return ResponseEntity.status(HttpStatus.CREATED).body(sugang); + final SugangResponseDto response = service.createSugang(request, courseId); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + + @PatchMapping("/{courseId}") + public ResponseEntity cancelSugang(@RequestBody final SugangRequestDto request, + @PathVariable final Long courseId) { + final SugangResponseDto response = service.cancelSugang(request, courseId); + return ResponseEntity.status(HttpStatus.OK).body(response); } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java index bd70fe4..371ab91 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java @@ -5,4 +5,6 @@ public interface SugangService { SugangResponseDto createSugang(SugangRequestDto request, Long courseId); + + SugangResponseDto cancelSugang(SugangRequestDto request, Long courseId); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java index 40bf758..a47718d 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java @@ -3,6 +3,7 @@ import java.util.Optional; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import jpabook.onboarding.data.entity.Course; import jpabook.onboarding.data.entity.Student; @@ -10,6 +11,7 @@ import jpabook.onboarding.data.repository.CourseRepository; import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.repository.SugangRepository; +import jpabook.onboarding.data.status.SugangStatus; import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; import lombok.RequiredArgsConstructor; @@ -21,6 +23,19 @@ public class SugangServiceImpl implements SugangService { private final StudentRepository studentRepository; private final CourseRepository courseRepository; + @Transactional + @Override + public SugangResponseDto cancelSugang(final SugangRequestDto request, final Long courseId) { + final Optional student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()); + final Optional course = courseRepository.findById(courseId); + if (student.isEmpty() || course.isEmpty()) { + return null; + } + final Optional sugang = repository.findByStudentAndCourse(student.get(), course.get()); + sugang.get().setStatus(SugangStatus.CANCELED); + return new SugangResponseDto(sugang.get()); + } + @Override public SugangResponseDto createSugang(final SugangRequestDto request, final Long courseId) { final Optional student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()); diff --git a/taehyeon/onboarding/src/main/resources/application.yml b/taehyeon/onboarding/src/main/resources/application.yml index 5a1400f..5439d52 100644 --- a/taehyeon/onboarding/src/main/resources/application.yml +++ b/taehyeon/onboarding/src/main/resources/application.yml @@ -6,7 +6,7 @@ spring: url: jdbc:mysql://localhost:3306/onboarding_db jpa: hibernate: - ddl-auto: create + ddl-auto: update properties: hibernate: show_sql: true From 949fb9ff63c87aa571a35420a613efdf9084aa37 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Tue, 26 Nov 2024 11:58:45 +0900 Subject: [PATCH 16/20] =?UTF-8?q?feat:=20=ED=95=99=EC=83=9D=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=ED=91=9C=20=EB=B3=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/OnboardingApplication.java | 11 +++----- .../dto/response/CourseResponseDto.java | 19 ++++++-------- .../course/service/CourseServiceImpl.java | 9 +++---- .../onboarding/data/entity/Course.java | 14 +++++++++-- .../onboarding/data/entity/Student.java | 6 +++-- .../onboarding/data/entity/Sugang.java | 8 +++--- .../student/controller/StudentController.java | 10 ++++++++ .../dto/response/StudentResponseDto.java | 5 ---- .../response/StudentScheduleResponseDto.java | 25 +++++++++++++++++++ .../response/StudentSchedulesResponseDto.java | 12 +++++++++ .../student/service/StudentService.java | 3 +++ .../student/service/StudentServiceImpl.java | 17 ++++++++++++- .../dto/response/SugangResponseDto.java | 2 -- .../sugang/service/SugangServiceImpl.java | 2 +- .../src/main/resources/application.yml | 5 +--- 15 files changed, 103 insertions(+), 45 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentScheduleResponseDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentSchedulesResponseDto.java diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java index 5f74504..2163251 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/OnboardingApplication.java @@ -1,15 +1,12 @@ package jpabook.onboarding; -import java.util.Optional; - import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class OnboardingApplication { - public static void main(String[] args) { - SpringApplication.run(OnboardingApplication.class, args); - } - -} + public static void main(String[] args) { + SpringApplication.run(OnboardingApplication.class, args); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java index 6c70853..eefc01a 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/response/CourseResponseDto.java @@ -1,6 +1,5 @@ package jpabook.onboarding.course.controller.dto.response; -import jakarta.validation.constraints.NotBlank; import jpabook.onboarding.data.entity.Course; import jpabook.onboarding.data.status.CourseStatus; import lombok.AccessLevel; @@ -10,19 +9,15 @@ @Getter @AllArgsConstructor(access = AccessLevel.PROTECTED) public class CourseResponseDto { - @NotBlank(message = "교수 이름은 필수 입니다.") - private String professorName; - - @NotBlank(message = "강의 이름은 필수입니다.") - private String name; - - @NotBlank(message = "현재 수강 인원은 필수입니다.") - private int count; - - private int grade; - private CourseStatus status; + private final long id; + private final String professorName; + private final String name; + private final int count; + private final int grade; + private final CourseStatus status; public CourseResponseDto(final Course course) { + this.id = course.getId(); this.professorName = course.getProfessorName(); this.name = course.getName(); this.count = course.getCount(); diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java index d8d7846..883c4cc 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -32,7 +32,7 @@ public CourseResponseDto complete(final Long courseId) { if (course.isEmpty()) { return null; } - course.get().setStatus(CourseStatus.COMPLETED); + course.get().updateStatus(CourseStatus.COMPLETED); return new CourseResponseDto(course.get()); } @@ -44,10 +44,7 @@ public CourseResponseDto update(final Long courseId, final CourseUpdateRequestDt final Course newCourse = repository.save(new Course(request)); return new CourseResponseDto(newCourse); } - course.get().setName(request.getName()); - course.get().setProfessorName(request.getProfessorName()); - course.get().setGrade(request.getGrade()); - course.get().setStatus(request.getStatus()); + course.get().update(request); return new CourseResponseDto(course.get()); } @@ -58,7 +55,7 @@ public CourseResponseDto delete(final Long courseId) { if (course.isEmpty()) { return null; } - course.get().setStatus(CourseStatus.DELETED); + course.get().updateStatus(CourseStatus.DELETED); return new CourseResponseDto(course.get()); } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index bf25338..33e2029 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -20,7 +20,6 @@ @Entity @Getter -@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Course { @@ -29,7 +28,7 @@ public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "course_id") - private int id; + private Long id; @Column(nullable = false) private String professorName; @@ -63,4 +62,15 @@ public Course(CourseUpdateRequestDto request) { this.grade = request.getGrade(); this.status = request.getStatus(); } + + public void updateStatus(final CourseStatus status) { + this.status = status; + } + + public void update(final CourseUpdateRequestDto request) { + this.name = request.getName(); + this.grade = request.getGrade(); + this.professorName = request.getProfessorName(); + this.status = request.getStatus(); + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index e173c1c..c04dd1e 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -21,11 +21,9 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; @Entity @Getter -@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Student { @Id @@ -58,4 +56,8 @@ public Student(StudentRequestDto request) { this.birth = request.getBirth(); this.status = StudentStatus.ENROLLED; } + + public void updateStatus(final StudentStatus status) { + this.status = status; + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java index c9d8c37..76dc0bc 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Sugang.java @@ -17,17 +17,15 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; @Entity @Getter -@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Sugang { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "sugang_id") - private int id; + private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "student_id") @@ -48,4 +46,8 @@ public Sugang(final Student student, final Course course) { this.course = course; this.status = SugangStatus.ONGOING; } + + public void updateStatus(final SugangStatus status) { + this.status = status; + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 23dc0b2..773f408 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -1,5 +1,7 @@ package jpabook.onboarding.student.controller; +import java.util.List; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; @@ -14,6 +16,8 @@ import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; +import jpabook.onboarding.student.controller.dto.response.StudentScheduleResponseDto; +import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; import jpabook.onboarding.student.service.StudentService; import lombok.RequiredArgsConstructor; @@ -42,4 +46,10 @@ public ResponseEntity> getGraduates(@RequestParam(defau final Page response = service.getGraduates(pageRequest); return ResponseEntity.status(HttpStatus.OK).body(response); } + + @GetMapping("/schedule") + public ResponseEntity getSchedule(@RequestBody final StudentRequestDto request) { + final StudentSchedulesResponseDto response = service.getSchedule(request); + return ResponseEntity.status(HttpStatus.OK).body(response); + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java index 63e1310..bfd5913 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentResponseDto.java @@ -2,7 +2,6 @@ import java.time.LocalDate; -import jakarta.validation.constraints.NotBlank; import jpabook.onboarding.data.entity.Student; import jpabook.onboarding.data.status.StudentStatus; import lombok.AccessLevel; @@ -13,12 +12,8 @@ @AllArgsConstructor(access = AccessLevel.PROTECTED) public class StudentResponseDto { - @NotBlank(message = "이름은 필수입니다.") private final String name; - - @NotBlank(message = "생일은 필수입니다.") private final LocalDate birth; - private final int currentGrade; private final int totalGrade; private final StudentStatus status; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentScheduleResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentScheduleResponseDto.java new file mode 100644 index 0000000..8b90e6e --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentScheduleResponseDto.java @@ -0,0 +1,25 @@ +package jpabook.onboarding.student.controller.dto.response; + +import jpabook.onboarding.data.entity.Sugang; +import jpabook.onboarding.data.status.SugangStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class StudentScheduleResponseDto { + private final Long id; + private final String professorName; + private final String courseName; + private final int grade; + private final SugangStatus status; + + public StudentScheduleResponseDto(final Sugang sugang) { + this.id = sugang.getId(); + this.professorName = sugang.getCourse().getProfessorName(); + this.courseName = sugang.getCourse().getName(); + this.grade = sugang.getCourse().getGrade(); + this.status = sugang.getStatus(); + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentSchedulesResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentSchedulesResponseDto.java new file mode 100644 index 0000000..38e1b0b --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/dto/response/StudentSchedulesResponseDto.java @@ -0,0 +1,12 @@ +package jpabook.onboarding.student.controller.dto.response; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class StudentSchedulesResponseDto { + private final List schedules; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java index ecb7dd4..cf3a257 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -5,6 +5,7 @@ import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; +import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; public interface StudentService { StudentResponseDto create(StudentRequestDto request); @@ -12,4 +13,6 @@ public interface StudentService { StudentResponseDto drop(StudentRequestDto request); Page getGraduates(Pageable pageable); + + StudentSchedulesResponseDto getSchedule(StudentRequestDto request); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 11d00b5..4d76255 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -10,10 +10,13 @@ import org.springframework.transaction.annotation.Transactional; import jpabook.onboarding.data.entity.Student; +import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.status.StudentStatus; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; +import jpabook.onboarding.student.controller.dto.response.StudentScheduleResponseDto; +import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; import lombok.RequiredArgsConstructor; @Service @@ -35,7 +38,7 @@ public StudentResponseDto drop(final StudentRequestDto request) { if (student.isEmpty()) { return null; } - student.get().setStatus(StudentStatus.DROP); + student.get().updateStatus(StudentStatus.DROP); return new StudentResponseDto(student.get()); } @@ -44,4 +47,16 @@ public StudentResponseDto drop(final StudentRequestDto request) { public Page getGraduates(final Pageable pageable) { return repository.findAllByStatus(StudentStatus.GRADUATED, pageable).map(StudentResponseDto::new); } + + @Transactional(readOnly = true) + @Override + public StudentSchedulesResponseDto getSchedule(final StudentRequestDto request) { + final Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); + final List sugangs = student.get().getSugangs(); + final List schedule = new ArrayList<>(); + for (final Sugang sugang : sugangs) { + schedule.add(new StudentScheduleResponseDto(sugang)); + } + return new StudentSchedulesResponseDto(schedule); + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java index bc8baeb..27b5585 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java @@ -1,8 +1,6 @@ package jpabook.onboarding.sugang.controller.dto.response; import jakarta.validation.constraints.NotBlank; -import jpabook.onboarding.data.entity.Course; -import jpabook.onboarding.data.entity.Student; import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.status.SugangStatus; import lombok.AccessLevel; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java index a47718d..49828cd 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java @@ -32,7 +32,7 @@ public SugangResponseDto cancelSugang(final SugangRequestDto request, final Long return null; } final Optional sugang = repository.findByStudentAndCourse(student.get(), course.get()); - sugang.get().setStatus(SugangStatus.CANCELED); + sugang.get().updateStatus(SugangStatus.CANCELED); return new SugangResponseDto(sugang.get()); } diff --git a/taehyeon/onboarding/src/main/resources/application.yml b/taehyeon/onboarding/src/main/resources/application.yml index 5439d52..445bdae 100644 --- a/taehyeon/onboarding/src/main/resources/application.yml +++ b/taehyeon/onboarding/src/main/resources/application.yml @@ -12,7 +12,4 @@ spring: show_sql: true logging: level: - org: - hibernate: - orm.jdbc.bind : trace - + org.hibernate.orm.jdbc.bind: trace \ No newline at end of file From e32a0b4fab47d14a582da14cf4b9767a49b16fd1 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Tue, 26 Nov 2024 13:34:23 +0900 Subject: [PATCH 17/20] =?UTF-8?q?feat:=20=EA=B0=95=EC=9D=98=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taehyeon/onboarding/.gitignore | 1 + .../onboarding/data/entity/Course.java | 5 ++-- .../onboarding/data/entity/Student.java | 2 +- .../onboarding/data/status/CourseStatus.java | 2 +- .../onboarding/data/status/StudentStatus.java | 2 +- .../onboarding/data/status/SugangStatus.java | 2 +- .../student/controller/StudentController.java | 3 --- .../sugang/controller/SugangController.java | 12 +++++++++ .../dto/request/SugangRequestDto.java | 2 +- .../response/SugangCoursesResponseDto.java | 26 +++++++++++++++++++ .../sugang/service/SugangService.java | 6 +++++ .../sugang/service/SugangServiceImpl.java | 9 +++++++ 12 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangCoursesResponseDto.java diff --git a/taehyeon/onboarding/.gitignore b/taehyeon/onboarding/.gitignore index c2065bc..0d0cb25 100644 --- a/taehyeon/onboarding/.gitignore +++ b/taehyeon/onboarding/.gitignore @@ -16,6 +16,7 @@ build/ bin/ !**/src/main/**/bin/ !**/src/test/**/bin/ +./src/main/resources/** ### IntelliJ IDEA ### .idea diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index 33e2029..7386b43 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -16,7 +16,6 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; @Entity @Getter @@ -47,7 +46,7 @@ public class Course { @JdbcTypeCode(SqlTypes.VARCHAR) private CourseStatus status; - public Course(CourseRequestDto request) { + public Course(final CourseRequestDto request) { this.professorName = request.getProfessorName(); this.name = request.getName(); this.count = request.getCount(); @@ -55,7 +54,7 @@ public Course(CourseRequestDto request) { this.status = CourseStatus.REGISTERED; } - public Course(CourseUpdateRequestDto request) { + public Course(final CourseUpdateRequestDto request) { this.professorName = request.getProfessorName(); this.name = request.getName(); this.count = 0; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index c04dd1e..0b848cc 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -51,7 +51,7 @@ public class Student { @JdbcTypeCode(SqlTypes.VARCHAR) private StudentStatus status; - public Student(StudentRequestDto request) { + public Student(final StudentRequestDto request) { this.name = request.getName(); this.birth = request.getBirth(); this.status = StudentStatus.ENROLLED; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java index d6beb5d..29022c8 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java @@ -7,7 +7,7 @@ public enum CourseStatus { private final String status; - CourseStatus(String status) { + CourseStatus(final String status) { this.status = status; } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java index 2af562e..ee505dd 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java @@ -7,7 +7,7 @@ public enum StudentStatus { private final String status; - StudentStatus(String status) { + StudentStatus(final String status) { this.status = status; } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java index 5bd8267..01d8064 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java @@ -7,7 +7,7 @@ public enum SugangStatus { private final String status; - SugangStatus(String status) { + SugangStatus(final String status) { this.status = status; } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 773f408..d205307 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -1,7 +1,5 @@ package jpabook.onboarding.student.controller; -import java.util.List; - import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; @@ -16,7 +14,6 @@ import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; -import jpabook.onboarding.student.controller.dto.response.StudentScheduleResponseDto; import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; import jpabook.onboarding.student.service.StudentService; import lombok.RequiredArgsConstructor; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java index 0c57568..39fe548 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java @@ -1,15 +1,20 @@ package jpabook.onboarding.sugang.controller; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; +import jpabook.onboarding.sugang.controller.dto.response.SugangCoursesResponseDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; import jpabook.onboarding.sugang.service.SugangService; import lombok.RequiredArgsConstructor; @@ -33,4 +38,11 @@ public ResponseEntity cancelSugang(@RequestBody final SugangR final SugangResponseDto response = service.cancelSugang(request, courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } + + @GetMapping + public ResponseEntity> getCourses(@RequestParam(defaultValue = "0") final int page) { + final PageRequest pageRequest = PageRequest.of(page, 5); + final Page response = service.getCourses(pageRequest); + return ResponseEntity.status(HttpStatus.OK).body(response); + } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java index 7611522..04092f0 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/request/SugangRequestDto.java @@ -16,4 +16,4 @@ public class SugangRequestDto { @NotNull(message = "생일은 필수입니다.") private final LocalDate birth; -} +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangCoursesResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangCoursesResponseDto.java new file mode 100644 index 0000000..0e6af05 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangCoursesResponseDto.java @@ -0,0 +1,26 @@ +package jpabook.onboarding.sugang.controller.dto.response; + +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.status.CourseStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class SugangCoursesResponseDto { + + private final String courseName; + private final String professorName; + private final int count; + private final int grade; + private final CourseStatus status; + + public SugangCoursesResponseDto(final Course course) { + this.courseName = course.getName(); + this.professorName = course.getProfessorName(); + this.count = course.getCount(); + this.grade = course.getGrade(); + this.status = course.getStatus(); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java index 371ab91..60db030 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java @@ -1,10 +1,16 @@ package jpabook.onboarding.sugang.service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; +import jpabook.onboarding.sugang.controller.dto.response.SugangCoursesResponseDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; public interface SugangService { SugangResponseDto createSugang(SugangRequestDto request, Long courseId); SugangResponseDto cancelSugang(SugangRequestDto request, Long courseId); + + Page getCourses(Pageable pageable); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java index 49828cd..94fa04f 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java @@ -2,6 +2,8 @@ import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,6 +15,7 @@ import jpabook.onboarding.data.repository.SugangRepository; import jpabook.onboarding.data.status.SugangStatus; import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; +import jpabook.onboarding.sugang.controller.dto.response.SugangCoursesResponseDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; import lombok.RequiredArgsConstructor; @@ -47,4 +50,10 @@ public SugangResponseDto createSugang(final SugangRequestDto request, final Long repository.save(sugang); return new SugangResponseDto(sugang); } + + @Transactional(readOnly = true) + @Override + public Page getCourses(final Pageable pageable) { + return courseRepository.findAll(pageable).map(SugangCoursesResponseDto::new); + } } From 020fc5355e1c453061d58eceb91ff3a823e488a3 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Wed, 27 Nov 2024 15:03:42 +0900 Subject: [PATCH 18/20] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../course/controller/CourseController.java | 15 +++--- .../dto/request/CourseUpdateRequestDto.java | 5 +- .../course/service/CourseServiceImpl.java | 48 ++++++++++-------- .../onboarding/data/entity/Student.java | 1 + .../data/repository/CourseRepository.java | 7 +++ .../onboarding/data/status/CourseStatus.java | 13 ++--- .../onboarding/data/status/StudentStatus.java | 13 ++--- .../onboarding/data/status/SugangStatus.java | 13 ++--- .../onboarding/exception/CustomError.java | 18 +++++++ .../onboarding/exception/CustomException.java | 10 ++++ .../controller/CustomExceptionHandler.java | 50 +++++++++++++++++++ .../controller/dto/ErrorResponseDto.java | 18 +++++++ .../student/controller/StudentController.java | 28 +++++++---- .../student/service/StudentService.java | 4 +- .../student/service/StudentServiceImpl.java | 35 ++++++++----- .../sugang/controller/SugangController.java | 20 +++++--- .../dto/response/SugangResponseDto.java | 4 -- .../sugang/service/SugangService.java | 4 +- .../sugang/service/SugangServiceImpl.java | 43 +++++++++------- .../jpabook/onboarding/util/PageConfig.java | 12 +++++ .../util/dto/response/PageResponseDto.java | 12 +++++ 21 files changed, 260 insertions(+), 113 deletions(-) create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomException.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/CustomExceptionHandler.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/dto/ErrorResponseDto.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/util/PageConfig.java create mode 100644 taehyeon/onboarding/src/main/java/jpabook/onboarding/util/dto/response/PageResponseDto.java diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java index f9b5ab1..e1628ff 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/CourseController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; @@ -20,30 +21,30 @@ @RequestMapping("/courses") @RequiredArgsConstructor public class CourseController { - private final CourseService service; + private final CourseService courseService; @PostMapping - public ResponseEntity createCourse(@RequestBody final CourseRequestDto request) { - final CourseResponseDto response = service.create(request); + public ResponseEntity createCourse(@Valid @RequestBody final CourseRequestDto request) { + final CourseResponseDto response = courseService.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @PutMapping("/{courseId}") public ResponseEntity updateCourse(@PathVariable final Long courseId, - @RequestBody final CourseUpdateRequestDto request) { - final CourseResponseDto response = service.update(courseId, request); + @Valid @RequestBody final CourseUpdateRequestDto request) { + final CourseResponseDto response = courseService.update(courseId, request); return ResponseEntity.status(HttpStatus.OK).body(response); } @PatchMapping("/delete/{courseId}") public ResponseEntity deleteCourse(@PathVariable final Long courseId) { - final CourseResponseDto response = service.delete(courseId); + final CourseResponseDto response = courseService.delete(courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } @PatchMapping("/complete/{courseId}") public ResponseEntity completeCourse(@PathVariable final Long courseId) { - final CourseResponseDto response = service.complete(courseId); + final CourseResponseDto response = courseService.complete(courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java index 7402c3d..1872662 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseUpdateRequestDto.java @@ -1,6 +1,7 @@ package jpabook.onboarding.course.controller.dto.request; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jpabook.onboarding.data.status.CourseStatus; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -15,9 +16,9 @@ public class CourseUpdateRequestDto { @NotBlank(message = "강의 이름은 필수입니다.") private final String name; - @NotBlank(message = "학점은 필수입니다.") + @NotNull(message = "학점은 필수입니다.") private final int grade; - @NotBlank(message = "강의 상태는 필수입니다.") + @NotNull(message = "강의 상태는 필수입니다.") private final CourseStatus status; } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java index 883c4cc..b589806 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -1,7 +1,5 @@ package jpabook.onboarding.course.service; -import java.util.Optional; - import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -11,52 +9,58 @@ import jpabook.onboarding.data.entity.Course; import jpabook.onboarding.data.repository.CourseRepository; import jpabook.onboarding.data.status.CourseStatus; +import jpabook.onboarding.exception.CustomError; +import jpabook.onboarding.exception.CustomException; import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class CourseServiceImpl implements CourseService { - private final CourseRepository repository; + private final CourseRepository courseRepository; @Override public CourseResponseDto create(final CourseRequestDto request) { + if (courseRepository.findByNameAndProfessorName(request.getName(), request.getProfessorName()).isPresent()) { + throw new CustomException(CustomError.CONFLICT); + } final Course course = new Course(request); - repository.save(course); + courseRepository.save(course); return new CourseResponseDto(course); } @Transactional @Override - public CourseResponseDto complete(final Long courseId) { - final Optional course = repository.findById(courseId); - if (course.isEmpty()) { - return null; + public CourseResponseDto update(final Long courseId, final CourseUpdateRequestDto request) { + if (request.getStatus() == CourseStatus.COMPLETED + || courseRepository.findByNameAndProfessorNameAndGradeAndStatus(request.getName(), + request.getProfessorName(), request.getGrade(), request.getStatus()).isPresent()) { + throw new CustomException(CustomError.CONFLICT); } - course.get().updateStatus(CourseStatus.COMPLETED); - return new CourseResponseDto(course.get()); + final Course course = courseRepository.findById(courseId).orElseThrow(); + course.update(request); + return new CourseResponseDto(course); } @Transactional @Override - public CourseResponseDto update(final Long courseId, final CourseUpdateRequestDto request) { - final Optional course = repository.findById(courseId); - if (course.isEmpty()) { - final Course newCourse = repository.save(new Course(request)); - return new CourseResponseDto(newCourse); + public CourseResponseDto complete(final Long courseId) { + final Course course = courseRepository.findById(courseId).orElseThrow(); + if (course.getStatus() == CourseStatus.COMPLETED) { + throw new CustomException(CustomError.CONFLICT); } - course.get().update(request); - return new CourseResponseDto(course.get()); + course.updateStatus(CourseStatus.COMPLETED); + return new CourseResponseDto(course); } @Transactional @Override public CourseResponseDto delete(final Long courseId) { - final Optional course = repository.findById(courseId); - if (course.isEmpty()) { - return null; + final Course course = courseRepository.findById(courseId).orElseThrow(); + if (course.getStatus() == CourseStatus.DELETED || course.getStatus() == CourseStatus.COMPLETED) { + throw new CustomException(CustomError.CONFLICT); } - course.get().updateStatus(CourseStatus.DELETED); - return new CourseResponseDto(course.get()); + course.updateStatus(CourseStatus.DELETED); + return new CourseResponseDto(course); } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index 0b848cc..135bce4 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -26,6 +26,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Student { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "student_id") diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java index 239eb71..fb05b16 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java @@ -1,10 +1,17 @@ package jpabook.onboarding.data.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.status.CourseStatus; @Repository public interface CourseRepository extends JpaRepository { + Optional findByNameAndProfessorName(String name, String professorName); + + Optional findByNameAndProfessorNameAndGradeAndStatus(String name, String professorName, int grade, + CourseStatus status); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java index 29022c8..f2930cf 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/CourseStatus.java @@ -1,17 +1,14 @@ package jpabook.onboarding.data.status; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor public enum CourseStatus { REGISTERED("등록"), DELETED("삭제"), COMPLETED("완료"); private final String status; - - CourseStatus(final String status) { - this.status = status; - } - - public String getStatus() { - return status; - } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java index ee505dd..fe9adac 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/StudentStatus.java @@ -1,17 +1,14 @@ package jpabook.onboarding.data.status; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor public enum StudentStatus { ENROLLED("재학"), DROP("중퇴"), GRADUATED("졸업"); private final String status; - - StudentStatus(final String status) { - this.status = status; - } - - public String getStatus() { - return status; - } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java index 01d8064..c289339 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/status/SugangStatus.java @@ -1,17 +1,14 @@ package jpabook.onboarding.data.status; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor public enum SugangStatus { ONGOING("진행중"), CANCELED("취소"), COMPLETED("완료"); private final String status; - - SugangStatus(final String status) { - this.status = status; - } - - public String getStatus() { - return status; - } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java new file mode 100644 index 0000000..3323bf3 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java @@ -0,0 +1,18 @@ +package jpabook.onboarding.exception; + +import org.springframework.http.HttpStatus; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum CustomError { + BAD_REQUEST(HttpStatus.BAD_REQUEST, "잘못된 요청 입니다."), + NOT_FOUND(HttpStatus.NOT_FOUND, "찾을수 없습니다."), + METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "없는 메서드 입니다."), + CONFLICT(HttpStatus.CONFLICT, "중복 오류입니다."); + + private final HttpStatus status; + private final String message; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomException.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomException.java new file mode 100644 index 0000000..330fc4a --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomException.java @@ -0,0 +1,10 @@ +package jpabook.onboarding.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class CustomException extends RuntimeException { + private final CustomError error; +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/CustomExceptionHandler.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/CustomExceptionHandler.java new file mode 100644 index 0000000..843c4e8 --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/CustomExceptionHandler.java @@ -0,0 +1,50 @@ +package jpabook.onboarding.exception.controller; + +import java.util.NoSuchElementException; + +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +import jpabook.onboarding.exception.CustomError; +import jpabook.onboarding.exception.CustomException; +import jpabook.onboarding.exception.controller.dto.ErrorResponseDto; + +@ControllerAdvice +public class CustomExceptionHandler { + @ExceptionHandler(CustomException.class) + protected ResponseEntity handleCustom400Exception(final CustomException exception) { + return ErrorResponseDto.toResponseEntity(exception); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + protected HttpEntity handleMethodArgumentNotValidException( + final MethodArgumentNotValidException exception) { + return ErrorResponseDto.toResponseEntity(new CustomException(CustomError.BAD_REQUEST)); + } + + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + protected HttpEntity handleMethodArgumentTypeMismatchException( + final MethodArgumentTypeMismatchException exception) { + return ErrorResponseDto.toResponseEntity(new CustomException(CustomError.BAD_REQUEST)); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + protected HttpEntity handleHttpMessageNotReadableException(final Exception exception) { + return ErrorResponseDto.toResponseEntity(new CustomException(CustomError.BAD_REQUEST)); + } + + @ExceptionHandler(NoSuchElementException.class) + protected HttpEntity handleNoSuchElementException(final Exception exception) { + return ErrorResponseDto.toResponseEntity(new CustomException(CustomError.NOT_FOUND)); + } + + // @ExceptionHandler(Exception.class) + // protected HttpEntity handleException(final Exception exception) { + // return ErrorResponseDto.toResponseEntity(new CustomException(CustomError.NOT_FOUND)); + // } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/dto/ErrorResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/dto/ErrorResponseDto.java new file mode 100644 index 0000000..09b693d --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/controller/dto/ErrorResponseDto.java @@ -0,0 +1,18 @@ +package jpabook.onboarding.exception.controller.dto; + +import org.springframework.http.ResponseEntity; + +import jpabook.onboarding.exception.CustomException; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ErrorResponseDto { + private final String message; + + public static ResponseEntity toResponseEntity(final CustomException exception) { + return ResponseEntity.status(exception.getError().getStatus()) + .body(new ErrorResponseDto(exception.getError().getMessage())); + } +} diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index d205307..912dd8b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -1,6 +1,5 @@ package jpabook.onboarding.student.controller; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -12,10 +11,14 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; +import jpabook.onboarding.data.status.StudentStatus; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; import jpabook.onboarding.student.service.StudentService; +import jpabook.onboarding.util.PageConfig; +import jpabook.onboarding.util.dto.response.PageResponseDto; import lombok.RequiredArgsConstructor; @RestController @@ -23,30 +26,33 @@ @RequiredArgsConstructor public class StudentController { - private final StudentService service; + private final StudentService studentService; @PostMapping - public ResponseEntity createStudent(@RequestBody final StudentRequestDto request) { - final StudentResponseDto response = service.create(request); + public ResponseEntity createStudent(@Valid @RequestBody final StudentRequestDto request) { + final StudentResponseDto response = studentService.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); + } @PatchMapping("/drop") - public ResponseEntity dropStudent(@RequestBody final StudentRequestDto request) { - final StudentResponseDto response = service.drop(request); + public ResponseEntity dropStudent(@Valid @RequestBody final StudentRequestDto request) { + final StudentResponseDto response = studentService.drop(request); return ResponseEntity.status(HttpStatus.OK).body(response); } @GetMapping("/graduated") - public ResponseEntity> getGraduates(@RequestParam(defaultValue = "0") final int page) { - final PageRequest pageRequest = PageRequest.of(page, 5); - final Page response = service.getGraduates(pageRequest); + public ResponseEntity> getGraduates( + @RequestParam(defaultValue = "0") final int page) { + final PageRequest pageRequest = PageRequest.of(page, PageConfig.SIZE.getSize()); + final PageResponseDto response = studentService.getGraduates(pageRequest); return ResponseEntity.status(HttpStatus.OK).body(response); } @GetMapping("/schedule") - public ResponseEntity getSchedule(@RequestBody final StudentRequestDto request) { - final StudentSchedulesResponseDto response = service.getSchedule(request); + public ResponseEntity getSchedule( + @Valid @RequestBody final StudentRequestDto request) { + final StudentSchedulesResponseDto response = studentService.getSchedule(request); return ResponseEntity.status(HttpStatus.OK).body(response); } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java index cf3a257..25567dc 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentService.java @@ -1,18 +1,18 @@ package jpabook.onboarding.student.service; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; +import jpabook.onboarding.util.dto.response.PageResponseDto; public interface StudentService { StudentResponseDto create(StudentRequestDto request); StudentResponseDto drop(StudentRequestDto request); - Page getGraduates(Pageable pageable); + PageResponseDto getGraduates(Pageable pageable); StudentSchedulesResponseDto getSchedule(StudentRequestDto request); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 4d76255..418ea3f 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -2,9 +2,7 @@ import java.util.ArrayList; import java.util.List; -import java.util.Optional; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,46 +11,57 @@ import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.status.StudentStatus; +import jpabook.onboarding.exception.CustomError; +import jpabook.onboarding.exception.CustomException; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; import jpabook.onboarding.student.controller.dto.response.StudentScheduleResponseDto; import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; +import jpabook.onboarding.util.dto.response.PageResponseDto; import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class StudentServiceImpl implements StudentService { - private final StudentRepository repository; + private final StudentRepository studentRepository; @Override public StudentResponseDto create(final StudentRequestDto request) { + if (studentRepository.findByNameAndBirth(request.getName(), request.getBirth()).isPresent()) { + throw new CustomException(CustomError.CONFLICT); + } final Student student = new Student(request); - repository.save(student); + studentRepository.save(student); return new StudentResponseDto(student); } @Transactional @Override public StudentResponseDto drop(final StudentRequestDto request) { - final Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); - if (student.isEmpty()) { - return null; + final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) + .orElseThrow(); + if (student.getStatus() == StudentStatus.DROP) { + throw new CustomException(CustomError.CONFLICT); } - student.get().updateStatus(StudentStatus.DROP); - return new StudentResponseDto(student.get()); + student.updateStatus(StudentStatus.DROP); + return new StudentResponseDto(student); } @Transactional(readOnly = true) @Override - public Page getGraduates(final Pageable pageable) { - return repository.findAllByStatus(StudentStatus.GRADUATED, pageable).map(StudentResponseDto::new); + public PageResponseDto getGraduates(final Pageable pageable) { + final List content = studentRepository.findAllByStatus(StudentStatus.GRADUATED, pageable) + .map(StudentResponseDto::new) + .getContent(); + return new PageResponseDto<>(content); } @Transactional(readOnly = true) @Override public StudentSchedulesResponseDto getSchedule(final StudentRequestDto request) { - final Optional student = repository.findByNameAndBirth(request.getName(), request.getBirth()); - final List sugangs = student.get().getSugangs(); + final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) + .orElseThrow(); + final List sugangs = student.getSugangs(); final List schedule = new ArrayList<>(); for (final Sugang sugang : sugangs) { schedule.add(new StudentScheduleResponseDto(sugang)); diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java index 39fe548..60b4478 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/SugangController.java @@ -13,36 +13,40 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; import jpabook.onboarding.sugang.controller.dto.response.SugangCoursesResponseDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; import jpabook.onboarding.sugang.service.SugangService; +import jpabook.onboarding.util.PageConfig; +import jpabook.onboarding.util.dto.response.PageResponseDto; import lombok.RequiredArgsConstructor; @RestController @RequestMapping("/sugangs") @RequiredArgsConstructor public class SugangController { - private final SugangService service; + private final SugangService sugangService; @PostMapping("/{courseId}") - public ResponseEntity createSugang(@RequestBody final SugangRequestDto request, + public ResponseEntity createSugang(@Valid @RequestBody final SugangRequestDto request, @PathVariable final Long courseId) { - final SugangResponseDto response = service.createSugang(request, courseId); + final SugangResponseDto response = sugangService.createSugang(request, courseId); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @PatchMapping("/{courseId}") - public ResponseEntity cancelSugang(@RequestBody final SugangRequestDto request, + public ResponseEntity cancelSugang(@Valid @RequestBody final SugangRequestDto request, @PathVariable final Long courseId) { - final SugangResponseDto response = service.cancelSugang(request, courseId); + final SugangResponseDto response = sugangService.cancelSugang(request, courseId); return ResponseEntity.status(HttpStatus.OK).body(response); } @GetMapping - public ResponseEntity> getCourses(@RequestParam(defaultValue = "0") final int page) { - final PageRequest pageRequest = PageRequest.of(page, 5); - final Page response = service.getCourses(pageRequest); + public ResponseEntity> getCourses( + @RequestParam(defaultValue = "0") final int page) { + final PageRequest pageRequest = PageRequest.of(page, PageConfig.SIZE.getSize()); + final PageResponseDto response = sugangService.getCourses(pageRequest); return ResponseEntity.status(HttpStatus.OK).body(response); } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java index 27b5585..0a0eeb1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/controller/dto/response/SugangResponseDto.java @@ -1,6 +1,5 @@ package jpabook.onboarding.sugang.controller.dto.response; -import jakarta.validation.constraints.NotBlank; import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.status.SugangStatus; import lombok.AccessLevel; @@ -10,10 +9,7 @@ @Getter @AllArgsConstructor(access = AccessLevel.PROTECTED) public class SugangResponseDto { - @NotBlank(message = "과목 이름은 필수입니다.") private final String courseName; - - @NotBlank(message = "수강 상태는 필수입니다.") private final SugangStatus status; public SugangResponseDto(final Sugang sugang) { diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java index 60db030..8abc51d 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangService.java @@ -1,16 +1,16 @@ package jpabook.onboarding.sugang.service; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; import jpabook.onboarding.sugang.controller.dto.response.SugangCoursesResponseDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; +import jpabook.onboarding.util.dto.response.PageResponseDto; public interface SugangService { SugangResponseDto createSugang(SugangRequestDto request, Long courseId); SugangResponseDto cancelSugang(SugangRequestDto request, Long courseId); - Page getCourses(Pageable pageable); + PageResponseDto getCourses(Pageable pageable); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java index 94fa04f..0386f53 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java @@ -1,8 +1,7 @@ package jpabook.onboarding.sugang.service; -import java.util.Optional; +import java.util.List; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,46 +13,54 @@ import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.repository.SugangRepository; import jpabook.onboarding.data.status.SugangStatus; +import jpabook.onboarding.exception.CustomError; +import jpabook.onboarding.exception.CustomException; import jpabook.onboarding.sugang.controller.dto.request.SugangRequestDto; import jpabook.onboarding.sugang.controller.dto.response.SugangCoursesResponseDto; import jpabook.onboarding.sugang.controller.dto.response.SugangResponseDto; +import jpabook.onboarding.util.dto.response.PageResponseDto; import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class SugangServiceImpl implements SugangService { - private final SugangRepository repository; + private final SugangRepository sugangRepository; private final StudentRepository studentRepository; private final CourseRepository courseRepository; @Transactional @Override public SugangResponseDto cancelSugang(final SugangRequestDto request, final Long courseId) { - final Optional student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()); - final Optional course = courseRepository.findById(courseId); - if (student.isEmpty() || course.isEmpty()) { - return null; + final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) + .orElseThrow(); + final Course course = courseRepository.findById(courseId).orElseThrow(); + final Sugang sugang = sugangRepository.findByStudentAndCourse(student, course).orElseThrow(); + if (sugang.getStatus() == SugangStatus.CANCELED) { + throw new CustomException(CustomError.CONFLICT); } - final Optional sugang = repository.findByStudentAndCourse(student.get(), course.get()); - sugang.get().updateStatus(SugangStatus.CANCELED); - return new SugangResponseDto(sugang.get()); + sugang.updateStatus(SugangStatus.CANCELED); + return new SugangResponseDto(sugang); } @Override public SugangResponseDto createSugang(final SugangRequestDto request, final Long courseId) { - final Optional student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()); - final Optional course = courseRepository.findById(courseId); - if (student.isEmpty() || course.isEmpty()) { - return null; + final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) + .orElseThrow(); + final Course course = courseRepository.findById(courseId).orElseThrow(); + if (sugangRepository.findByStudentAndCourse(student, course).isPresent()) { + throw new CustomException(CustomError.CONFLICT); } - final Sugang sugang = new Sugang(student.get(), course.get()); - repository.save(sugang); + final Sugang sugang = new Sugang(student, course); + sugangRepository.save(sugang); return new SugangResponseDto(sugang); } @Transactional(readOnly = true) @Override - public Page getCourses(final Pageable pageable) { - return courseRepository.findAll(pageable).map(SugangCoursesResponseDto::new); + public PageResponseDto getCourses(final Pageable pageable) { + final List content = courseRepository.findAll(pageable) + .map(SugangCoursesResponseDto::new) + .getContent(); + return new PageResponseDto<>(content); } } diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/util/PageConfig.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/util/PageConfig.java new file mode 100644 index 0000000..4dad65e --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/util/PageConfig.java @@ -0,0 +1,12 @@ +package jpabook.onboarding.util; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum PageConfig { + SIZE(5); + + private final int size; +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/util/dto/response/PageResponseDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/util/dto/response/PageResponseDto.java new file mode 100644 index 0000000..91d085d --- /dev/null +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/util/dto/response/PageResponseDto.java @@ -0,0 +1,12 @@ +package jpabook.onboarding.util.dto.response; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PageResponseDto { + private final List content; +} From 49eef94edc31330f4499c2285499e4b58b0c7841 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Mon, 2 Dec 2024 12:04:36 +0900 Subject: [PATCH 19/20] =?UTF-8?q?feat:=20=EC=83=81=EC=84=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/CourseRequestDto.java | 3 +- .../course/service/CourseServiceImpl.java | 46 +++++++++++++------ .../onboarding/data/entity/Course.java | 9 ++++ .../onboarding/data/entity/Student.java | 28 +++++++++-- .../data/repository/CourseRepository.java | 5 +- .../data/repository/StudentRepository.java | 2 + .../data/repository/SugangRepository.java | 4 ++ .../onboarding/exception/CustomError.java | 21 ++++++++- .../student/controller/StudentController.java | 2 - .../student/service/StudentServiceImpl.java | 20 ++++++-- .../sugang/service/SugangServiceImpl.java | 27 +++++++---- 11 files changed, 129 insertions(+), 38 deletions(-) diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java index 7bbdba3..eedced2 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java @@ -1,6 +1,7 @@ package jpabook.onboarding.course.controller.dto.request; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,6 +15,6 @@ public class CourseRequestDto { @NotBlank(message = "강의 이름은 필수입니다.") private final String name; - @NotBlank(message = "현재 수강 인원은 필수입니다.") + @NotNull(message = "현재 수강 인원은 필수입니다.") private final int count; } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java index b589806..c51d4bd 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/service/CourseServiceImpl.java @@ -1,5 +1,7 @@ package jpabook.onboarding.course.service; +import java.util.List; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -7,8 +9,11 @@ import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.repository.CourseRepository; +import jpabook.onboarding.data.repository.SugangRepository; import jpabook.onboarding.data.status.CourseStatus; +import jpabook.onboarding.data.status.SugangStatus; import jpabook.onboarding.exception.CustomError; import jpabook.onboarding.exception.CustomException; import lombok.RequiredArgsConstructor; @@ -17,11 +22,12 @@ @RequiredArgsConstructor public class CourseServiceImpl implements CourseService { private final CourseRepository courseRepository; + private final SugangRepository sugangRepository; @Override public CourseResponseDto create(final CourseRequestDto request) { if (courseRepository.findByNameAndProfessorName(request.getName(), request.getProfessorName()).isPresent()) { - throw new CustomException(CustomError.CONFLICT); + throw new CustomException(CustomError.COURSE_CREATE); } final Course course = new Course(request); courseRepository.save(course); @@ -31,12 +37,16 @@ public CourseResponseDto create(final CourseRequestDto request) { @Transactional @Override public CourseResponseDto update(final Long courseId, final CourseUpdateRequestDto request) { - if (request.getStatus() == CourseStatus.COMPLETED - || courseRepository.findByNameAndProfessorNameAndGradeAndStatus(request.getName(), - request.getProfessorName(), request.getGrade(), request.getStatus()).isPresent()) { - throw new CustomException(CustomError.CONFLICT); + final Course course = courseRepository.findById(courseId) + .orElseThrow(() -> new CustomException(CustomError.COURSE_NOT_FOUND)); + if (course.getStatus() != request.getStatus()) { + if (request.getStatus() == CourseStatus.COMPLETED) { + complete(courseId); + } + if (request.getStatus() == CourseStatus.DELETED) { + delete(courseId); + } } - final Course course = courseRepository.findById(courseId).orElseThrow(); course.update(request); return new CourseResponseDto(course); } @@ -44,9 +54,14 @@ public CourseResponseDto update(final Long courseId, final CourseUpdateRequestDt @Transactional @Override public CourseResponseDto complete(final Long courseId) { - final Course course = courseRepository.findById(courseId).orElseThrow(); - if (course.getStatus() == CourseStatus.COMPLETED) { - throw new CustomException(CustomError.CONFLICT); + final Course course = courseRepository.findById(courseId) + .orElseThrow(() -> new CustomException(CustomError.COURSE_NOT_FOUND)); + if (course.getStatus() != CourseStatus.REGISTERED) { + throw new CustomException(CustomError.COURSE_COMPLETE); + } + final List sugangs = sugangRepository.findAllByCourseIdAndStatus(courseId, SugangStatus.ONGOING); + for (final Sugang sugang : sugangs) { + sugang.getStudent().addTotalGrade(course.getGrade()); } course.updateStatus(CourseStatus.COMPLETED); return new CourseResponseDto(course); @@ -55,12 +70,17 @@ public CourseResponseDto complete(final Long courseId) { @Transactional @Override public CourseResponseDto delete(final Long courseId) { - final Course course = courseRepository.findById(courseId).orElseThrow(); - if (course.getStatus() == CourseStatus.DELETED || course.getStatus() == CourseStatus.COMPLETED) { - throw new CustomException(CustomError.CONFLICT); + final Course course = courseRepository.findById(courseId) + .orElseThrow(() -> new CustomException(CustomError.COURSE_NOT_FOUND)); + if (course.getStatus() != CourseStatus.REGISTERED) { + throw new CustomException(CustomError.COURSE_DELETE); + } + final List sugangs = sugangRepository.findAllByCourseIdAndStatus(courseId, SugangStatus.ONGOING); + for (final Sugang sugang : sugangs) { + sugang.updateStatus(SugangStatus.CANCELED); + sugang.getStudent().addCurrentGrade(-course.getGrade()); } course.updateStatus(CourseStatus.DELETED); return new CourseResponseDto(course); - } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index 7386b43..76cab55 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -13,6 +13,8 @@ import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; import jpabook.onboarding.course.controller.dto.request.CourseUpdateRequestDto; import jpabook.onboarding.data.status.CourseStatus; +import jpabook.onboarding.exception.CustomError; +import jpabook.onboarding.exception.CustomException; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -72,4 +74,11 @@ public void update(final CourseUpdateRequestDto request) { this.professorName = request.getProfessorName(); this.status = request.getStatus(); } + + public void addCount(final int count) { + if (this.count + count > MAX_COUNT) { + throw new CustomException(CustomError.BAD_REQUEST); + } + this.count += count; + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java index 135bce4..73827d3 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Student.java @@ -1,8 +1,8 @@ package jpabook.onboarding.data.entity; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; @@ -17,6 +17,8 @@ import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import jpabook.onboarding.data.status.StudentStatus; +import jpabook.onboarding.exception.CustomError; +import jpabook.onboarding.exception.CustomException; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import lombok.AccessLevel; import lombok.Getter; @@ -27,13 +29,16 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Student { + private static final int MAX_CURRENT_GRADE = 15; + private static final int MAX_TOTAL_GRADE = 60; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "student_id") private Long id; @OneToMany(mappedBy = "student", cascade = CascadeType.ALL) - private List sugangs = new ArrayList<>(); + private Set sugangs = new HashSet<>(); @Column(nullable = false) private String name; @@ -61,4 +66,21 @@ public Student(final StudentRequestDto request) { public void updateStatus(final StudentStatus status) { this.status = status; } + + public void addCurrentGrade(final int grade) { + if (this.currentGrade + grade > MAX_CURRENT_GRADE) { + throw new CustomException(CustomError.BAD_REQUEST); + } + this.currentGrade += grade; + } + + public void addTotalGrade(final int grade) { + if (this.totalGrade == MAX_TOTAL_GRADE) { + throw new CustomException(CustomError.BAD_REQUEST); + } + this.totalGrade = Integer.min(this.totalGrade + grade, MAX_TOTAL_GRADE); + if (this.totalGrade == MAX_TOTAL_GRADE) { + this.status = StudentStatus.GRADUATED; + } + } } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java index fb05b16..b3fe02b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/CourseRepository.java @@ -10,8 +10,7 @@ @Repository public interface CourseRepository extends JpaRepository { - Optional findByNameAndProfessorName(String name, String professorName); + Optional findByIdAndStatus(Long id, CourseStatus status); - Optional findByNameAndProfessorNameAndGradeAndStatus(String name, String professorName, int grade, - CourseStatus status); + Optional findByNameAndProfessorName(String name, String professorName); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java index 94667cd..a9b1a5d 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/StudentRepository.java @@ -15,5 +15,7 @@ public interface StudentRepository extends JpaRepository { Optional findByNameAndBirth(String name, LocalDate birth); + Optional findByNameAndBirthAndStatus(String name, LocalDate birth, StudentStatus status); + Page findAllByStatus(StudentStatus status, Pageable pageable); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java index 6127b52..cfcb937 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/repository/SugangRepository.java @@ -1,5 +1,6 @@ package jpabook.onboarding.data.repository; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -8,8 +9,11 @@ import jpabook.onboarding.data.entity.Course; import jpabook.onboarding.data.entity.Student; import jpabook.onboarding.data.entity.Sugang; +import jpabook.onboarding.data.status.SugangStatus; @Repository public interface SugangRepository extends JpaRepository { Optional findByStudentAndCourse(Student student, Course course); + + List findAllByCourseIdAndStatus(Long courseId, SugangStatus status); } \ No newline at end of file diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java index 3323bf3..5a6dd93 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/exception/CustomError.java @@ -8,10 +8,27 @@ @Getter @AllArgsConstructor public enum CustomError { + //공통 에러 BAD_REQUEST(HttpStatus.BAD_REQUEST, "잘못된 요청 입니다."), - NOT_FOUND(HttpStatus.NOT_FOUND, "찾을수 없습니다."), + NOT_FOUND(HttpStatus.NOT_FOUND, "찾을 수 없습니다."), METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "없는 메서드 입니다."), - CONFLICT(HttpStatus.CONFLICT, "중복 오류입니다."); + CONFLICT(HttpStatus.CONFLICT, "중복 오류입니다."), + + //학생 에러 + STUDENT_NOT_FOUND(HttpStatus.NOT_FOUND, "학생을 찾을 수 없습니다."), + STUDENT_CREATE(HttpStatus.CONFLICT, "이미 등록된 학생입니다.,"), + STUDENT_DROP(HttpStatus.CONFLICT, "이미 중퇴한 학생입니다."), + + //강의 에러 + COURSE_NOT_FOUND(HttpStatus.NOT_FOUND, "강의를 찾을 수 없습니다."), + COURSE_CREATE(HttpStatus.CONFLICT, "이미 등록된 강의입니다."), + COURSE_COMPLETE(HttpStatus.CONFLICT,"이미 완료된 강의입니다."), + COURSE_DELETE(HttpStatus.CONFLICT,"이미 삭제된 강의입니다."), + + //수강 에러 + SUGANG_NOT_FOUND(HttpStatus.NOT_FOUND, "수강을 찾을 수 없습니다."), + SUGANG_CREATE(HttpStatus.CONFLICT, "이미 등록된 수강입니다,"), + SUGANG_CANCEL(HttpStatus.CONFLICT, "이미 취소된 수강입니다."); private final HttpStatus status; private final String message; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java index 912dd8b..3eacaf0 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/controller/StudentController.java @@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.RestController; import jakarta.validation.Valid; -import jpabook.onboarding.data.status.StudentStatus; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; import jpabook.onboarding.student.controller.dto.response.StudentResponseDto; import jpabook.onboarding.student.controller.dto.response.StudentSchedulesResponseDto; @@ -32,7 +31,6 @@ public class StudentController { public ResponseEntity createStudent(@Valid @RequestBody final StudentRequestDto request) { final StudentResponseDto response = studentService.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); - } @PatchMapping("/drop") diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java index 418ea3f..9e0707b 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/student/service/StudentServiceImpl.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -11,6 +12,7 @@ import jpabook.onboarding.data.entity.Sugang; import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.status.StudentStatus; +import jpabook.onboarding.data.status.SugangStatus; import jpabook.onboarding.exception.CustomError; import jpabook.onboarding.exception.CustomException; import jpabook.onboarding.student.controller.dto.request.StudentRequestDto; @@ -28,7 +30,7 @@ public class StudentServiceImpl implements StudentService { @Override public StudentResponseDto create(final StudentRequestDto request) { if (studentRepository.findByNameAndBirth(request.getName(), request.getBirth()).isPresent()) { - throw new CustomException(CustomError.CONFLICT); + throw new CustomException(CustomError.STUDENT_CREATE); } final Student student = new Student(request); studentRepository.save(student); @@ -39,9 +41,17 @@ public StudentResponseDto create(final StudentRequestDto request) { @Override public StudentResponseDto drop(final StudentRequestDto request) { final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) - .orElseThrow(); + .orElseThrow(() -> new CustomException(CustomError.STUDENT_NOT_FOUND)); if (student.getStatus() == StudentStatus.DROP) { - throw new CustomException(CustomError.CONFLICT); + throw new CustomException(CustomError.STUDENT_DROP); + } + final Set sugangs = student.getSugangs(); + for (final Sugang sugang : sugangs) { + if (sugang.getStatus() == SugangStatus.ONGOING) { + sugang.updateStatus(SugangStatus.CANCELED); + sugang.getCourse().addCount(-1); + student.addCurrentGrade(sugang.getCourse().getGrade()); + } } student.updateStatus(StudentStatus.DROP); return new StudentResponseDto(student); @@ -60,8 +70,8 @@ public PageResponseDto getGraduates(final Pageable pageable) @Override public StudentSchedulesResponseDto getSchedule(final StudentRequestDto request) { final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) - .orElseThrow(); - final List sugangs = student.getSugangs(); + .orElseThrow(() -> new CustomException(CustomError.STUDENT_NOT_FOUND)); + final Set sugangs = student.getSugangs(); final List schedule = new ArrayList<>(); for (final Sugang sugang : sugangs) { schedule.add(new StudentScheduleResponseDto(sugang)); diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java index 0386f53..6353a27 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/sugang/service/SugangServiceImpl.java @@ -12,6 +12,8 @@ import jpabook.onboarding.data.repository.CourseRepository; import jpabook.onboarding.data.repository.StudentRepository; import jpabook.onboarding.data.repository.SugangRepository; +import jpabook.onboarding.data.status.CourseStatus; +import jpabook.onboarding.data.status.StudentStatus; import jpabook.onboarding.data.status.SugangStatus; import jpabook.onboarding.exception.CustomError; import jpabook.onboarding.exception.CustomException; @@ -31,25 +33,32 @@ public class SugangServiceImpl implements SugangService { @Transactional @Override public SugangResponseDto cancelSugang(final SugangRequestDto request, final Long courseId) { - final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) - .orElseThrow(); - final Course course = courseRepository.findById(courseId).orElseThrow(); - final Sugang sugang = sugangRepository.findByStudentAndCourse(student, course).orElseThrow(); + final Student student = studentRepository.findByNameAndBirthAndStatus(request.getName(), request.getBirth(), + StudentStatus.ENROLLED).orElseThrow(() -> new CustomException(CustomError.STUDENT_NOT_FOUND)); + final Course course = courseRepository.findByIdAndStatus(courseId, CourseStatus.REGISTERED) + .orElseThrow(() -> new CustomException(CustomError.COURSE_NOT_FOUND)); + final Sugang sugang = sugangRepository.findByStudentAndCourse(student, course) + .orElseThrow(() -> new CustomException(CustomError.SUGANG_NOT_FOUND)); if (sugang.getStatus() == SugangStatus.CANCELED) { - throw new CustomException(CustomError.CONFLICT); + throw new CustomException(CustomError.SUGANG_CANCEL); } + student.addCurrentGrade(-course.getGrade()); + course.addCount(-1); sugang.updateStatus(SugangStatus.CANCELED); return new SugangResponseDto(sugang); } @Override public SugangResponseDto createSugang(final SugangRequestDto request, final Long courseId) { - final Student student = studentRepository.findByNameAndBirth(request.getName(), request.getBirth()) - .orElseThrow(); - final Course course = courseRepository.findById(courseId).orElseThrow(); + final Student student = studentRepository.findByNameAndBirthAndStatus(request.getName(), request.getBirth(), + StudentStatus.ENROLLED).orElseThrow(() -> new CustomException(CustomError.STUDENT_NOT_FOUND)); + final Course course = courseRepository.findByIdAndStatus(courseId, CourseStatus.REGISTERED) + .orElseThrow(() -> new CustomException(CustomError.COURSE_NOT_FOUND)); if (sugangRepository.findByStudentAndCourse(student, course).isPresent()) { - throw new CustomException(CustomError.CONFLICT); + throw new CustomException(CustomError.SUGANG_CREATE); } + student.addCurrentGrade(course.getGrade()); + course.addCount(1); final Sugang sugang = new Sugang(student, course); sugangRepository.save(sugang); return new SugangResponseDto(sugang); From f26d9f0508600f12c720c91b0e08ff550a199000 Mon Sep 17 00:00:00 2001 From: taehyeon Date: Tue, 3 Dec 2024 17:25:43 +0900 Subject: [PATCH 20/20] =?UTF-8?q?test:=20course=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?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 --- .../dto/request/CourseRequestDto.java | 2 +- .../onboarding/data/entity/Course.java | 10 +-- .../controller/CourseControllerTest.java | 68 +++++++++++++++++++ .../course/service/CourseServiceImplTest.java | 66 ++++++++++++++++++ .../onboarding/data/entity/CourseTest.java | 30 ++++++++ .../data/repository/CourseRepositoryTest.java | 60 ++++++++++++++++ .../src/test/resources/application.yml | 11 +++ 7 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 taehyeon/onboarding/src/test/java/jpabook/onboarding/course/controller/CourseControllerTest.java create mode 100644 taehyeon/onboarding/src/test/java/jpabook/onboarding/course/service/CourseServiceImplTest.java create mode 100644 taehyeon/onboarding/src/test/java/jpabook/onboarding/data/entity/CourseTest.java create mode 100644 taehyeon/onboarding/src/test/java/jpabook/onboarding/data/repository/CourseRepositoryTest.java create mode 100644 taehyeon/onboarding/src/test/resources/application.yml diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java index eedced2..447f473 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/course/controller/dto/request/CourseRequestDto.java @@ -7,7 +7,7 @@ import lombok.Getter; @Getter -@AllArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor public class CourseRequestDto { @NotBlank(message = "교수 이름은 필수입니다.") private final String professorName; diff --git a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java index 76cab55..8659fc1 100644 --- a/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java +++ b/taehyeon/onboarding/src/main/java/jpabook/onboarding/data/entity/Course.java @@ -56,12 +56,12 @@ public Course(final CourseRequestDto request) { this.status = CourseStatus.REGISTERED; } - public Course(final CourseUpdateRequestDto request) { - this.professorName = request.getProfessorName(); - this.name = request.getName(); + public Course(String professorName, String name) { + this.professorName = professorName; + this.name = name; this.count = 0; - this.grade = request.getGrade(); - this.status = request.getStatus(); + this.grade = 3; + this.status = CourseStatus.REGISTERED; } public void updateStatus(final CourseStatus status) { diff --git a/taehyeon/onboarding/src/test/java/jpabook/onboarding/course/controller/CourseControllerTest.java b/taehyeon/onboarding/src/test/java/jpabook/onboarding/course/controller/CourseControllerTest.java new file mode 100644 index 0000000..31300a1 --- /dev/null +++ b/taehyeon/onboarding/src/test/java/jpabook/onboarding/course/controller/CourseControllerTest.java @@ -0,0 +1,68 @@ +package jpabook.onboarding.course.controller; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; +import jpabook.onboarding.course.service.CourseService; +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.status.CourseStatus; + +@WebMvcTest(CourseController.class) +class CourseControllerTest { + @Autowired + MockMvc mvc; + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + CourseService courseService; + + @Test + void 강의_생성_성공() throws Exception { + //given + CourseRequestDto request = new CourseRequestDto("pobi", "computer", 0); + Course course = new Course("pobi", "computer"); + ReflectionTestUtils.setField(course, "id", 1L); + CourseResponseDto response = new CourseResponseDto(course); + when(courseService.create(any(CourseRequestDto.class))).thenReturn(response); + + //when & then + mvc.perform( + post("/courses") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.name").value("computer")) + .andExpect(jsonPath("$.professorName").value("pobi")); + } + + @Test + void 강의_완료_성공() throws Exception { + //given + Course course = new Course("pobi", "computer"); + ReflectionTestUtils.setField(course, "id", 1L); + course.updateStatus(CourseStatus.COMPLETED); + CourseResponseDto response = new CourseResponseDto(course); + when(courseService.complete(1L)).thenReturn(response); + + //when & then + mvc.perform(patch("/courses/complete/{courseId}", 1L)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.status").value("COMPLETED")); + } + +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/test/java/jpabook/onboarding/course/service/CourseServiceImplTest.java b/taehyeon/onboarding/src/test/java/jpabook/onboarding/course/service/CourseServiceImplTest.java new file mode 100644 index 0000000..80d47bb --- /dev/null +++ b/taehyeon/onboarding/src/test/java/jpabook/onboarding/course/service/CourseServiceImplTest.java @@ -0,0 +1,66 @@ +package jpabook.onboarding.course.service; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import jpabook.onboarding.course.controller.dto.request.CourseRequestDto; +import jpabook.onboarding.course.controller.dto.response.CourseResponseDto; +import jpabook.onboarding.data.entity.Course; +import jpabook.onboarding.data.repository.CourseRepository; +import jpabook.onboarding.data.repository.SugangRepository; +import jpabook.onboarding.data.status.CourseStatus; + +@ExtendWith(MockitoExtension.class) +class CourseServiceImplTest { + @InjectMocks + CourseServiceImpl courseService; + + @Mock + CourseRepository courseRepository; + + @Mock + SugangRepository sugangRepository; + + @Test + void 강의_생성() { + //given + CourseRequestDto requestDto = new CourseRequestDto("pobi", "computer", 0); + + //when + when(courseRepository.save(any(Course.class))).thenAnswer(invocation -> { + Course savedCourse = invocation.getArgument(0); + ReflectionTestUtils.setField(savedCourse, "id", 1L); + return savedCourse; + }); + CourseResponseDto response = courseService.create(requestDto); + + //then + assertThat(response.getName()).isEqualTo("computer"); + assertThat(response.getProfessorName()).isEqualTo("pobi"); + verify(courseRepository).save(any(Course.class)); + } + + @Test + void 강의_완료() { + //given + Course course = new Course("pobi", "computer"); + ReflectionTestUtils.setField(course, "id", 1L); + + //when + when(courseRepository.findById(1L)).thenReturn(Optional.of(course)); + CourseResponseDto response = courseService.complete(1L); + + //then + assertThat(response.getStatus()).isEqualTo(CourseStatus.COMPLETED); + verify(courseRepository).findById(1L); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/test/java/jpabook/onboarding/data/entity/CourseTest.java b/taehyeon/onboarding/src/test/java/jpabook/onboarding/data/entity/CourseTest.java new file mode 100644 index 0000000..e7edd47 --- /dev/null +++ b/taehyeon/onboarding/src/test/java/jpabook/onboarding/data/entity/CourseTest.java @@ -0,0 +1,30 @@ +package jpabook.onboarding.data.entity; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import jpabook.onboarding.data.status.CourseStatus; + +class CourseTest { + @Test + void 강의가_생성되는지_획인() { + //given + final Course course = new Course("pobi", "computer"); + + //when //then + Assertions.assertThat(course.getProfessorName()).isEqualTo("pobi"); + Assertions.assertThat(course.getName()).isEqualTo("computer"); + } + + @Test + void 강의상태_변경() { + //given + final Course course = new Course("pobi", "computer"); + + //when + course.updateStatus(CourseStatus.COMPLETED); + + //then + Assertions.assertThat(course.getStatus()).isEqualTo(CourseStatus.COMPLETED); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/test/java/jpabook/onboarding/data/repository/CourseRepositoryTest.java b/taehyeon/onboarding/src/test/java/jpabook/onboarding/data/repository/CourseRepositoryTest.java new file mode 100644 index 0000000..f558411 --- /dev/null +++ b/taehyeon/onboarding/src/test/java/jpabook/onboarding/data/repository/CourseRepositoryTest.java @@ -0,0 +1,60 @@ +package jpabook.onboarding.data.repository; + +import java.util.List; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import jpabook.onboarding.data.entity.Course; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +class CourseRepositoryTest { + @Autowired + CourseRepository courseRepository; + + @Test + void 강의_저장() { + //given + final Course course = new Course("pobi", "computer"); + + //when + final Course excepted = courseRepository.save(course); + + //then + Assertions.assertThat(course.getName()).isEqualTo(excepted.getName()); + Assertions.assertThat(course.getProfessorName()).isEqualTo(excepted.getProfessorName()); + } + + @Test + void 강의_찾기() { + //given + final Course course = new Course("pobi", "computer"); + + //when + courseRepository.save(course); + final Course excepted = courseRepository.findById(course.getId()).orElseThrow(); + + //then + Assertions.assertThat(course.getName()).isEqualTo(excepted.getName()); + Assertions.assertThat(course.getProfessorName()).isEqualTo(excepted.getProfessorName()); + } + + @Test + void 강의_수() { + //given + final Course course1 = new Course("pobi", "computer"); + final Course course2 = new Course("pobi", "math"); + + //when + courseRepository.save(course1); + courseRepository.save(course2); + final List courses = courseRepository.findAll(); + + //then + Assertions.assertThat(courses.size()).isEqualTo(2); + } +} \ No newline at end of file diff --git a/taehyeon/onboarding/src/test/resources/application.yml b/taehyeon/onboarding/src/test/resources/application.yml new file mode 100644 index 0000000..c29ce33 --- /dev/null +++ b/taehyeon/onboarding/src/test/resources/application.yml @@ -0,0 +1,11 @@ +spring: + datasource: + url: jdbc:mysql://localhost:3306/test_db + username: root + jpa: + show-sql: true + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true \ No newline at end of file