From d7cb86808ffd244b7dca061ed454eb29a6d70d75 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Thu, 11 Dec 2025 17:35:45 +0300 Subject: [PATCH 01/20] feat: Implement controllers and models for filmorate --- pom.xml | 5 ++ .../filmorate/FilmorateApplication.java | 3 +- .../filmorate/controller/FilmController.java | 50 +++++++++++- .../filmorate/controller/UserController.java | 49 ++++++++++++ .../filmorate/error/ErrorHandler.java | 39 ++++++++++ .../filmorate/error/ErrorResponse.java | 13 ++++ .../exception/ValidationException.java | 7 ++ .../practicum/filmorate/model/Film.java | 29 ++++--- .../practicum/filmorate/model/User.java | 23 ++++++ .../filmorate/FilmControllerTest.java | 76 +++++++++++++++++++ .../filmorate/UserControllerTest.java | 64 ++++++++++++++++ 11 files changed, 345 insertions(+), 13 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/error/ErrorResponse.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/User.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java diff --git a/pom.xml b/pom.xml index 0cad031..f4799aa 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,11 @@ spring-boot-starter-test test + + + org.springframework.boot + spring-boot-starter-validation + diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java index dca451b..8f860a2 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java +++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java @@ -8,5 +8,4 @@ public class FilmorateApplication { public static void main(String[] args) { SpringApplication.run(FilmorateApplication.class, args); } - -} +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 08cf0a1..115a2ee 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,7 +1,53 @@ package ru.yandex.practicum.filmorate.controller; -import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @RestController +@RequestMapping("/films") +@Slf4j public class FilmController { -} + private final Map films = new HashMap<>(); + private int nextId = 1; + private static final LocalDate EARLIEST_RELEASE_DATE = LocalDate.of(1895, 12, 28); + + @GetMapping + public List getAllFilms() { + return new ArrayList<>(films.values()); + } + + @PostMapping + public Film createFilm(@Valid @RequestBody Film film) { + validateReleaseDate(film); + film.setId(nextId++); + films.put(film.getId(), film); + log.info("Фильм '{}' с id={} успешно создан.", film.getName(), film.getId()); + return film; + } + + @PutMapping + public Film updateFilm(@Valid @RequestBody Film film) { + if (!films.containsKey(film.getId())) { + throw new ValidationException("Фильм с id=" + film.getId() + " не найден."); + } + validateReleaseDate(film); + films.put(film.getId(), film); + log.info("Фильм '{}' с id={} успешно обновлен.", film.getName(), film.getId()); + return film; + } + + private void validateReleaseDate(Film film) { + if (film.getReleaseDate() == null || film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) { + throw new ValidationException("Дата релиза не может быть раньше 28 декабря 1895 года."); + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java new file mode 100644 index 0000000..f7d5ee9 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -0,0 +1,49 @@ +package ru.yandex.practicum.filmorate.controller; + +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.User; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/users") +@Slf4j +public class UserController { + private final Map users = new HashMap<>(); + private int nextId = 1; + + @GetMapping + public List getAllUsers() { + return new ArrayList<>(users.values()); + } + + @PostMapping + public User createUser(@Valid @RequestBody User user) { + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + user.setId(nextId++); + users.put(user.getId(), user); + log.info("Пользователь '{}' с id={} успешно создан.", user.getLogin(), user.getId()); + return user; + } + + @PutMapping + public User updateUser(@Valid @RequestBody User user) { + if (!users.containsKey(user.getId())) { + throw new ValidationException("Пользователь с id=" + user.getId() + " не найден."); + } + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + users.put(user.getId(), user); + log.info("Пользователь '{}' с id={} успешно обновлен.", user.getLogin(), user.getId()); + return user; + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java new file mode 100644 index 0000000..127970f --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java @@ -0,0 +1,39 @@ +package ru.yandex.practicum.filmorate.error; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.yandex.practicum.filmorate.exception.ValidationException; + +@RestControllerAdvice +public class ErrorHandler { + + // Этот обработчик будет ловить ошибки валидации от @Valid + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(final MethodArgumentNotValidException e) { + return new ErrorResponse( + e.getBindingResult().getFieldError().getDefaultMessage() + ); + } + + // Этот обработчик для нашей ручной валидации даты фильма + @ExceptionHandler(ValidationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleCustomValidationException(final ValidationException e) { + return new ErrorResponse( + e.getMessage() + ); + } + + // Этот обработчик для всех остальных ошибок + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleThrowable(final Throwable e) { + return new ErrorResponse( + "Произошла непредвиденная ошибка." + ); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorResponse.java b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorResponse.java new file mode 100644 index 0000000..9aa31ba --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorResponse.java @@ -0,0 +1,13 @@ +package ru.yandex.practicum.filmorate.error; + +public class ErrorResponse { + private final String error; + + public ErrorResponse(String error) { + this.error = error; + } + + public String getError() { + return error; + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java new file mode 100644 index 0000000..532f9bd --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.exception; + +public class ValidationException extends RuntimeException { + public ValidationException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index 3614a44..ed1959a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,12 +1,23 @@ package ru.yandex.practicum.filmorate.model; -import lombok.Getter; -import lombok.Setter; - -/** - * Film. - */ -@Getter -@Setter +import lombok.Data; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.Size; +import java.time.LocalDate; + +@Data public class Film { -} + private int id; + + @NotBlank(message = "Название не может быть пустым.") + private String name; + + @Size(max = 200, message = "Описание не должно превышать 200 символов.") + private String description; + + private LocalDate releaseDate; + + @Positive(message = "Продолжительность фильма должна быть положительной.") + private int duration; +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java new file mode 100644 index 0000000..d402eb4 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -0,0 +1,23 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.Data; +import jakarta.validation.constraints.*; +import java.time.LocalDate; + +@Data +public class User { + private int id; + + @NotBlank(message = "Email не может быть пустым.") + @Email(message = "Email должен быть в правильном формате.") + private String email; + + @NotBlank(message = "Логин не может быть пустым.") + @Pattern(regexp = "\\S*", message = "Логин не может содержать пробелы.") + private String login; + + private String name; + + @PastOrPresent(message = "Дата рождения не может быть в будущем.") + private LocalDate birthday; +} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java new file mode 100644 index 0000000..8e2637d --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java @@ -0,0 +1,76 @@ +package ru.yandex.practicum.filmorate; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import ru.yandex.practicum.filmorate.controller.FilmController; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; + +import java.time.LocalDate; + +import static org.junit.jupiter.api.Assertions.*; + +class FilmControllerTest { + + private FilmController filmController; + private Film film; + + @BeforeEach + void setUp() { + filmController = new FilmController(); + film = new Film(); + film.setName("Valid Name"); + film.setDescription("Valid description"); + film.setReleaseDate(LocalDate.of(2000, 1, 1)); + film.setDuration(100); + } + + // Тест на успешное создание + @Test + void shouldCreateFilmWhenDataIsValid() { + Film createdFilm = filmController.createFilm(film); + assertNotNull(createdFilm); + assertEquals(1, filmController.getAllFilms().size()); + } + + // Тест на пустое имя + @Test + void shouldThrowExceptionWhenNameIsBlank() { + film.setName(""); + + assertThrows(ValidationException.class, () -> { + filmController.createFilm(film); + }); + } + + // Тест на слишком длинное описание + @Test + void shouldThrowExceptionWhenDescriptionIsTooLong() { + String longDescription = "a".repeat(201); + film.setDescription(longDescription); + + assertThrows(ValidationException.class, () -> { + filmController.createFilm(film); + }); + } + + // Тест на слишком старую дату релиза + @Test + void shouldThrowExceptionWhenReleaseDateIsTooEarly() { + film.setReleaseDate(LocalDate.of(1895, 12, 27)); + + assertThrows(ValidationException.class, () -> { + filmController.createFilm(film); + }); + } + + // Тест на отрицательную продолжительность + @Test + void shouldThrowExceptionWhenDurationIsNegative() { + film.setDuration(-1); + + assertThrows(ValidationException.class, () -> { + filmController.createFilm(film); + }); + } +} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java new file mode 100644 index 0000000..135eeeb --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java @@ -0,0 +1,64 @@ +package ru.yandex.practicum.filmorate; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import ru.yandex.practicum.filmorate.controller.UserController; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.User; + +import java.time.LocalDate; + +import static org.junit.jupiter.api.Assertions.*; + +class UserControllerTest { + + private UserController userController; + private User user; + + @BeforeEach + void setUp() { + userController = new UserController(); + user = new User(); + user.setLogin("validLogin"); + user.setEmail("valid@email.com"); + user.setBirthday(LocalDate.of(2000, 1, 1)); + } + + // Тест на создание, когда имя пустое (должен использоваться логин) + @Test + void shouldSetNameAsLoginWhenNameIsBlank() { + user.setName(""); + User createdUser = userController.createUser(user); + assertEquals("validLogin", createdUser.getName()); + } + + // Тест на некорректный email + @Test + void shouldThrowExceptionWhenEmailIsInvalid() { + user.setEmail("invalid-email.com"); + + assertThrows(ValidationException.class, () -> { + userController.createUser(user); + }); + } + + // Тест на логин с пробелами + @Test + void shouldThrowExceptionWhenLoginHasSpaces() { + user.setLogin("invalid login"); + + assertThrows(ValidationException.class, () -> { + userController.createUser(user); + }); + } + + // Тест на дату рождения в будущем + @Test + void shouldThrowExceptionWhenBirthdayIsInTheFuture() { + user.setBirthday(LocalDate.now().plusDays(1)); + + assertThrows(ValidationException.class, () -> { + userController.createUser(user); + }); + } +} \ No newline at end of file From 87b2811e800eab7f847bf19f111700729c958af1 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Thu, 11 Dec 2025 17:39:35 +0300 Subject: [PATCH 02/20] fix: Correctly handle validation exceptions --- .../ru/yandex/practicum/filmorate/error/ErrorHandler.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java index 127970f..194f9dc 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java +++ b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java @@ -11,16 +11,17 @@ public class ErrorHandler { // Этот обработчик будет ловить ошибки валидации от @Valid - @ExceptionHandler(MethodArgumentNotValidException.class) + @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleValidationException(final MethodArgumentNotValidException e) { + // Мы ловим системную ошибку Spring и возвращаем её сообщение return new ErrorResponse( e.getBindingResult().getFieldError().getDefaultMessage() ); } // Этот обработчик для нашей ручной валидации даты фильма - @ExceptionHandler(ValidationException.class) + @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleCustomValidationException(final ValidationException e) { return new ErrorResponse( From 0b3aa4ce58b365939c1f3bde5e015b1d946b8d61 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Thu, 11 Dec 2025 17:45:09 +0300 Subject: [PATCH 03/20] fix: Add manual validation calls for unit tests --- .../filmorate/controller/FilmController.java | 16 +++++++++++++--- .../filmorate/controller/UserController.java | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 115a2ee..473cfb3 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -27,7 +27,7 @@ public List getAllFilms() { @PostMapping public Film createFilm(@Valid @RequestBody Film film) { - validateReleaseDate(film); + validateFilm(film); film.setId(nextId++); films.put(film.getId(), film); log.info("Фильм '{}' с id={} успешно создан.", film.getName(), film.getId()); @@ -39,15 +39,25 @@ public Film updateFilm(@Valid @RequestBody Film film) { if (!films.containsKey(film.getId())) { throw new ValidationException("Фильм с id=" + film.getId() + " не найден."); } - validateReleaseDate(film); + validateFilm(film); films.put(film.getId(), film); log.info("Фильм '{}' с id={} успешно обновлен.", film.getName(), film.getId()); return film; } - private void validateReleaseDate(Film film) { + + private void validateFilm(Film film) { + if (film.getName() == null || film.getName().isBlank()) { + throw new ValidationException("Название фильма не может быть пустым."); + } + if (film.getDescription() != null && film.getDescription().length() > 200) { + throw new ValidationException("Описание не должно превышать 200 символов."); + } if (film.getReleaseDate() == null || film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) { throw new ValidationException("Дата релиза не может быть раньше 28 декабря 1895 года."); } + if (film.getDuration() <= 0) { + throw new ValidationException("Продолжительность фильма должна быть положительной."); + } } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index f7d5ee9..e8cbf77 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -6,6 +6,7 @@ import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; +import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -25,6 +26,7 @@ public List getAllUsers() { @PostMapping public User createUser(@Valid @RequestBody User user) { + validateUser(user); if (user.getName() == null || user.getName().isBlank()) { user.setName(user.getLogin()); } @@ -39,6 +41,7 @@ public User updateUser(@Valid @RequestBody User user) { if (!users.containsKey(user.getId())) { throw new ValidationException("Пользователь с id=" + user.getId() + " не найден."); } + validateUser(user); if (user.getName() == null || user.getName().isBlank()) { user.setName(user.getLogin()); } @@ -46,4 +49,17 @@ public User updateUser(@Valid @RequestBody User user) { log.info("Пользователь '{}' с id={} успешно обновлен.", user.getLogin(), user.getId()); return user; } + + + private void validateUser(User user) { + if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains("@")) { + throw new ValidationException("Email должен быть заполнени содержать символ '@'."); + } + if (user.getLogin() == null || user.getLogin().isBlank() || user.getLogin().contains(" ")) { + throw new ValidationException("Логин не может быть пустым или содержать пробелы."); + } + if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) { + throw new ValidationException("Дата рождения не может быть в будущем."); + } + } } \ No newline at end of file From 218e5fd11c2b346795385777fa3759ce11ace30a Mon Sep 17 00:00:00 2001 From: Darya346 Date: Thu, 11 Dec 2025 17:52:09 +0300 Subject: [PATCH 04/20] fix: Return 404 on update for unknown entities --- .../practicum/filmorate/controller/FilmController.java | 4 ++-- .../practicum/filmorate/controller/UserController.java | 4 ++-- .../ru/yandex/practicum/filmorate/error/ErrorHandler.java | 8 +++++++- .../practicum/filmorate/exception/NotFoundException.java | 7 +++++++ 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 473cfb3..8a1aeac 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; - +import ru.yandex.practicum.filmorate.exception.NotFoundException; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; @@ -37,7 +37,7 @@ public Film createFilm(@Valid @RequestBody Film film) { @PutMapping public Film updateFilm(@Valid @RequestBody Film film) { if (!films.containsKey(film.getId())) { - throw new ValidationException("Фильм с id=" + film.getId() + " не найден."); + throw new NotFoundException("Фильм с id=" + film.getId() + " не найден."); } validateFilm(film); films.put(film.getId(), film); diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index e8cbf77..6ce5b92 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; - +import ru.yandex.practicum.filmorate.exception.NotFoundException; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; @@ -39,7 +39,7 @@ public User createUser(@Valid @RequestBody User user) { @PutMapping public User updateUser(@Valid @RequestBody User user) { if (!users.containsKey(user.getId())) { - throw new ValidationException("Пользователь с id=" + user.getId() + " не найден."); + throw new NotFoundException("Пользователь с id=" + user.getId() + " не найден."); } validateUser(user); if (user.getName() == null || user.getName().isBlank()) { diff --git a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java index 194f9dc..477d75a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java +++ b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java @@ -1,5 +1,5 @@ package ru.yandex.practicum.filmorate.error; - +import ru.yandex.practicum.filmorate.exception.NotFoundException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -29,6 +29,12 @@ public ErrorResponse handleCustomValidationException(final ValidationException e ); } + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleNotFoundException(final NotFoundException e) { + return new ErrorResponse(e.getMessage()); + } + // Этот обработчик для всех остальных ошибок @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java new file mode 100644 index 0000000..82e3f72 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.exception; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} \ No newline at end of file From c86dd3973b7c2d7bc8b87be68cbf8281fe09291c Mon Sep 17 00:00:00 2001 From: Darya346 Date: Thu, 11 Dec 2025 19:38:25 +0300 Subject: [PATCH 05/20] Use @FieldDefaults --- .../practicum/filmorate/model/Film.java | 16 ++++++++++------ .../practicum/filmorate/model/User.java | 19 +++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index ed1959a..f85c26c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,23 +1,27 @@ package ru.yandex.practicum.filmorate.model; -import lombok.Data; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Positive; import jakarta.validation.constraints.Size; +import lombok.AccessLevel; +import lombok.Data; +import lombok.experimental.FieldDefaults; + import java.time.LocalDate; @Data +@FieldDefaults(level = AccessLevel.PRIVATE) public class Film { - private int id; + int id; @NotBlank(message = "Название не может быть пустым.") - private String name; + String name; @Size(max = 200, message = "Описание не должно превышать 200 символов.") - private String description; + String description; - private LocalDate releaseDate; + LocalDate releaseDate; @Positive(message = "Продолжительность фильма должна быть положительной.") - private int duration; + int duration; } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index d402eb4..df67aae 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,23 +1,30 @@ package ru.yandex.practicum.filmorate.model; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.PastOrPresent; +import jakarta.validation.constraints.Pattern; +import lombok.AccessLevel; import lombok.Data; -import jakarta.validation.constraints.*; +import lombok.experimental.FieldDefaults; + import java.time.LocalDate; @Data +@FieldDefaults(level = AccessLevel.PRIVATE) public class User { - private int id; + int id; @NotBlank(message = "Email не может быть пустым.") @Email(message = "Email должен быть в правильном формате.") - private String email; + String email; @NotBlank(message = "Логин не может быть пустым.") @Pattern(regexp = "\\S*", message = "Логин не может содержать пробелы.") - private String login; + String login; - private String name; + String name; @PastOrPresent(message = "Дата рождения не может быть в будущем.") - private LocalDate birthday; + LocalDate birthday; } \ No newline at end of file From 1021353441a47402f8217a551d496c542386acd0 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Wed, 24 Dec 2025 17:43:53 +0300 Subject: [PATCH 06/20] feat: add friends and likes functionality --- pom.xml | 63 +++++++++--- .../filmorate/controller/FilmController.java | 69 ++++++------- .../filmorate/controller/UserController.java | 70 +++++++------- .../filmorate/error/ErrorHandler.java | 21 ++-- .../practicum/filmorate/model/Film.java | 7 +- .../practicum/filmorate/model/User.java | 7 +- .../filmorate/service/FilmService.java | 92 ++++++++++++++++++ .../filmorate/service/UserService.java | 96 +++++++++++++++++++ .../filmorate/storage/FilmStorage.java | 12 +++ .../storage/InMemoryFilmStorage.java | 58 +++++++++++ .../storage/InMemoryUserStorage.java | 58 +++++++++++ .../filmorate/storage/UserStorage.java | 12 +++ src/main/resources/application.properties | 3 +- 13 files changed, 465 insertions(+), 103 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/UserService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java diff --git a/pom.xml b/pom.xml index f4799aa..cca16ab 100644 --- a/pom.xml +++ b/pom.xml @@ -1,42 +1,58 @@ - + 4.0.0 + org.springframework.boot spring-boot-starter-parent - 3.2.4 - + 3.2.0 + + ru.yandex.practicum filmorate - 0.0.1-SNAPSHOT - filmorate - filmorate + 1.0.0 + - 21 + 17 + 3.9.0 + + org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + + + + + org.zalando + logbook-spring-boot-starter + ${logbook.version} + + + org.projectlombok lombok provided + + org.springframework.boot spring-boot-starter-test test - - - org.springframework.boot - spring-boot-starter-validation - @@ -45,7 +61,26 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + ${lombok.version} + + + + - + + + central + https://repo.maven.apache.org/maven2 + + + \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 8a1aeac..39ee916 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -2,62 +2,55 @@ import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; -import ru.yandex.practicum.filmorate.exception.NotFoundException; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.HashMap; +import ru.yandex.practicum.filmorate.service.FilmService; import java.util.List; -import java.util.Map; @RestController @RequestMapping("/films") @Slf4j public class FilmController { - private final Map films = new HashMap<>(); - private int nextId = 1; - private static final LocalDate EARLIEST_RELEASE_DATE = LocalDate.of(1895, 12, 28); + private final FilmService filmService; + + @Autowired + public FilmController(FilmService filmService) { + this.filmService = filmService; + } @GetMapping public List getAllFilms() { - return new ArrayList<>(films.values()); + return filmService.getAll(); + } + + @GetMapping("/{id}") + public Film getFilmById(@PathVariable int id) { + return filmService.getById(id); } @PostMapping public Film createFilm(@Valid @RequestBody Film film) { - validateFilm(film); - film.setId(nextId++); - films.put(film.getId(), film); - log.info("Фильм '{}' с id={} успешно создан.", film.getName(), film.getId()); - return film; + return filmService.create(film); } @PutMapping public Film updateFilm(@Valid @RequestBody Film film) { - if (!films.containsKey(film.getId())) { - throw new NotFoundException("Фильм с id=" + film.getId() + " не найден."); - } - validateFilm(film); - films.put(film.getId(), film); - log.info("Фильм '{}' с id={} успешно обновлен.", film.getName(), film.getId()); - return film; - } - - - private void validateFilm(Film film) { - if (film.getName() == null || film.getName().isBlank()) { - throw new ValidationException("Название фильма не может быть пустым."); - } - if (film.getDescription() != null && film.getDescription().length() > 200) { - throw new ValidationException("Описание не должно превышать 200 символов."); - } - if (film.getReleaseDate() == null || film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) { - throw new ValidationException("Дата релиза не может быть раньше 28 декабря 1895 года."); - } - if (film.getDuration() <= 0) { - throw new ValidationException("Продолжительность фильма должна быть положительной."); - } + return filmService.update(film); + } + + @PutMapping("/{id}/like/{userId}") + public void addLike(@PathVariable int id, @PathVariable int userId) { + filmService.addLike(id, userId); + } + + @DeleteMapping("/{id}/like/{userId}") + public void removeLike(@PathVariable int id, @PathVariable int userId) { + filmService.removeLike(id, userId); + } + + @GetMapping("/popular") + public List getPopularFilms(@RequestParam(defaultValue = "10") int count) { + return filmService.getPopularFilms(count); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 6ce5b92..35ab709 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -2,64 +2,60 @@ import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; -import ru.yandex.practicum.filmorate.exception.NotFoundException; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.HashMap; +import ru.yandex.practicum.filmorate.service.UserService; import java.util.List; -import java.util.Map; @RestController @RequestMapping("/users") @Slf4j public class UserController { - private final Map users = new HashMap<>(); - private int nextId = 1; + private final UserService userService; + + @Autowired + public UserController(UserService userService) { + this.userService = userService; + } @GetMapping public List getAllUsers() { - return new ArrayList<>(users.values()); + return userService.getAll(); + } + + @GetMapping("/{id}") + public User getUserById(@PathVariable int id) { + return userService.getById(id); } @PostMapping public User createUser(@Valid @RequestBody User user) { - validateUser(user); - if (user.getName() == null || user.getName().isBlank()) { - user.setName(user.getLogin()); - } - user.setId(nextId++); - users.put(user.getId(), user); - log.info("Пользователь '{}' с id={} успешно создан.", user.getLogin(), user.getId()); - return user; + return userService.create(user); } @PutMapping public User updateUser(@Valid @RequestBody User user) { - if (!users.containsKey(user.getId())) { - throw new NotFoundException("Пользователь с id=" + user.getId() + " не найден."); - } - validateUser(user); - if (user.getName() == null || user.getName().isBlank()) { - user.setName(user.getLogin()); - } - users.put(user.getId(), user); - log.info("Пользователь '{}' с id={} успешно обновлен.", user.getLogin(), user.getId()); - return user; + return userService.update(user); } + @PutMapping("/{id}/friends/{friendId}") + public void addFriend(@PathVariable int id, @PathVariable int friendId) { + userService.addFriend(id, friendId); + } + + @DeleteMapping("/{id}/friends/{friendId}") + public void removeFriend(@PathVariable int id, @PathVariable int friendId) { + userService.removeFriend(id, friendId); + } + + @GetMapping("/{id}/friends") + public List getFriends(@PathVariable int id) { + return userService.getFriends(id); + } - private void validateUser(User user) { - if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains("@")) { - throw new ValidationException("Email должен быть заполнени содержать символ '@'."); - } - if (user.getLogin() == null || user.getLogin().isBlank() || user.getLogin().contains(" ")) { - throw new ValidationException("Логин не может быть пустым или содержать пробелы."); - } - if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) { - throw new ValidationException("Дата рождения не может быть в будущем."); - } + @GetMapping("/{id}/friends/common/{otherId}") + public List getCommonFriends(@PathVariable int id, @PathVariable int otherId) { + return userService.getCommonFriends(id, otherId); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java index 477d75a..dcf6964 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java +++ b/src/main/java/ru/yandex/practicum/filmorate/error/ErrorHandler.java @@ -1,46 +1,45 @@ package ru.yandex.practicum.filmorate.error; -import ru.yandex.practicum.filmorate.exception.NotFoundException; + +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; @RestControllerAdvice +@Slf4j public class ErrorHandler { - // Этот обработчик будет ловить ошибки валидации от @Valid @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleValidationException(final MethodArgumentNotValidException e) { - // Мы ловим системную ошибку Spring и возвращаем её сообщение + log.error("Ошибка валидации: {}", e.getMessage()); return new ErrorResponse( e.getBindingResult().getFieldError().getDefaultMessage() ); } - // Этот обработчик для нашей ручной валидации даты фильма @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleCustomValidationException(final ValidationException e) { - return new ErrorResponse( - e.getMessage() - ); + log.error("Ошибка валидации: {}", e.getMessage()); + return new ErrorResponse(e.getMessage()); } @ExceptionHandler @ResponseStatus(HttpStatus.NOT_FOUND) public ErrorResponse handleNotFoundException(final NotFoundException e) { + log.error("Объект не найден: {}", e.getMessage()); return new ErrorResponse(e.getMessage()); } - // Этот обработчик для всех остальных ошибок @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleThrowable(final Throwable e) { - return new ErrorResponse( - "Произошла непредвиденная ошибка." - ); + log.error("Внутренняя ошибка сервера: ", e); + return new ErrorResponse("Произошла непредвиденная ошибка."); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index f85c26c..4de66fa 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -6,8 +6,10 @@ import lombok.AccessLevel; import lombok.Data; import lombok.experimental.FieldDefaults; - +import com.fasterxml.jackson.annotation.JsonIgnore; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data @FieldDefaults(level = AccessLevel.PRIVATE) @@ -24,4 +26,7 @@ public class Film { @Positive(message = "Продолжительность фильма должна быть положительной.") int duration; + + @JsonIgnore + Set likes = new HashSet<>(); } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index df67aae..3627226 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -7,8 +7,10 @@ import lombok.AccessLevel; import lombok.Data; import lombok.experimental.FieldDefaults; - +import com.fasterxml.jackson.annotation.JsonIgnore; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data @FieldDefaults(level = AccessLevel.PRIVATE) @@ -27,4 +29,7 @@ public class User { @PastOrPresent(message = "Дата рождения не может быть в будущем.") LocalDate birthday; + + @JsonIgnore + Set friends = new HashSet<>(); } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java new file mode 100644 index 0000000..7eabf2e --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -0,0 +1,92 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.FilmStorage; +import ru.yandex.practicum.filmorate.storage.UserStorage; +import java.time.LocalDate; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class FilmService { + private static final LocalDate EARLIEST_RELEASE_DATE = LocalDate.of(1895, 12, 28); + + private final FilmStorage filmStorage; + private final UserStorage userStorage; + + @Autowired + public FilmService(FilmStorage filmStorage, UserStorage userStorage) { + this.filmStorage = filmStorage; + this.userStorage = userStorage; + } + + public Film create(Film film) { + validateFilm(film); + return filmStorage.create(film); + } + + public Film update(Film film) { + validateFilm(film); + return filmStorage.update(film); + } + + public Film getById(int id) { + return filmStorage.getById(id); + } + + public List getAll() { + return filmStorage.getAll(); + } + + public void addLike(int filmId, int userId) { + Film film = filmStorage.getById(filmId); + userStorage.getById(userId); // Проверяем существование пользователя + + film.getLikes().add(userId); + filmStorage.update(film); + + log.info("Пользователь с id={} поставил лайк фильму с id={}", userId, filmId); + } + + public void removeLike(int filmId, int userId) { + Film film = filmStorage.getById(filmId); + + if (!film.getLikes().contains(userId)) { + throw new NotFoundException("Лайк от пользователя с id=" + userId + " не найден."); + } + + film.getLikes().remove(userId); + filmStorage.update(film); + + log.info("Пользователь с id={} удалил лайк фильму с id={}", userId, filmId); + } + + public List getPopularFilms(int count) { + return filmStorage.getAll().stream() + .sorted(Comparator.comparingInt((Film f) -> f.getLikes().size()).reversed()) + .limit(count) + .collect(Collectors.toList()); + } + + private void validateFilm(Film film) { + if (film.getName() == null || film.getName().isBlank()) { + throw new ValidationException("Название фильма не может быть пустым."); + } + if (film.getDescription() != null && film.getDescription().length() > 200) { + throw new ValidationException("Описание не должно превышать 200 символов."); + } + if (film.getReleaseDate() == null || film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) { + throw new ValidationException("Дата релиза не может быть раньше 28 декабря 1895 года."); + } + if (film.getDuration() <= 0) { + throw new ValidationException("Продолжительность фильма должна быть положительной."); + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java new file mode 100644 index 0000000..58d2582 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -0,0 +1,96 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.UserStorage; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Service +@Slf4j +public class UserService { + private final UserStorage userStorage; + + @Autowired + public UserService(UserStorage userStorage) { + this.userStorage = userStorage; + } + + public User create(User user) { + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + return userStorage.create(user); + } + + public User update(User user) { + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + return userStorage.update(user); + } + + public User getById(int id) { + return userStorage.getById(id); + } + + public List getAll() { + return userStorage.getAll(); + } + + public void addFriend(int userId, int friendId) { + User user = userStorage.getById(userId); + User friend = userStorage.getById(friendId); + + user.getFriends().add(friendId); + friend.getFriends().add(userId); + + userStorage.update(user); + userStorage.update(friend); + + log.info("Пользователь с id={} добавил в друзья пользователя с id={}", userId, friendId); + } + + public void removeFriend(int userId, int friendId) { + User user = userStorage.getById(userId); + User friend = userStorage.getById(friendId); + + user.getFriends().remove(friendId); + friend.getFriends().remove(userId); + + userStorage.update(user); + userStorage.update(friend); + + log.info("Пользователь с id={} удалил из друзей пользователя с id={}", userId, friendId); + } + + public List getFriends(int userId) { + User user = userStorage.getById(userId); + List friends = new ArrayList<>(); + + for (Integer friendId : user.getFriends()) { + friends.add(userStorage.getById(friendId)); + } + + return friends; + } + + public List getCommonFriends(int userId, int otherId) { + User user = userStorage.getById(userId); + User other = userStorage.getById(otherId); + + Set commonFriendIds = new HashSet<>(user.getFriends()); + commonFriendIds.retainAll(other.getFriends()); + + List commonFriends = new ArrayList<>(); + for (Integer friendId : commonFriendIds) { + commonFriends.add(userStorage.getById(friendId)); + } + + return commonFriends; + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java new file mode 100644 index 0000000..e245099 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -0,0 +1,12 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.Film; +import java.util.List; + +public interface FilmStorage { + Film create(Film film); + Film update(Film film); + Film getById(int id); + List getAll(); + void delete(int id); +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java new file mode 100644 index 0000000..1cc886f --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -0,0 +1,58 @@ +package ru.yandex.practicum.filmorate.storage.film; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.FilmStorage; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +@Slf4j +public class InMemoryFilmStorage implements FilmStorage { + private final Map films = new HashMap<>(); + private int nextId = 1; + + @Override + public Film create(Film film) { + film.setId(nextId++); + films.put(film.getId(), film); + log.info("Фильм '{}' с id={} успешно создан.", film.getName(), film.getId()); + return film; + } + + @Override + public Film update(Film film) { + if (!films.containsKey(film.getId())) { + throw new NotFoundException("Фильм с id=" + film.getId() + " не найден."); + } + films.put(film.getId(), film); + log.info("Фильм '{}' с id={} успешно обновлен.", film.getName(), film.getId()); + return film; + } + + @Override + public Film getById(int id) { + Film film = films.get(id); + if (film == null) { + throw new NotFoundException("Фильм с id=" + id + " не найден."); + } + return film; + } + + @Override + public List getAll() { + return new ArrayList<>(films.values()); + } + + @Override + public void delete(int id) { + if (!films.containsKey(id)) { + throw new NotFoundException("Фильм с id=" + id + " не найден."); + } + films.remove(id); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java new file mode 100644 index 0000000..403d2c8 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -0,0 +1,58 @@ +package ru.yandex.practicum.filmorate.storage.user; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.UserStorage; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +@Slf4j +public class InMemoryUserStorage implements UserStorage { + private final Map users = new HashMap<>(); + private int nextId = 1; + + @Override + public User create(User user) { + user.setId(nextId++); + users.put(user.getId(), user); + log.info("Пользователь '{}' с id={} успешно создан.", user.getLogin(), user.getId()); + return user; + } + + @Override + public User update(User user) { + if (!users.containsKey(user.getId())) { + throw new NotFoundException("Пользователь с id=" + user.getId() + " не найден."); + } + users.put(user.getId(), user); + log.info("Пользователь '{}' с id={} успешно обновлен.", user.getLogin(), user.getId()); + return user; + } + + @Override + public User getById(int id) { + User user = users.get(id); + if (user == null) { + throw new NotFoundException("Пользователь с id=" + id + " не найден."); + } + return user; + } + + @Override + public List getAll() { + return new ArrayList<>(users.values()); + } + + @Override + public void delete(int id) { + if (!users.containsKey(id)) { + throw new NotFoundException("Пользователь с id=" + id + " не найден."); + } + users.remove(id); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java new file mode 100644 index 0000000..d815bcc --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -0,0 +1,12 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.User; +import java.util.List; + +public interface UserStorage { + User create(User user); + User update(User user); + User getById(int id); + List getAll(); + void delete(int id); +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..636895c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ - +# Logbook configuration +logging.level.org.zalando.logbook=TRACE From 7c42e67ce11925a250146d7af5273e7bec9f0290 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Wed, 24 Dec 2025 18:06:23 +0300 Subject: [PATCH 07/20] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D1=87=D0=B5=D0=BA=D1=81=D1=82=D0=B0=D0=B9?= =?UTF-8?q?=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/yandex/practicum/filmorate/controller/FilmController.java | 1 + .../ru/yandex/practicum/filmorate/controller/UserController.java | 1 + .../java/ru/yandex/practicum/filmorate/service/FilmService.java | 1 + 3 files changed, 3 insertions(+) diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 39ee916..e138bc5 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.service.FilmService; + import java.util.List; @RestController diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 35ab709..961e226 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.service.UserService; + import java.util.List; @RestController diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java index 7eabf2e..c10bd71 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -8,6 +8,7 @@ import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.storage.FilmStorage; import ru.yandex.practicum.filmorate.storage.UserStorage; + import java.time.LocalDate; import java.util.Comparator; import java.util.List; From 50611ea47e40b2cd9c8225ef7cc8316e005765d4 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Wed, 24 Dec 2025 18:36:19 +0300 Subject: [PATCH 08/20] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE?= =?UTF-8?q?=D0=BA=20=D1=87=D0=B5=D0=BA=D1=81=D1=82=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/yandex/practicum/filmorate/service/UserService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java index 58d2582..42f81ec 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -3,10 +3,11 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.UserStorage; + import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; From 616e7d57a55de8345e2f01d03263c31cb75fc305 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Wed, 24 Dec 2025 18:42:40 +0300 Subject: [PATCH 09/20] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= =?UTF-8?q?=20=D1=87=D0=B5=D0=BA=D1=81=D1=82=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/yandex/practicum/filmorate/storage/FilmStorage.java | 5 +++++ .../practicum/filmorate/storage/InMemoryFilmStorage.java | 2 +- .../ru/yandex/practicum/filmorate/storage/UserStorage.java | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java index e245099..8c4f56d 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -4,9 +4,14 @@ import java.util.List; public interface FilmStorage { + Film create(Film film); + Film update(Film film); + Film getById(int id); + List getAll(); + void delete(int id); } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java index 1cc886f..61c6774 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -1,4 +1,4 @@ -package ru.yandex.practicum.filmorate.storage.film; +package ru.yandex.practicum.filmorate.storage; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java index d815bcc..b34fd80 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -4,9 +4,14 @@ import java.util.List; public interface UserStorage { + User create(User user); + User update(User user); + User getById(int id); + List getAll(); + void delete(int id); } \ No newline at end of file From fa739a3315ad88e0e6fbfa8e3b5e193ea5a92649 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Wed, 24 Dec 2025 18:48:35 +0300 Subject: [PATCH 10/20] =?UTF-8?q?=D0=B8=D1=81=D1=80=D0=BF=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B2=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/FilmControllerTest.java | 126 ++++++++++++------ .../filmorate/UserControllerTest.java | 122 ++++++++++++----- 2 files changed, 176 insertions(+), 72 deletions(-) diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java index 8e2637d..63c6d6e 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java @@ -1,76 +1,122 @@ package ru.yandex.practicum.filmorate; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; 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.web.servlet.MockMvc; import ru.yandex.practicum.filmorate.controller.FilmController; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.service.FilmService; import java.time.LocalDate; +import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +@WebMvcTest(FilmController.class) class FilmControllerTest { - private FilmController filmController; - private Film film; + @Autowired + private MockMvc mockMvc; + + @MockBean + private FilmService filmService; + + @Autowired + private ObjectMapper objectMapper; + + private Film validFilm; @BeforeEach void setUp() { - filmController = new FilmController(); - film = new Film(); - film.setName("Valid Name"); - film.setDescription("Valid description"); - film.setReleaseDate(LocalDate.of(2000, 1, 1)); - film.setDuration(100); + validFilm = new Film(); + validFilm.setId(1); + validFilm.setName("Test Film"); + validFilm.setDescription("Test Description"); + validFilm.setReleaseDate(LocalDate.of(2000, 1, 1)); + validFilm.setDuration(120); + } + + @Test + void shouldCreateFilm() throws Exception { + when(filmService.create(any(Film.class))).thenReturn(validFilm); + + mockMvc.perform(post("/films") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(validFilm))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.name").value("Test Film")) + .andExpect(jsonPath("$.duration").value(120)); } - // Тест на успешное создание @Test - void shouldCreateFilmWhenDataIsValid() { - Film createdFilm = filmController.createFilm(film); - assertNotNull(createdFilm); - assertEquals(1, filmController.getAllFilms().size()); + void shouldGetAllFilms() throws Exception { + when(filmService.getAll()).thenReturn(List.of(validFilm)); + + mockMvc.perform(get("/films")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id").value(1)) + .andExpect(jsonPath("$[0].name").value("Test Film")); } - // Тест на пустое имя @Test - void shouldThrowExceptionWhenNameIsBlank() { - film.setName(""); + void shouldGetFilmById() throws Exception { + when(filmService.getById(1)).thenReturn(validFilm); - assertThrows(ValidationException.class, () -> { - filmController.createFilm(film); - }); + mockMvc.perform(get("/films/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.name").value("Test Film")); } - // Тест на слишком длинное описание @Test - void shouldThrowExceptionWhenDescriptionIsTooLong() { - String longDescription = "a".repeat(201); - film.setDescription(longDescription); + void shouldUpdateFilm() throws Exception { + when(filmService.update(any(Film.class))).thenReturn(validFilm); + + mockMvc.perform(put("/films") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(validFilm))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.name").value("Test Film")); + } - assertThrows(ValidationException.class, () -> { - filmController.createFilm(film); - }); + @Test + void shouldAddLike() throws Exception { + mockMvc.perform(put("/films/1/like/2")) + .andExpect(status().isOk()); + } + + @Test + void shouldRemoveLike() throws Exception { + mockMvc.perform(delete("/films/1/like/2")) + .andExpect(status().isOk()); } - // Тест на слишком старую дату релиза @Test - void shouldThrowExceptionWhenReleaseDateIsTooEarly() { - film.setReleaseDate(LocalDate.of(1895, 12, 27)); + void shouldGetPopularFilms() throws Exception { + when(filmService.getPopularFilms(anyInt())).thenReturn(List.of(validFilm)); - assertThrows(ValidationException.class, () -> { - filmController.createFilm(film); - }); + mockMvc.perform(get("/films/popular?count=10")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id").value(1)); } - // Тест на отрицательную продолжительность @Test - void shouldThrowExceptionWhenDurationIsNegative() { - film.setDuration(-1); + void shouldGetPopularFilmsWithDefaultCount() throws Exception { + when(filmService.getPopularFilms(10)).thenReturn(List.of(validFilm)); - assertThrows(ValidationException.class, () -> { - filmController.createFilm(film); - }); + mockMvc.perform(get("/films/popular")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id").value(1)); } } \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java index 135eeeb..1fd378d 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java @@ -1,64 +1,122 @@ package ru.yandex.practicum.filmorate; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; 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.web.servlet.MockMvc; import ru.yandex.practicum.filmorate.controller.UserController; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.service.UserService; import java.time.LocalDate; +import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +@WebMvcTest(UserController.class) class UserControllerTest { - private UserController userController; - private User user; + @Autowired + private MockMvc mockMvc; + + @MockBean + private UserService userService; + + @Autowired + private ObjectMapper objectMapper; + + private User validUser; @BeforeEach void setUp() { - userController = new UserController(); - user = new User(); - user.setLogin("validLogin"); - user.setEmail("valid@email.com"); - user.setBirthday(LocalDate.of(2000, 1, 1)); + validUser = new User(); + validUser.setId(1); + validUser.setEmail("test@example.com"); + validUser.setLogin("testLogin"); + validUser.setName("Test Name"); + validUser.setBirthday(LocalDate.of(1990, 1, 1)); + } + + @Test + void shouldCreateUser() throws Exception { + when(userService.create(any(User.class))).thenReturn(validUser); + + mockMvc.perform(post("/users") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(validUser))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.email").value("test@example.com")) + .andExpect(jsonPath("$.login").value("testLogin")); + } + + @Test + void shouldGetAllUsers() throws Exception { + when(userService.getAll()).thenReturn(List.of(validUser)); + + mockMvc.perform(get("/users")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id").value(1)) + .andExpect(jsonPath("$[0].email").value("test@example.com")); } - // Тест на создание, когда имя пустое (должен использоваться логин) @Test - void shouldSetNameAsLoginWhenNameIsBlank() { - user.setName(""); - User createdUser = userController.createUser(user); - assertEquals("validLogin", createdUser.getName()); + void shouldGetUserById() throws Exception { + when(userService.getById(1)).thenReturn(validUser); + + mockMvc.perform(get("/users/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.email").value("test@example.com")); } - // Тест на некорректный email @Test - void shouldThrowExceptionWhenEmailIsInvalid() { - user.setEmail("invalid-email.com"); + void shouldUpdateUser() throws Exception { + when(userService.update(any(User.class))).thenReturn(validUser); + + mockMvc.perform(put("/users") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(validUser))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.email").value("test@example.com")); + } - assertThrows(ValidationException.class, () -> { - userController.createUser(user); - }); + @Test + void shouldAddFriend() throws Exception { + mockMvc.perform(put("/users/1/friends/2")) + .andExpect(status().isOk()); + } + + @Test + void shouldRemoveFriend() throws Exception { + mockMvc.perform(delete("/users/1/friends/2")) + .andExpect(status().isOk()); } - // Тест на логин с пробелами @Test - void shouldThrowExceptionWhenLoginHasSpaces() { - user.setLogin("invalid login"); + void shouldGetFriends() throws Exception { + when(userService.getFriends(anyInt())).thenReturn(List.of(validUser)); - assertThrows(ValidationException.class, () -> { - userController.createUser(user); - }); + mockMvc.perform(get("/users/1/friends")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id").value(1)); } - // Тест на дату рождения в будущем @Test - void shouldThrowExceptionWhenBirthdayIsInTheFuture() { - user.setBirthday(LocalDate.now().plusDays(1)); + void shouldGetCommonFriends() throws Exception { + when(userService.getCommonFriends(anyInt(), anyInt())).thenReturn(List.of(validUser)); - assertThrows(ValidationException.class, () -> { - userController.createUser(user); - }); + mockMvc.perform(get("/users/1/friends/common/2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id").value(1)); } } \ No newline at end of file From e23d473bca6fe2b6332027c6deca0349175ce8cb Mon Sep 17 00:00:00 2001 From: Darya346 Date: Thu, 25 Dec 2025 13:37:36 +0300 Subject: [PATCH 11/20] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20FieldDefaults?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ru/yandex/practicum/filmorate/model/Film.java | 1 + src/main/java/ru/yandex/practicum/filmorate/model/User.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index 4de66fa..ecb293e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -7,6 +7,7 @@ import lombok.Data; import lombok.experimental.FieldDefaults; import com.fasterxml.jackson.annotation.JsonIgnore; + import java.time.LocalDate; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index 3627226..f360e27 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -8,6 +8,7 @@ import lombok.Data; import lombok.experimental.FieldDefaults; import com.fasterxml.jackson.annotation.JsonIgnore; + import java.time.LocalDate; import java.util.HashSet; import java.util.Set; From 60bfcf0299d27ad6237eed2b3753e7f04c9dd2fc Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 13 Jan 2026 15:43:53 +0300 Subject: [PATCH 12/20] docs: Add ER diagram and update README --- filmorate_database.png | Bin 0 -> 119959 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 filmorate_database.png diff --git a/filmorate_database.png b/filmorate_database.png new file mode 100644 index 0000000000000000000000000000000000000000..62b9e0d5512f0653d3720bccdf47f1f2e9b2bed5 GIT binary patch literal 119959 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

K(|2dG%nHV3{BCc>oV$7AVSeY|#;xJhu(2 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 literal 0 HcmV?d00001 From 6ad5059117ec779a4aa67baf6a3959e108fb3fe4 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 13 Jan 2026 20:51:06 +0300 Subject: [PATCH 13/20] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE:=D0=9F=D0=B5=D1=80=D0=B5=D0=BF=D0=BB?= =?UTF-8?q?=D0=B5=D1=82=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=B2=D1=8F=D0=B7?= =?UTF-8?q?=D0=B5=D0=B9=20=D0=B2=20=D0=91=D0=94,=20=D0=BD=D0=B0=D0=B8?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=B5=D0=B9=20=D0=B2=20friendship,=20=D0=B4=D1=83?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B9=20=D1=82=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=86=20=D0=B2=20=D0=BD=D0=B0=D0=B7=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=D1=85=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filmorate_database.png | Bin 119959 -> 93377 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/filmorate_database.png b/filmorate_database.png index 62b9e0d5512f0653d3720bccdf47f1f2e9b2bed5..364b4cf50a5eca546b310a33046998dae657d9ab 100644 GIT binary patch literal 93377 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

>j5zz8L(ZS&b zuf5-rmIbv(mCoCaE-`K)p?xHF^1_(jlRGR0l-uWar|Q;LR~dN=*;c;gSwsQ$2OtCX zy0GG0Fx^1|?Bb;hApWD<_WB?*sKUpN9XoX3fKhO%=h7FV=r2$1Jrbt!gk=A|$pPo; zTAgHdDYZPE&c(76eX>Yif`-bsPM4Gq@bM`@46*J`iKsfQ~OnmJQPuVZyG-^wuZ@Mac&MX z4w&yqv40iymgZj~AwM^cr^MJ;9y|7MvL`-^+}&NVaX6VH+ybkOw)GN^=wtZD>pGbH zx4x&}G6DCqu~G8-Q_$0W7_e3i@%|zZlswAH$Z1&@?U;AohfWBQIygE`&cEU>=?|Fy ziSL~^MN>R|PLiCP+u3XO=M5fbF;L61ce}fX_nBJ|J7nTh=6iv-Yd*Al_r@i0U>CGz zcC0?|oC9h^vv)%Z01v{q&!>NXl1Df-{QaLJ`vUSt{W*+8fBO!Je`tP1++Xth$!Lmy zZ=(=q{`cNl59Pm5GyLbk{jW4YwPXMHd?AN((Jll@joxHp=WX4)02^VNbgcD$jjz=d8+?to*sVS z<~2&}Gq(@#O2y&Keue!x9Soj2W?HEyQ{TsJwO$)|*1BFCCiEL5bUR>lp%iK_^^I=1 z#qYGQ=w11+kx%N%l`GBQ-U3ij+<&OJe8OfDAXmp4VX8OvCsrv15!(eCX(okRl}Ciy zp?Uo_UJx%Cs>NXkLQMnJKhx=9B66koDS$DgWu(3?setTp2Pk>t4k{pNevLJCwZw{X zfi+4QXBz{SbtFQ-Uqjm_iYKScxWV3$1?^CXfiE(=La%Daiu<$pG0|tf4ww(!xdGHE z$X)}zX3@t00w|3&)z!&E8Zh|!?tFN|&zm!rJlT&&CG-sqfjv=%9;*xXFPuDgjzt`4 zOyISl`pRWHsfbKM0YUHICj+1E*toi~Vgwo)SQ7&2!524~QBBhZLkBnGpb;n#D*eu& zDG08O#~M7V1)~V^wJm-oW!JE!{%77fahgvv?TR!J?ng34M|=AfXhMKu&30NGKc8&Q zHHBQ5v>QYFoqz(jSzCMrTNLb46@y-;%d33@1bN9QnWWE zN=r-CN}O^K0|PB+J-Fw<8zLZ}2?U03BmQv#xYUjyMI#hvk<}ga_H7K%*Wd`(iY(77 zKwt$*0%Dc`aF{)wmSp$S&wusD3s4dVlz~>R;Xl)$QFK-?$d)(43H(}0uzLd8TK{Z0M(9_NQUqQ#4z!U0NEw*m)<^+o z6c>ONun-p)@4S|UOZxR^A#D*DlTh~xEU~uxW)3V>*aMRSaVi-AS0e`i3}TEyegX_d zmX@BD)(PglMUY9bFd<>wW?|qnV-jagD*-wLV#n!ckt}!tq0nDW#RCThOv>fNHsojq zX41UBkZaA>8Ys!rhYuY-Y`S1_j+T~PTU#4^^fg&^xdo`7LX9l=Qj5%s@Z9}Co=f>f zfD!;nJ_)w)q+p4eAI-N1bJ4I!_vg>I5z7ZVw9*A`btcKhq9R^g%rA3gYHTbKET|4& z4$}&1z%C%LoMvA3*sM6>7LAkxa5K%HOVK{YEDmNgSgvhIX?^wT(Cu#KPu->x5)!Sj z08wiX+x;SVtZr{@ZNYp5(yy+qO;Wg zo^GaOSqp8IA@Pc-D5mrgh1MP>ww=q>ADVyE86fmfwlT^c&SeM8&)S5HyOR_mpLUMs ze28HIpc0Wj2XvR#WAo4bmr^>wLCq9e zZyP}?ULE-ET@tVh!66|`AaZ~UOaeB-JPkaR)|jn^qvFte0bL-~-dNZcL&akm4VyY( zyC8pc+4>A0N(w-zLV!S<0GI5s*Bazgg6YGEprAO|hXEcuxB|IJxr%vJmOvW>YI|iF zHW>q3i8xpRe?EXR&;=_(nt*GF9Nhc%?L(db@N}WYBq8zYV{EJvKtIqi8G&T6mgy#i zjxR#MIk#4j%@EYgH86W814qfk!I7z|d&6R2+OcgX4d-*@_2Qw`=o4nsa)4V9l)yv< zBgPY{!J$vnq^`Zcr=o#(8Y zC4ugTpa`gs0%MXA5{s*2Q6@XIJv2*X$_$e7fUaCzUD@BSLw@AR0`Go< zs;&pWL}_;U+?g}Uz=;}fZLB&ibsIuZK%?jcay7tIVnk5)k3PA-TW#p4&9KQkLfQTU zhPyDQ(BgyL7~ocg{4j|X=}wsbmLZbY_t*zIX$I8FV3U&a)3|s!z#<4>6cNg>XGaNy zUSc_dvsMOQz#U(zc(lI@5)2pwJE3O{zj7DNetCWNhBTkubTi=pFabMQq^#J3 z=zN65Y#+`!6*TSY(_nKWYkP3@Xya}S+rve>JyI`yeLFmM?O9yvwMYSo0_`g_YCQ$k ziI76o_?HW;$57#dYDCTNAj_WeTT}16>8=V{S(?bc!JK!Kc_Pj<-lQ0ysB5ca|1oA=ENul&@%L0u^A@+?V9Bvdg0PudRuG)^!UK!l3Dmy#r zt__7Q$16A!!be7MHBNA2P6Wj>$dGTLY@wNgol<#5Ga&4nfO`NDa}0@X$>5Ad`wqe& zzzL7G7>a@y%V^8K3z>#+3VmmUjD%AD!PrD-ZVzmup zP_b(V2g|xgsEH`(-x3G-1kUn5#J^~aWbLd|np!O1v}eBh$;{0T0@-8f``7muaI2h> zZM2c!@yZ?skBpz0>fXXX>)JJbpN(7}E~|V0)OUZM^gWn97xR_iOpm;Gpeun!3I&n4 z&9roVMmc@Lt|$le+JkS3M*4dHx`A+ux9Z zofVzByL+wmsGU+557pi*3~wpvo^Fg#%I*ypkaYOV_D_oRtOb#u^#{6jSa#Z`2r2Tk@ zm>8FnjOxpdOpN9A>rMbtzY$mQ?P zlSCJ+2<*Zb9scJ7_w7Yc)QIs9_=`Sse-mDHU-bwk|MZ_%p&|Zn<3o+hrYeUqMz0H4 zea;+yp3CxEn(32eI4s$!u$;ie!6O`CQ=D{fJ7bP{^_|q(mg38$Q4cpUpix-=k;(7m59<(?W!zd05-GWxhk zNlPhK!rAwRI$&gB=098SFg+grRrFc4SH!WYb`E~q?(XU%xDXgb^PNBN*F)KE*-U`Y zw<$6@J9Saq>4Ba_KOd*~tZNvqbiPGuKxip9j%_VZ?8}w%Cb4?%S-CIKG>1sDYgMOO zZ#er;_{@@M;2m=&{mfWu^#K;W=4Ddg_Ar;CnPk{!Dmt-9{>91fPYyWz|NL?P@%>tUEd}aOj#@8EhPfD$7ov?-L+FiwSNE)MdD@i!zP)=kpRua00{(L zKm{E|u+qesyLznq+P2ELLyO~?!>u^E3f#ObjM9?qKDze@I}}R zp^DLEA!o;Z|Rjf+WXTxCv_JL!r_(q5W>xkP|lG7!k8?tmz9<_N*T8k{b6Gc z=#D9IeQcqyo_A*c=zEDr8s&1(zTXfYHZ1*@ z5Pl|iFeE7_Py8Pb?)VGy6}(Rh7K?~6tvzCrs~3r=F-CL;!SVe@`Q~Y4BnN)cxB5y06Ny7Rzb~O<4!36 zD<)36Op7ga3Y*>!0xCM(5rA?0WjKY5eOhVm~^JLl)8qN{>shB06<{oWU(Vqz$bfz zH;|RNTA7@I&0*knnZ@C|=57hMrY7x}4%{HOUHl?oLi4PWFTaW$~ z=f!ck64)4m$Z`5)gjAtd>;R`v(>rK8h|hpA0N^74BTz-5g^7#WoHneht!-(Imn6V0 zrTV5O8C0;r@4=~8bF>6h7PLngnmr&dV&r1))IPZCFg5&{^#4IDAFAafjx31+%YALB z8K~o&8?H>p?rb$dS30b7=5{ymL{mt-gvi5!G$abPBxv@Ui3onNRT8>z*suOx%YD-p ztXmW8?yEk)T`p>G6STp^+om8RVB76s3r0j>vzz&5i!TZZ3E?!0lwntt9NPI`eo7wo zbk4H^K)oWCBtQ{FJeYW7_yCCtSzDCTG?GEUfW>J1_lsi^GBTmv8q2z&up15VI&A2k zfbJ=z;z2X`1-XEqhC3fUj6q!!fbv>m*MzGeKue|e>47IQ7XkbehXMU^iBeN@2G=0$ zLNi-jk9_;~d{+1LK@-3hvC#6=!YT!N#5^wr{4&07{m`ev1>L=8PxuB^b#--pSC6%b0@8Qv%lz-ab*%a$>i_F# zeKz0*>3tT;sxMyvf+}<^3Q%zw2R*j7M!Gpft91hnAH^DR~+o<6P7$vm%iqIR$828Q#_b#+xa}KHw*)U~?t- z_0Vk<0AwN3z-#{zxJdwlMF3+@f@cYs9%L>C5i8QUPOC@`Pnh`S_W z^AZ>K;zkft7y>5>+e0Rw^d%@KDJv@*gErR$b9LNsPocv3)m#} zGw$1fW!0gv`tQG!fGh-$m3wSVYQMRPgTo5NdVT;{D+N}DypWO~>9SC3;JXPfR|4ER zWF^exKNN9{U8w95NRw!>fy>V@$JEv~2UsiE{P_J$C=?}RbOuQ%pv7oWxrkcL^;-#S z4F;A53;XI1k&}negX@kNZWR%G$F~)N4(;wk{v){J4Pks>o`eMh0*=aIgR^a|J;XZ{ zLFIRxIpLhKu<*Dcf=>kypQ4kKlNXI9Tj*huO8s^7Nf!Z_EJ#a_z#`u;Q*;e@t~Q|7 z5V_3hJPkjoDen06QTp9Z?2iu?d45<9@+%Ow7rZOa!@I%EhBj`3*?9gnAJ{0tRFcNq zT-gC|9e~Vxpv}?F=B9brNLMrZI2lL~@H`@SKI{PZF=z^hy`K9^#=vaXK zxq!AA(#;;3iK9gVpJFIEP5R#f-T^j1_W)%JiF`PK7uY5cx_r~3OVotcTKqvdSTpbk zlHJVbU)M>xNS*QQv12iz+HR^yhC|i@aoZF__jw=fD;ylH*Ue$BoWNTKdoIt3+b;jS zCoSCx_wI48-4wCH!@C=vD^c5T62?9@RQjRflNuiRBF7 zyAf0_GUFR!t{9gXpnfOdmQiKc4D-Bo?Bsu9){2Oq15ZK22@kkyCO|B}bWH*R{pQO` z`|ow>K;0t7z1!L&Fgu82d%v&1rbl_8T_T+(la*n2eANE|($>V|?TWw?)XpH#0T$E1 zvNHFqYB05eNC7z!J-}WC4Ykovzp{|#mwgH(`9}?j zs$pAmCoS@JYbbAq2eZ3GK$qvFHCDH_^g?Uhp(wOyujNIju|!>46U9#;dI1qW#+9+A z9%kF#RSB|v=S(iUIc!1jMIi`sYYMp3VTCH(zyFTcegbmlAYxq&+RoY(xLm0=Cl;sZ>HS`cX*3$3LUUTy_pnjsg zX`E_$SwB)=qw+1>T;I*C@0zfuw74K^#dM;Gj~h;&AG0%+~U@9L7;45@>1qBPaMzr3L! zksU2(%nh&J_3DYV^DjX+Ehl@?Pqho8z$n*n>c@V-`*U3J+3tU|uir zUFe^33Y&aqbRV+cN4f9QfA3cOZzz?*;T&PFu{c}DA~N)u|GII@>U|e_adPjr`Uv!d za4+5e!rFVsbKU>{;@VSEktm8Nloe7|Q&uI}v#jhDLZMAcLJ~rQvfm+lB^hO9?_?z; zD_flVQ&(Nr`JQwB`u*Jc_WfL?x7T=%$K$@9f1+MK78UK0A@X3`UF2^*3IEe(9ty_2 zj|?Y7#(vLA)g*=TRpEu4Q~a+cErVleD33Y^gs%!Cq=4*ceSLl0_k%%W+@@iPM@88k z{nZV&tg)ed8g4LAK$>!i`RE(w(OwgRQPh+C0PR3#bR4J$nYQy58cms;-N&?;EF4Ba-m}H%V=Re$j%83K=SOEOSHd z{VHqHD)F%-SqL1am96qYBpH49KJdGfdt0{a_1UW(oqGNuqai=GhW!|Du-*thR?$W# zP|xy?X;KjMNmYP~<7cv<8Jq?*exaf*DJjVxq$KG<2CUqw$!!t`11oDsM*VV2K{$Cx zI2iQa$l0LuH6eSXk1(=(Q(G3Oy>onT6a&yw{b8|(JP+TPHktA~ojlb)z$jti;nML#u7SVJgWoIW^n2R?(%Yoo`fu9Yor?n?h6)%5J|V3!;fdc&`SHB zdLr@+e8_G-zM+hXbuGq3APHthMiC^#STUQoV>!q_V?h6;+ypCQ_oL+i!PZF*9Tt8@ ztr;*9{n&eQ4bUWMT>mpADG0l$%bqZb?9z&&=h1i;rNvS!{yAqRH~d3Il-Qu3l51+t zR5%Tt2^@l=4zVdomqz{IGJoG|NclCD~$Qp6k-s}BX&2mb(^JGgm^n3P3S z`&a$O1_w?V8u~kQ4*(Ls#l=f`uv0xwVq|R0pF&Y?S+v$T7qxVkUEN3Ze(-h4TFE@= zEj;PkJXWc<*S)i(nEXs@-iy5_a@tL`M40|#hE_7x%BYmOs6NvZ!9SZHBWy#6vAAwU zGTuCh9Di?b@6T68Pf|0NiU(hFc6D|2-5Fd)h#yt9`JC5@Td6)V{$6O_aHpqdKFr*A zI^^I~%;hWl(JNv`YtgTnzq|w+i__>MI5Ik+nLmA_bB2aq+V@AWW55N?&S`}do_qF0 z{DHO2FT|#(gve_6Y0>ZkrF_+)^X^GayV*&ZRte#g@H~w}(sb2< zWAA`)T-$4zu-Fe(A)Wm{nlli7;*vbYWIs^VxUtx(!pHoN79fQV!~?&6;cjffVmmg*-Mbc?2dap~Jwj$lNK!Pyq;fuV=ulF;w};0A3Wb8O z7w`aYAb!B^e=0anmh}W?L{(>aCYg-=6(t@!4_()u(kZ$*3Q-Vv3Aw zwiTTDH5J;)uYJ($dxIe5Cp5TA(MV?_n}g79VE%#AI}nlXNu3#F`Z-Dr!m$8crYv2R%!LG;maQ|ig6D}ER65gs%Nn8|g9D+_Tx@VDl@<$1xOPitwbAs} zAIqCFYU=8oQ|xUrTW8spw;cN|?D{XIA*PupJu=%^`9xeZmc+hYn;BF&cWyLvatRW# zMQz`p7}xC!%^Xy4bc{@GUPNU_g|(N9hx2UdUavOM!~@NnXE0d|OQ=hOgkti*w^XBR z>4~tU(t_yj2;MH(Dx;*v(V)kOm%BnmWhoI081fn(@HYslD<5*6?dtDu?i(8)Y@<+e z=QL=VrNdXtTjGvWva?%%CtbZ2 zIv=s;(-A5C{_NCt6vp*X8wtVTSWr}S`F^Grj|<>671ed6CLxa?eAm(<;;3>dP_KCbIXo`A^BH zIfEjIg3Pc>Kdur}3whMSmzE!sgkcm6ux6C(moSzs{P--VB-F1&h(YMQ)zop#Ik9-e z#9T+}O2|&9W@gMf-ros2XdjJY_d+OEDAVqb{=@-|j-PBWyI~x(${N0nKqGdvlTc)Q zgV*m7WTQ%#bW4fwfyfdOjR<1+XM?^sr;w2UulY(-U{476+&4DZrVA?7%K8VaZ;J4r zk}xu08OC5UNmqa%Sa=>d&@{l)M7+9QIgY)y>Bt(3hwrGQZa>3Xva^xZ0NWmtA}2B= zrSLAl?>r^`q5l%z^3m1E~Lgo5qkm3W79bqP30j&X4etbX-Ub7NX-2dsVgZwAc0)VR{ zdoQt@6SozD7A{geGTq40Cd^N_xxjl5))qA>araka)UyTfIaae=+3 zC(Mn+eFAoIfm4n6x3C88LTB*c!Gq=8vS@S229IilIFra+2i1u{GCRNxCD3oedPdAa zPfqo)b1Oz<%w$_)AMU9LQ^mDFW^5T)_LaV#2cRqzWj~->kz<|!Hc~^;g}QgSEYvN& zq-~Exjv~6n(VlJ6#rf+gd3hy0z2{J#z!w*ds9OU4keUI)3ijG%dhoPYL3p&vFgsS_9+Kw5Gwga< z!AnDoYliCBHyjNnhJvae$4NjTN@$aa(fD^0d{VL1vxX?i@E`$+)In9zH8{wNN6aqw z2tj0u#J$i3Z4sJ!PAv5R4}HV2$P>N5KWa9jI$0RE8TMvpEMy1}foTMvE{{{oSbe=H zd@9%rfCTTX&0cgKJJ)pUpzAAa1(^FJYZtBbgPo8?nm}ewglw=05}5?{7Qqalox}Kxbq>t{onAF&E&b}Rs3|aG$lD0WOD}coH72SNaX7y@CfUm@83DMm*0DP!d zNg7^w#*hF%f91X$iTC0VBJ^B%MwDeI?*BBu1+fm)37396!PZL_wbLtufWcr~R9wOC z%_!;+i`4>U4vDV@!bV2W@#Kh%y|-^%zaF&q2sbx3Za)IJ^64=6ZW#9&-9xw2Wt;wn zWN1M7M<72uQh3dTY`diK*oYGsDr}N6hWy7XA7-(`W7))&k{$DDnX;;?obMGJ@j)j0 zA<;TZ$h>So3Bke{4`A`v+(a&*wlp*-gmy|%udk=bXH`uRnwVBPV=@qX z3)*mbxSsn^tL=IM0m?M=B8b>9!mv4|sJ&i;<*S@8U=nNVA@+*_4CUPTG*>4=(^p zo=@l=gN3Z1Dk7$V;w+85QF~>4e0)fx1eAdrW>H$Sx(*Ak^vAXma#7B`s5(UypJTD8yJy<{Zmx;m%TLLPlK9q#e zmB4Du&(E)sXmAJQ5*z*sv)2T6-;+Ac05VD38v-iO32E8JBjFQS;@Cz*cvcy(_mW8i zeI}&A_(jBp_(rliVVT$ZX>XcJx?{(s_W9?7l-S>NE!SC^>+|@XV zAhC$WO>2IbW&RmS*~XJ~{`Slr;M#lo3JX34JG7aEV?iGLOIW1$LL39F2uWDUT-Vy^ z{0#syiI{_!%1OmdV-I~Rk_`yKL-tAH#b@CA;@M2A8##BGG=lrvuAGJH80!;uXH&oW zlsC}KZ5u&LL3F>+XJ&L8J1 z3cs@C%L9 zE-|Ze`i}!x$_g~nO+%Q|=7CTNOWwmSLya29B=22!&~*Ntk0bz^@d#eES~eC$zFj0Y1j9JvJrl?d$r z{P}b20&RUlqa!0^IW1zoEUyxiT-*PbB(*ajVwLr{5u+Fb_9!^2(b2dC*Z#E&d@KH! z?T0((opG1pC1mML{^eP(_P_78b;?{u1)%KzBhVWD4Q{? zT^=a^l2H3;PJe|dR83x>8}ay3WcH$-3NEYTNJiWeQ!_bkW8tf58O-oT*J716Q)Oz! z3nRAkTiPGh1r^o65i=|G76yFFSD{5z+i3os;XqEG!|3ZJC2;PGkscpIR_i~YUc4gM z2@*ro($XRv)nj*XEN=x1>7EEeOwq+$Wp?VKCBn?gi^vr)scVq@)q9#6iY#mKWE0ts zpJ(2db!&tk`+b356rn?Kn`v%?9qm)JJyAo$+5QneA~^ixG-5&<%~gO~BcX*bo!ZrA zvP33|GZ>Nz@1u5a)W_q{fyDmL1N$U+BkxnRs2{*Ha$*4HY6jXTL*e4I;O*GLAx`A#-duwsw)cg%gd&92pWWtN zND+$b3lcQ(MHc>cqP-;H_C^(F&7GU9wKV? zIl)Y_!AZeN(pmsNllB4d+V{X_z+kuzglHsy(Id4PiH!yP&@FrnV52+QW*c$X1E?1_ zf(Ih1a|mvU7nVriA(6qZgaCu@a3qSi0IEwnd?_z$zif zm)QG4`ASg#kQ)H$vl|O3fF%-ANfMw?BZOz{HQM+8U!gwu`SaBCH*8QR)?)x56lZOt zxv&iBRZM@qa>^-V#YHBx%1_lQyCzzd% zfiXqa8H!2;06=(uJ8R=!i z8A%wo!`%0QLuCPMY>I__MvLZ;a_tb)FjNl^k3yhtEkmM0Ym+XVMs&xBSK}KD5 z5e8J3pTk8g{U{?s6;ynsyqV*Ev}VfrqGkA}tmh(4!9x(y@82IIbQ+2uU^ENywwNg3 zHspM9o=DfKyp@K*4v4*kQh^YYgjNmDcq$B0DTXW_8g6$%hYBn?l3EE{R(OVjU2U{7*@ZVDT?OAy<{w~Y!24)Q=G^`s`&e)O!C(hI<=WB> zE6=wb*&V)G=k01PW2(c}+=_82^)dBD76TEo-Pbku&UOte#3-38+jKW}wdeL=57w25 zG7UR#7EtZj$??D?rHzHZNSwIeeauT1jEcw(cKS0s?W$Lf0KY)HyPqW@}>ea@(1@FMe z9mbR93zSC;lQpEuXpisYw{I5{djd)924-fRUb0dk(ShNbl?90HP?Y?>4;~!COXF>H zcz1JE7SLBAQ)Cp`CU5$PiuCuF-~;r!6lp94Hr1Luq9>(n6N; zvAM(lgjX!Pw>^ftC zQeVWjYb9^?PereBnw2ZlzK^4m4~6u(zQ8&-0^q?Y$kB^)vrfp-TSZMR#1*y(6<`^@ zsT?oPIsw_Ya}Ej3V(TC`|8h}8Eb`%^v2cT zHkE{}K9?c`@E+$A3t=WA&9CI(;_?I%GmKYP{p{!pv|wA{C{M`79*M(Xf&rPx>hf40 z43QEV@CVf*2-NvJ@EILl`N)r8ck|tF+62MmJFgr&cC7D4dcunBxcA>*5x90vE-pQ= zzEYDaP;ErXj?3P3ckhH^*V%bmd7}17vT3a+t{;vKX8gUhyu4tYxwz}B2)rwcFzaRq z=jV8Vl&r->6Y8t4uMa@G19qQctfhLk7$dFP@@qwdZ8DSDyO`CW~-xE zsOiLBU20cOut^yFN=(f4MCFwau!gs}93O>$hg`ofhHB@#9v(F-ZYBP?Zq|AaWRr+7 z(_of4iZPdmikJAZ%i)=;wqBB!UWqz-AABy%7@7iHoM#mkMX(%gyO-mHS!Or*IRuGA zs{=}oqm51&fQ@76^5sY;zg%jx58Du#&_X{_F|Ue6C9-tcYvx8q9F**FM)=VWnK)j?qO9N41xw%%dQHE8032HO zwS+hKy@7!8mMms5$At-M?@u`f7%dGciXsTvGi+YBMc^iuSv;-En1e4pJc=WXr}b!Q zqf`T?AH{k|pH)$z-hs!U7y#`J8QMrs-wKZX{rmSrfbL#jnHq`tfhC6@Mx*ZzqPSBo z;7R#<37?=c2zBhZbCAJhv@+`KE}#@LAe5lQD(pl&)fYSmvXB&32y<~o7yd$!{*t7| zQaC9mk!9|cn=1*a{adJ!gdb-&=^yQ7Oh%UiJ>_jo>2t}CT(4*;DZR(5{ZL%|1w@EY z6AkV|(<<8^#|qdWui!NfHgKICK7n>+3&1^EHApi95JRowI%TNEvl-F)=K)Ikztlwx zS`TnTJrF5{36w&NhqIkgxr6CF%&41w#Yo_hNZZS=bANG4a_@wr7~X!1<$lXlrhpQ| z*dSAjYLnyPoH0Kp>c*yLzH6W) zDehqB4z#``;OaVFGKe{)c;e&d%!l(&pe|qxyQm(gLP-`s9={o^RB4zbbh#S*fCDI> z(j^d&=SvXF7KDrc1dQM0fXy3Aa>C(4C63*@BUS1zyShpkC2a{VyIpH4B(ZT{pnT!U zW5i`%mDQ`%`yy)*el;OTHB5v3qo{L=h!0I#ONr#cHMd65-0>)o0+0X~=Tg2hWxr%Er&$yI5JP7~+E!#t~E+tD75&@=!eM>mW*6|Ll;aC_RIQI*eJ*C^?6L4DShbXwzwXXgUzSAX zXjKg!CP5>Yi-xvZ_CR$Qd8YYxyu$uKd9KA9XnhXawBAgFRE-<|*KgRYoo0QFoCL8* zYG>7JOhec|g)DQyqafKo53FFHf!8`80mJHs02)2+&zosYqCcJ%QmL)cH+&X%T^$(& zv_8}41p8+U!+pO8D{loXz-Yl?J|#QB4xbFlr%B>^@lV#30Tp)EmP3 z)QO7O0Kom^)D%C$PQmyT!%V53Zp#i*={zXmEYL2%4@bcdE#^ZxqQ9*XQXZg<`KTR% zN!j(+c>yMPf+4o0vmx^mFSrJJWX^Bjz1su8F2KNgwd$&>$NR0Au_3*{MgRjEv&+vj z=phgyx&k|A_pQx3Pa&Erlz`UN0PT6{2J*?AYD<`zX>*j$s#+BDM>o{J6*7lAhfA19EoSk05xrcI$@dY=2!CwG)rs0&9tdl)(c^9$Y3Z2Hv>l=W^TUOWsEk6 zo7lv~x4GvZHaFjcpvldMYv}s=RR9W0(C1k2v%vn7s|R&VyLIc@x8M)evK;w0^JwAJ zw|zhw34%`(5Fx9)EYUKxd8I+ge72qlH*1xWQtW-9;IhIvJq46bzrPgE_^mR8qWXxI z)>bMYW%p2RLEGr-@87L#qoH%|+;(Cx^2!w=+BHvrN5+<&6)jFW`Czi9C-t zd`wD806!Wli*T?PRMH6u%%QmAXQ0~P`vHLF21pcAI)E_$R{e?wx=KT|UutnG;QkL| z7jc>Xnf@;9zTkc&=yjoqk`ENX3iS>R?0XcC*-dM=9elWM+d-<=&_Afes^u-A5j$jU z&4>KOr4X(!iWD5UWNFDmwrF%8&rsMI7#Sr32Et)G$L;Lw@}E2vRPR2jhG|mLEim`P zEAj>;^f$ln)eYCCnp39 zD9$hT)o`K{ev5I?+mOJ9O-6`0Mo<^!GoWZ3W9D6EwB#u^=dGd+rN$dKY&e3Jz$Tac z0X9^ah$%%ewrFj^Gabf8zGx*4%`ViPP@Ql+^q1ukvPdZD)+_Saw`X>iigQywjCy#}f8-AsKJv6!mFQ#RG zc<`Cyny$iBw-(k~GIa4u!mk3TW#i=hkQNpkeAnBX2D%_>;oFJZlhe`~BH!-i;$q#u zzuwp{C`k6q8Cq=Sd`A*NOTCb#e`}g-n@_!e2*R$)6bnu4#sDiUUXMO_S!SB7m#lH% z^7tN9F-v7B?)V2!1>ay*0Vz)iYnpvYE2_h05yOdz zD6obnCW_jvU*q%*Oz!OIgysQq4R!|+gz^>BlIne7p>J4N1^S|U))ruey1KiCCevlB z&*mr!@5)U}aA#vx9CR(^euo3gm5WW|%zuw7jI2nRhk40Zx3JNSQrv#sg^FH3sgZ$S zZz&kAX#4KNYHAFS^mZWN>dXAE-1#ExQKg{O%-&dGC4{qcC-f-oWA(bb_UyR_<(N0- z&lZdSS50V3$szR~R^Tb<*8*W-=h_{vg6UL&ulOAQ~iR2arog{kbC+_0*+Nn zKpcu2Vh9UCKxIz@%I1Yi*ASXN)XM?@ez5nQz@mel-~y6VSx*X z)yWQmEN=b!^`9E@X`?Q#bH9P1x3Hd4qf#r-%ftU>QPQQbsG+nfD+-I%|Nhtq%5LFt z>%QYtU!FzR&ra-TF~}=i;w2`F>VU3mF#q{0DWqWCV_%N-%;rY_#3k*caFZJh`})hL ziEfdUysS@i0!5Zj^yg7*MxEl`sJ$M=Z=mJmm6T*jYBbL}y?aK!)Iea%ep*@+*P!=5 z3+ma>&7(LXk+6%^Y11v0VmEE1HCY!OoS{a!MJ6WsQj~gT&W5eZyfN_>9QdKZRypYl zBV*Sl2@mOu5y=LSOD%kL*#^B2O04&TE(*-yT8w>1hegzy?BC9B;ljL? zIJsHJ5LAfbiSaT+)y`Zy8@nd!jqw`Iv!_%VC3b!~rFTVBz;>iD z>`~=*{U^?CZhQ_3D1J*j=jqM$W}dO|G`gOvH=Y};KWfq{@St0l`ODO;;1~<0S}ukLl5;ox+bD+>A8)k z+@MF9sd%xN#KAk2`|a5F=X&(eyOzHcH=!2k$e1Y2oqx066XPCZ`oEv; zGhKboKM^LN{}+q>zMd^ z=Kxi;d(E9YD6el`f9_kzeE$zLfY$SxGqqvK%e~5cY*kl!?GKse7a8T5a%%s`dYWdm zsGqweW#nUG+}MHGCC$F?`1hYmZ!>!!tG-NtwM@0ZEO*u=n@8G-ZH2?vJNzR>NzOE;`(Dv-xV16J*0)-H^A`V_WdY4)x|=O_JUbgK+n;%RX_M1r z$}y>R-{l|VZUe5;8+&(;TCRJ9ZaCFY;l@jRugwI_F1enzbL7)*PJX8+>}UV%>Qw*u zYwLWSr*>sclJ_!wf;S%QFiY|c46g8D;i8N=x0Sg#eo=KXrt9)y(;Z8W-CWu+>?q>M<)<28rC;P@r>`Z``dmibuWWJ)3!m+|3oqrj-mC65 z8Yq8p?;Fc$>#Mx!Qw6cp)1U0=q|vkg^QA>89do&w`003Ftn}#F99b30BHIJ5Il``4 zYB#I9mwz#LU_Mb*adGa*waS;LwRT>bOXPN7;dZ*k{-k1WWFn>L#4dgtY2NFz15e5` z4%HPbey*`>xFKW-LuIaCWx2ui_Ftlv*)AgNr#3TtyQ}2Qwd{Md+2x?r;-PQFy4KCS z9SJjPHfdT*S4;{-Ubsx@r0#1BUEw~#&bssJ-CG4)D~cCAHGIm_xOsJU^SI|T!!?qg z+fK=IY!ugHO`BJB;h7m-HIlmT$4lnPraccuR^lazXicK6Zrr7Ieyygw)C49IQe(NRzFKYY5} zu&n%rquBbbU*zl@*HiuKXg((#ED{`21Y$ubRs0uErg!LY--}yeyg9<$%rxPlv)f@9-%ktgK?69M?c2TjO4{G)<|buR=~bz`idlX zu7r|B@MDj2M-~rIy;)_E_hde2tCN}sKP^j`P@8ZanC`QMXcab(LU+Eru(kL7EUv6zEcw7cb&{GsWR$Lxt7m8 zK4ESk?N#17F#N#b>j~Qt&xSXiNcZL~~NPk%JQXex(dW>68v_ z#jKgQRcuQ+W}RB8QARRNPw!=`kszKeU+n5`#TOZT9^c`7>$p z=v3Lp5wj1E!ZI4VZQC6((cYxBM$}3p6ZUYN^hQ;iXj|+`1$x8L591ni!X=)F1jykB zE^=V08<6dGYnv-=s7u!7*7^}NpL1X~--(C*(WeYUlebJPbW%o^65Cicos;jH(j7Y{ zO*OBTbk{Auu^>N{ePqbu&g9JWryYrg5xw^*HyaI}%VnzET-qda&q}T&jLUUjq8YQ| z?DQe1$0OI)%cE&AB?(8=G2BpUZSd z;+Ke7-h{+Mbp+EYlimp7HLA4%g4F1d^15yLZM%w{MQ>O4c7X_a`ug<)z>RgyHe4i3 z<^zt+IDtkC#Z8f^#e>@UW5>b+BLmvF49}ZQ4MkkxJL}5WnMjp#Wqpi-N>`Jra<^Fl zXGzJty2JxzKJKxB^a+WcBd)ZmG~eab*0{a9K5L!Pf)|?~RobF4Hs*cWVg0wB{IXTs zhLhDll$Ko}%O_JytMSEWPal^)S^PZzhKJck&!Q#jn^#X7%$%pU`dslgzEaiY)Vf!} zA#Ja!vt5?vEz0Tox;d$@|7ht<>_|rP?~$Gi8sml$vNgxwZBtZPu0!IRBZYp3~U#oZkc^`KF|p&v!kzdJY`yO+cc^4V zymISDtBpP{k1)M#76mebohQDv#-a)jVS77+|sB4la(3ennS1^HN-l+oro zvllcgJ16I=-PED*^nL(TQvBh=j)Mn-5F_`PD6JmLzm!Gzyy%h@>$(uU#>U6D9v6%= ze?CIpci_^Gt$1u0KmpLo*}$`kq@VZDa5y5TRm7%aDXffp(BPlPQ@zJ59)zPw$f|MR zA_wTB3xJt{JJZF~euQJz5vla(Ij%rgnl<$`7z!h%9#v&sDhORVlIwLkVMC<)FZMK3 z4xAHQ91iL!{f$g1r}z~T9~l)6&8c(ll?2BD5QraXvS_luBwL_xN6%sdJW)TjSsjoM z2ywBYw@Uy;;MQd@THs@)fo$Xo5~2xWM#urXgHHGdt7vF?0BrZ5oIQ_KLkyX0I(fWr zVUQx9gFz;|xUH!ejV@Buvrk|MI(u(tttu5No?X+O9~2#}PxsMN(1kAM9QW-vbj^2u zmkNUW(F8w!unY*)3utZ@ z9u)d=fZ-3q!cIFoA9Tnhr4k5PwOm(mB-;r>p}2k5t|Bv&1TY#SkQUhPF;s{ zRu38&7=i)y79df0KT(JRjywM*WZ#8#-s0m7G~z$kqm@By8CD$ccL zGtPndO4n6^W(EqDYOwVnKGjmpw}9V3a|GoTaBL3%(Qx<9mM=!YK!1$~4l;(nRY3kb|m<$w!f z5HMH?Zh?)P`!3Gx*_PBOkIoe8pzVA2;ut1p$8E1Lk03UM4p3TJIm*vH9H)!8!@a#0U&X~6^x;(g0i7Pna+2>$q-MhrR=z;IJ+2xf@? zqL^rNFOM=r9_#;v`275ilGI1L&xkwNf%8`*EtfJJu-yp;iI^GXAM@oIixSX}hWQ>q zKQxd)g5Yx^pda1Gx%Z~YzKdQsozEJ zUMAu+vJ+Z1Lkt!JL&GzQii;mEPb72|V$Ve(c@M`{gv2D^DuT z@U<*B9Rid^0BvW#?$6x;a0?VT{uFEkqf{MF}&XzlXh|Vtpd&g>Z-?n7OZYHxG^f^t$oCw zfEoq9yOD{>>|l~}ut>Ft0+HD*W2+*;U%Dgf!FoI~Onw zyzJ|+6xsmg#hY1i2oO3@ax5+cuZ1~(vM+`L`FM1q8)_^hkMN43XZHy*eV{;}6=TFL z!NFR;OS_X*b6g1Hyvq(gwR2_rT_?afW;Bl zPB_~~ugUKkIdbHP$DKRp!TI03ecKikEDlmKF~20T^?OUYALfoQP9`~{}R1_t~gJVyZZ z$7N+#1M$S_3tphlpcHD6pBcI;_6&@S8l4gZ#lkbrekskv!^0sip8e7OXoL|Ivqi8Z z0p6m47pl;%9w;-+Gq!jDM8+2C^mU6X)M@km3V~1e$mOTJ}S|qsg&- zDR6k;o;I+soCa`+k;cl)OHqvAd3d{t9Mj_J=^-6rI;1eJ$V2zz+sk0f`mbOB7rso5 z{vY5clLg*(8VUs`EEqUvYO`f3eDoWzRD=IsO9idduDyE^6XaFYiANZMzry#gT(d?W z+`}vk5Icp0=u(@@@Swb0%t*N9_qN*92b7+BqgXGd1>k9-j>@!-68V`-bXqNDrjRMUx6xPE!KbZ%<`dPfw*4a2@uusLR5$P*lowIT`MwM%iWMJSp{Z6 z!+Q#ah!LV#@W5Fxr&0PnhBA=$w*9wH*McoG?vSb)m}IESxH>$Ey|pJC9YwIAbi&zT z04)2E$=LU>xu3iAy)>f4gUh6#C&JPqPUHDA4B**%!1gAlg?@sXadXOE)J#Ls>vEsqz{2VAffC3w z0ujurdTS6;IkK4{-_QV(tU^bk<XC`|Uy?1P8!$>bpRAFfwg;t3 z*`6~e;5$*zGGO2M<5XbdqaJOP#S%dFYsl}7KqRZqT1~+t1XQ{H@=~1fHL;SF zwX8)*$R*)-O}nsaTjBm8l~~WjRD%0w>Us>Qij*kOe8enNKG83F@BYDoaqB^P!olP@ z)}AW@`wt>AC+|LZ`Z8}W!+*bvEC+o)|M`>mcf-P1$T{Ckml;SySWm6|uOe*WYHHa2 zqoN_-!a62hz4#?h03MV;rd#9~*5m`|bS7be03kTHxC^%UI-)FDnted(K3TX;na zzf}zhVnj)c+aA>3D(RY-;9j}A3FJt`-vHIZb5oM@Cr@*?M9z}S6Wg9@XYMvn>7Qq>@3pg? z96F=8ZmZGc(6h{w{^p@$;k0AlD{rx!ib(1%u~^G=FfzgY ztQABmjbXMP`R=(ur#4hetag*U95>ULV!=ej6)3%T?%A{UD*Q0`IprY6(0;w^93Db& z>kyL3t+9v0&Dh(N%#BScoHqLVzm5Kvo}LqE^a-?6U%&aPdXf=8D*OA);vXTcMnha; zSbq(6WO`_0^dYa547o^4L@)SHv|?C(KTz*)QHUAUPBx{ZLcsT1^EsyxPk1qwINo~0 zswjkFk~G`gP5VVfgHfAzCjXsA;W@i8>Z49zEdX(uG+j*{J7>4#sC$b?8{JL+dZcMx zLF-#Fal#v8>I6)!#%=L?nY~xsEl}hw62oqV!s83sHHdTr`z`t_+6@~Pzr}Lp1aQF- znpj9JC810!eR5zU8eixF&izb+^a{{kf#lpU4J2U>m&@ieA)CT7bOJ>a5v+l4>c%6) zKl1zZ=~Ky%T)bFfH^%;%4q=)jPKLs1AS^gsLyvUXc;P#D?&NbE`qDIi6@(c&!eMB> z+U*Vo3Yu)dZo!v=Y}VVLV>fQwR)$1Bq;sQ#x&|*A)oZM!q#_3gP4-nZvAFnZ@biTS zxBXrV(#svi>MKTcSj&7q7(`dkEzI7ePoLKN4sOls3C=ZY969abWpScs^8T@7Z!n6r z6Jle{k+$&m&PK`gw3VLolio}o_f2n} zmVuAzD!RiTS)-?LK+i`!0isW#!Y17UshO(MjsSoE0u=8~c&;9vo{P7mo+B+c8W>&M zwnQO=ix)3Kp+f^V6DI+6p#0Fs@sC78g$$u##68tJYq6G<0lkosmOh6Qh?Ff)%gNzp znaL)D>U$JP4b=(yC%|T6IHEf9g3)2PUw1x3MYj~yG5Jd0x-60PWLQyWRP{L(vOp~{ zu4H{6D%E<#w9jVz)mEdiO6tj}Mzq6)pO3vP6AYC9t%xjYyeAJ~W)-)S7)PmuVvJk}>w7NNS(`IPhsM4(47lW&= zd{e+`zY|q6@F_^VpdTSiDE7@4i8{Ym{cwrh59rceYYh2-sU8bogvx)z=FM_CIuebI z2WBVr*G(5y=L54hZ9caPl)Fk`P%P8&jJtS{4+|8&fmo#HsV&<7V=Z zGx82?dD-mLC;_bq^?hcUDA8~Y)SD40#4p z@)F-l>l34RDbK9+ls6Zvkn*V6q+(GX+g;~YXJ3o>eO&ajugSw)EG2^AH3e9N*gFnM%C`oBjz;~}JTsEy%-Fv5nR zDwHw;o*NCuIaH!g#4poBL||&lg*nyBJ^?+#QZjG8H>Y}|6ekiUbnTAV8si-g8q%f< zpv8c2(gy*H=sClmGLtX z?p+x=Owzr{=WV2?FU0BJMc5L~z2W5H`HG6X3oSW-Y|@LNF((T$6=_Ql;?@D!?>x$U z{4KV?G;{>LSW7~lWPUJMsKs#*`7A!P2yGD1BnZAM0OUotS|JmKNWHPgFzv88a%3^d z+kUy1K7BEfy`w7!KsSUAVgpuNT#RZbuLvH%dQ4{sX*~<{o?$1(JWmKcv6t+;$?aft zuT1itIdjtLC8r64a4<9#ik;&G0Fsmp>+0%q-s-P)+LS&;OZ{nQ)D13i+H_kEirIv1 z{cr@O-jhP7tXvTU2XnkLw3Uy-bl>_$#5@)`FX%8crv6K9T&}Ql_zM=Abgd_1{^fJO z+@()TmOZXa-N@LK=ySr!0_J%pNTlBv6qsyd_vwENMH^ug8B-v`1rvr;FH76*{}${O zpCJOF^)U+XxXg_1wYv9xuU&_=2+)>fos@29v5?B*0l~x&&`e^qA#D;$J+wf2NXd!S z&U}Pc7t$Cf1mu51JWqmEfsi4hO$x~T1>TyV5k~}d$bGMVetgYSy919QW=y~i4G?za z%9Yy>90(*T=cGoQk`xOWEjo7}KffE8ifF{eV5@>4X7Ov}*^pp&4F78=!Xd6DMZ1*l zP3~MP1%>ta?<;@|?`;#UbL4&a=ushjQe;oXB6sY>iBYIB$tx#n9De=fIIfCs8Wqca zly3PI6@$@*9QE!P!O-Csp{g_cJ|6T-(*`L=c+J-E)zmeoVS(TeF4GyLg=p_Ho8aLw z+F~vbx^&?{Q@g$OKc?d*ohf99N9{Xf!FFdQ4M1BaNy*$o=2LM*8x57FinACz7MNs= zEY3BzfY{wiAcKXqtOkuBSvsfSct2rhCkQAReYyZv7Q7=OX~lj?fcII%KOydK3&f8q zeY-$3VS$V4 zD-M0uDT>=LcdRg~li_Su)NVoC2koA#-K1x>vCe2bbW%W-G_5i zVN${XBm)D0w^Q<(l`FrXEHr?62@nxcn&J6lENq0ehAgCHKZe>2Uc7VPFA3@Uy^H}+ zifKmv^?Bi7?lKRw;yXy>0B#!j`z;`I)-nmNMcWKJj@lbzS}0DpBL@Q#>qo*CO$w%*tM^%b=ef_IB%nl2>1!<|tX&j>TUD%0Pex372UGZ04oS69h4auhXkL1q!EJW8wjnbx5Ywm24m3g z(IYA3GTkeRtE=)}iIYQsX(SC#0y>ihvjOar3f#{{93PyB>=c;6ER?!b4F46o>Z|zt zQMx){gT!T`Rse-S7%{gwF+AtmaX0d0%}_{VKZOO(6Ix6RVnS;XHZ6Cm%xWckM0oPx zs1k5c8z!-Fef+l5;$xdo`96ih6m_TL7?7)lJsn5RT!xFh5p+RG0B;ZcKh(m(anDXG zGv?Lad@U5`8aK$75`9s@Fhx+Adg=;~sFHGPKyD7NWUEa#e}E*-e>!36ojA&>>fksK zCmfsZkNCYv#TisKTr&q8hqmjwjM0Ixc~#$uu}=0IykP~9D*!Gg@z}}z0S&?^)tBwU zD8gks0y~nCmp1@;0mBL5M!-o!5q=I^9+Zvm`x$=MQ(7ZpScr~;ddM<51HWISlKtbr zzz+zQseo@P&2bo8(j4kFEgscm7u|t|a1$J=-UA-;9O5Q{ZJ?5ZaUI% ze{t#>c&z&3SLQ^m;<5{n!AGGZGO;%{GK*ZswEI$T1i zWwa4ozEkTX8q*jWV>j2Iiga)O)0i_h`tJ!5fHJ`J!YnGuEMyZBxF6MHHFUm&$3*B! zWuZ|LKiC!+0C38oi94H4zIx$qJqpr@GJ=vM^2j`d9+0Se?}kj-iht`r*m2*v^3 zFnvEW@BH?+a91lIUV+5cxE)XY{PKyp3IwCqSQxkKs^?r-JOQDOK)9L!A#|q=;?Lz= z4f^l@8w2aJo zOc1PmM0<=F9R32ElQ8MtAIzD#j~0+kko*6T-@Yv>T5%O4rR4TGfX}Kz!X`nOo~WoW zHD3gcfoU)NS%AcfEK~_CcGV|Ah_1$JgDv0ya(XfG#>Uu1L>^A*RTGW-YTA$qgr56ZWYgN3kc8Za_T7 z6%-Y(!yklC2!Ht!`!d;g5hz4_ec$xqQiLfGCE~E77)A=bSWs-Qq$1uA>~iN&=We2- z!(S6w0Tz?Y?+2*2iabF3fV84>TipOF!fM!LypfU7bZb4pXXtVfGJCywK)4CiBK9Xl zz_SpuV4*WvTsXmC;qdvK*%3J`)cA8FNO20s0T-YmxpVg}R06j62uhS!3E&LdkuDju zNF@J{jcv(Q^g1ITIekMys1E_b$K{MVOMD!|G*S0{btSpA;;{EC&w2j=O}}7|no}0> zaeeWpDP|3w+A^90Kf81&8~tzSxOmAgtkL)_oE9b+;_@J6Hg-9VWxODy+yUDmtS_Nw0>ob7xeykP*jA84ehPFLc6AnH zItnzsFDlvx295+ZVGg5}Y=^b{JpAKQOnx7TDuT5BaAfV|;1GbXGlnr(P#Y5RFL1PX z0CB-TcgH{kghI6CkcSh2JhmAo_&4$V5o>+pjEv^j+f0_{Q2mm=51@bm9BLY=mM5VY zhDx9Zh4cG%YZM0QIMViB-|qArEsO1%E{5i{Gc|&0%2eEn6Fg%AI=|L-DxVJ4%CSu` zs%E^bT1x6ro{RsZ4$U0wzGQs;qw6B41$P)vz?y)PTUbp12XuDcC^ItaIs-&7_wHt1 z2!a7lU~Ak%zh(g>Flg!e2n|i5;|E!emXLd4VcA5g%UUM=FIapQV6hkHrQ^pwA|C%g z>IQ4Cw4g)dw&%Y`G^^|jWjy&Iy62wsfYw|F7fXsxpJDoJO4!73Xx(I$g`4Fplq+}>RA)*JvRC?vi7V+NO5gs zUkP96$oycGMEIBv>+~zWly~-;u4RoQ{bee#j~7Y^QoP|SxeCTVdS0EDhWz!kQTqN% z8l&?Ys#5T&{x=%J@>K_2#e~*+9`7<$vJdg6F+Is~c8YRNiK%LC*5%$vd+e*KH-)v! zlK!&=5G7QM#Dh47!bizbT=(J_-aq=GInf@IsO6)mdXVkPlv$!)L4U=LxJ&F7%I)S; zoL=J073??E|Fhdd2XL=;=Yu%c=nl{G<|l77^u<`49W;*<;x2pgY9xS-r(4nN?IVXC z{<%FYpWapIzK`5gu5w05Q+oj!_%pvy2$|KohX$-M$WB#VtMB%Cud@*;C}Q+QFX3I?Ve8BCf2=B~ROL-0) z02Ssu)!VUmjnT>3tywx;|J#TGZQ$RuJn?fG_X^R^)pV*lqIKQV2kzNtwshY=!&svt z^rX*QH$cgVyWX!vJd8KHmD^+NVQ#s2p#$61UnUy1eyd73Him}1Q%{=eSv^_h;=0Z# z`-I|w|M@e#xTy_dVtnHmid9s%K@x)F?kRjJKV54VncE*#z7;DS6}`A3u_)$j>u7Gq zhi!7N_RKlys}Gq92lG3;2ll^|w)KxYLWQ5!%FK2TH(oNhLUKY=QfUWnqe&tx#!T08y2G|!XX@73-M`E|5RW2y1tURMQEM%zdHty;B=6G;+i~Ul^Z>z?Ho>uNQ7G!)a8f_%R zxGXdJ`C%KCQu;D=4ZRePorbs8A6dEM=HK7qHQ6=ILmHmnjE&Yyjp3gV+)r&UKhxad0KE*vu09(P2%(p0Ft%e?($`i7+4_f6GhKCa$zOz4xbAQg{Q-M=4r zbA9q)U-Is|Tq>0Ml*x~3C*ne0*p7d6!2vXH3%2I8+E4Y}Shd4a>K0wROd~!0_pH)S z4u|dT4lVhMU=U=)9j^22En?YPm{nAb^VQR5qhx!-09X5F_SJ>KL!nJx+%;W577risdu`h*n zJk}p+>3gHGS0j!-sZp!>*`FsEx!l*9_K4P9AgcrGj~z&hXV-N0H#b?OzNsL=a*t|V zU~=QYcge7$&Y{b$?prl%U=%KQM8zZcF~-mZL)+;Z8LHK>4&$LEh4D=xJyb;^hte~i z=X5zOdk`MG{)p0MD=S`seMzRGYyb1Y=J=vJo(DcpDPZ5kVQ}~U#fSp_orVWI_l=C& zekdu+ZfCf;-u@_58jb3KR67lWLu6Ed671oRq31BVE1u&Sjl&*R?ub5VZN2@@oe#;| z3QrOc8b}CHE#YvR3gFvjqC2S&VpUG~1HcS1206$nAQ%fEN1b*TZvdfyd>w&9sJ%XS z*#AA--?wj*l<9D!F4^8jT{-c1g}G9t+7Y>S0aW;sp90t zkkAYEDn&~g)>z5O71B%QZt@Yr=zJb@bLoo2nbcn`=T$3>4dR}SAQ5bp)C(Wb)Qg|i z_sea270pFNXDIx>eft))HbI`KBLOv{T%8OWR#kzQ6X};Yd3V)SAd#f4l$h%B;}XCB zchJ8t3y-~Np59}l@&&JLq8;2H)QjS@lQ)Y#ncb$~p&6)cA4}bz_V{SJZJ|Q# zJ5AZxy_#=Ma{azOclYy28mM2*E!=IZNht$o7@!U68+ljr&K-Ke`AgNmK<_-5ukT3U zyZvHMGcb=S0RJ(u(J9inIy4D9;6dPEO#r@$*1ZTwK?Cww{F&uEf(vk?j=-WtU>>({ zXZ`2dc5v9njXzhFbhBUfBwMXn@5C~TgfXLA>r>x6Pw75RH=>#nRi11}Vb+~}xBmCc zw7InZ6IbH0+(Aib&Ep2FP32`}8FS|{f?Ha$WGmWxd)2=(?BBm1lE-&IW4K+O^x2|3 z+=pZvXn>;4%Rzw=wqnT;4ol_3-~hX3(wNBpC9<5Z!@C$^4NzwR^5n|0`rX&D@$)Az zvTpombvYBD)tb?emu#PK@p~=P>UvKlPImRXT&vV~%w1Jd&bGCY8n$59V9-4-!r=LGE*Zv-4oqjMchRSoN(XGiP)*RaY+{z=HQn*y;mMJL+dM0Vx zR7%LUJN|ybRsCZGyRMatzcA+A-`o6Zh18477VgT1rABK&bzb~7#IK|rp&av7aCPny zW#vlKWV)aj0Ml1+3IzexTA)}a!`6DIBCl?aJe+_8cY#LXeRFf>`#EryU`l-;&p~51 zG%}(G7$*x#L?TQEiM`nRe=+tQ;9T#2`>NAaX;=}GH0-jgtY&MAGz`}2Cg=6&C<#i^SlL<1C)jU`l3 zZ}`k<(6Bzi!m>+AiGb0dvc83$6OU2-J%EE}fIR`d?`r&H6AqI=KZExeiOCq+&s^ZX zq0*`D;%8=l93FloK>8cOu19Cj8s#-)x-J0n3r1>^qM2CNSE8ARsu=x5g02lXjX>B6 zHVqNI6MXn%92|R#wCd1RB_uXT2yVEf_u-FvXQt6Lh&Z{6K;=MuB0f3bU$+%0;jgih zWhAT`VDjx#mY$M_QU&F4-LZsjRd$tzEYrvP_+weAbjd{|wklbsFsj?EU)4}MBsd}S z$C0X@zsJDzgzQ$+pgG&x#P%Sbow53!J0Rj@BA6*%T~*un{UcLZn2_xGaM2LKoY*g}Jq(=1FJ02K{)!5Y0CGaWBO$~54wO3D-{0JVGqgGmT{b2Hp?ayLa01Pp9V+ z_B8yrpQiedO-O9{oFBUHDml7eC*+UaS?Jm-^jsn`s&oIo@9y2VPnCPOB6a4&CXuWsrmHj7e5D&45#=%H+m?kri z7Wyxgi>)$h+wkzAcZPb` zUfei;;r>!pL4JN5*C~AbzAnI^x7LOf+(YK-3MCS(7lXK1Qvc1chB!~T+eet zUIS>qL;SZ7Lt|+(QO@6jkR}O_Y3mi=G%>#msclhB=Xxfb05_W?C7xq5Gdg3;uPyhB z?NCr+(fT;ztHG|eBfacRRSmoJ(9nQf1?8U0Un>W6#BQ0pGl>UQ%^I%$ph&+oT2-YT z^JrfrrGum6kAVTHD2ba{bkdKbqxJ9ns#lO>4u)7qKxHK*JPGD38XZ&xd3h~H8t587 zrYLyE@8`E?$Bqv*HC||r1&rfq_y^T>cZZ-W0s$jU*Zqe2`Y*%6+-lZ5ytND2Es3Ct z=`C;x`cRVa_mKSOq@|<&XRgq(7r&oyzT7vaO^r$!m-)nKNB*L;RW?VPYS-@2q8!@a zc0R|r+sf2Q`O+-4#mwE0mDy@!g_=!Ql(+h`kMDjLzy2L((j~ol^C}P-v{4d!nU8!3 z)Ba%xNF>dVetB>zOxaVQk+C0>Ipj!yF_R}G5R7r~faM@7mp8O?_wHl3R+xcVFU{yH zDlr3N0Qh>^HOo^TV!-i1?PWVa=zt*;fdtHIH1P8VT`!FX#mc^wz!wDqhEI{P<%Ww7JRce(7|AdzuEO-72S5F{cLpss+AjBsC56+?v z+{e#x;)J`8==vMDlxDk=k;+P3jCYgg^-_6@Z;akjaP8loY1kPn&$X6!lcUpmw&vTI zot3P?%$3(_9&%4TEQPf-Os`B!dMKh4cocV-jEsp+ATz3a{AF3#mG2)uMy+NK*&hw! zi!pARqDl2@0Zj;r7&LJBiCG2^le@QV!HNU|Q9BSSsX$J&&WL7Jle{R@T%zIf{^;0f zmlR)1gSOl(nrNqyp1=Z(zrAN9NJ!9;YU_%{$Oe0)y|f3X1Q?;}*gx%%h1W)Uf4 zS@IDu9*_fM049oVlY!lcOE_E*B_@7%aZB_&Uv>$_OBQZtWptQU5t2y{|*DrJ33_Rv&H>r_hO zqfOYQoQR?SaZ9#SVPi>Ge#jqAygGI+x?%kKKEDS~?GUj}4KS_<<^s2pTxhVE* zm~Z(v5%cNkI~67w8Ecj2dbBeilb%wobxGzEG_?!UyBbTm=tNWbm0f2bJE~UCP*MD3 z-Sc14dQnG&c6;|~w=Zo?>UQxRX0`WyshfZMc~cmzM4R#+)$Dn$O+6A$nZ{St?C4YL zI-jNn2;%C+N(qZT-zJ=}D_+%+?U`U%fauuq$YRkA{&Yc2HD2-9qQ(!rr-j|yhRpTO zR~U5lW@LdV7c~@8p`Nkw*Pe$i#uW6Al%p7VS$*rq#Wa3f`uZi z!ujhC-fc$Y}c9p({(I@o?YLHTLj~|G++saMOEwdPoTS z#D)y?kG*OPbg`9ouU2~#}57Lww zaG;_ZjNrBdtj*v?wY0Pd%v@AMC3pvcm}(M z0?C5u2X>(t5HNGJ>`{z}$2O%|_DeuyYGkY|s>Niur$`W&Ah}%SSc2H}qcIA9`R6Kz z(`HY@sD3XzEi+5IncZ>6zUg$XjEtgE`K^qbY3+BKjPs&w&;I^xR+Bl<8M3nMkjtH5 zPdijx9J)OtXc7yrHp)lzzmGsiNdN9M^C2FZJ(y1uGXrQ2TdDlUnZL%! za~7&}A^6)L(%w}OY#K~~h;csZuzL_7#CX~(HueMwv}1LEOVY@{^VrJ|1lB6w0=!sW3{)A$70`y-p_NN+M3S4x>|BzWkSg5zDlu{q|NMd z;qv#8zm}h-blDs*1YU zGs8{(wdW?sdq#pPxYf;^7uNO`x4#d|Inh-v975;+0UqFer_#uF2i>#|)tnQd!>o2^ z5Xfyj&7OWS8+fI!edu`z(Sra~ z+>!b~NsR44q$I>}a65FlsF8Mj8(*-h3keQ>o{#`wOuiYm<9r7<7W|ev=2Pl^FSa7w zP>6)?|8fZ z+!ojyCiMd+xVg~l%~wii;XTyd8U@YmO8$>zyj}PwWON#*IB?eSRNv!t#=Fiue|Ax@ zA^qkNt%+>`WeqLXn(|f#9M-L4`V|eVrmx5*8Xvf?NH)ZUGDz?jRd?NXG9M`3|M-lx zY?=0zE#IB3jw`D#x#k%0G#=MzX2VLC=Pb@dvHjl-E>D90Kmd{n6`Yx$Ul4tXRvED+ zl6e+;1I+l;{l7Ac%Ql&0LBpE_B@#V7eb(WZajeaso285*)H3!VyeB&oGE zy>E5mXli*~b;yup&jr0G9V=N%zO~SM?I!)+t$m9Q)GRzI3e`W3D(sKALet~F?S9X@ zp`WwW>rK>i0*Dtjr90ajy;Zu>W={pne~DCb*!SD!_JvnYu9@Zs9(1RqZz%rQ!=V0@ zR!I?ctM>KJ4*&g47{w_Ftt{~9FybBJ!_*Ht+kq>g*wCR-u?Pnqr(Ggq-(|VosVHg& zOEhvmr2*N(P^2Xf0qW`nq(l8!x$%V!iJvZy$0zf?3yY3m44B>_vE9f4PE zRG+FpmWaYeIiR|pqSA(=A(+z>6Iz`S&jh3|SZ1;%Glf`n@+a1f*wbH#Qh?h(9hf{O z;`;LESB)9cBoZ4Vt+41+FXpnkgHaKy=ANm{+-;A(n3XqmdtC?#I@nz(a`V2(FPjwJ z`z0Z{mrayK=2we;eT&>=$*>mqJlMHM>;2Lb?~O`L1!N#^a&9v)xaEvL89Wf_+?+TO zu<_Rsf5JKcdv4A5j>`s30mYGFH6ShVocbg7=3Ky>9@BlBL;QeKLBfonzYy$a;IRmJ zjK;Hi&>I_))%giBA{u11NW$LWXE5TfJq?@;0jWdxnA_|d7YNZxx9CIUDu|bbR66lv z5T@(HF5&(NcY2onsrzip(fB09seqdKiSEM?vVL|IW~cptvSLL{ps1S&@FO>&2l%FD z(B%1zrwMRl?XGi&w^GvH7GMv|+sd{yu#a%B&Cxc+?YUuauX6(IeIJX1b6U z(4eNEzBg3Ay_HFCkn;QRgv5<-vJ!fc>eh#bGS4+LmySps%0pko{et}ca*5mb2cCF` z`Kut!>671r)xw{f#sa5#3PjyJn6H0s%rK9l4N`wPs=#8&`ve)ZiRBj)oF;!_BrhK# z`RyEtc@cwUHcDh4w;@5Ha*Gs|1Ga|I7HRotrAo#&MYNbS81bC+__2DxKOi8WF0!1J zdiKMP=MwQ(;dvFTQ`WzteneaA@9DHa$X?t!HScRX6sQIU2hmT^5MeUPQd@d{wML`$ zA-i&3%rzSkPLW!LKDEpmt=yX1If4}lk9Cz=rkxv-yHg^6@i+O{(laxQiyWMnw%eo~63t!A>yP~(c(RV$2azW%xGM{2g8u|MM zS)a%cpL-8FSPsf((Z%F$iB3=7g3yT+s>7;D3j%M)=voTciRgA)UdV03B-wgJ zWrP2LH#?1v&8r9d6>={B&&y7j?+>yuce;wDn-$X?d!xjz7*q)4X{z)7oE>^{EBl+# zwK|{oM;N|R(ysjAY_WPImg`FlQvTcQ@n5;|U)PPvBp!OdzInfE|DnC-@0V8%m+gN2 zneIoY>~_<0VvHJ6|NEOpUTan}*L3Dq&Q6twK{r~y8iVvb(jLTUEVXP-E#XGN9{U7g)+>H1CJgEQchwR#C ze3R`_uE_uOH5yy&NdErz8uEbCU;v|(+>_{?rN)kA``rL`Tl;2+Kyt#vM zAe9&sYhsTbAtTZ|jt`Xjo(o3!?ex`n_9s48A2F|X%{=GZIFniN`yAA!lp>@g5 zS04Z5l>750k+smEg_cE2Wm=LlD+*yS+uJIq35&C|zOLjiq;4*W;N;n5#>dmq_*U_A zdHHFSo$=m%joi`R*Lik@Zj&n7pOM1g11-4noG`3iz51 zkltuV1^jprEO}~h>UA;Ipx*t&#N);e%ftf5+EpBYI34!&5#4Qsy3ZzAGuYB_TCeg& z$KFIm6v~C`%cDXoV;Pws43y2HBS6$vtBccThD@5{_7gB5V!wm;)qkhKPt_$r4Wi=I zdWQi4dU6LSDJ2jNpy!GrXCFPi9CAQ&cU3W^V@jTN3QZJQn81Ape>7?NCIyCUmz4TS zHr6;H8-kSoVW9TccS7@47$BgT?Sb0=%zA?)L2pYCbzm%Gmm2E-g7mq4oyq;wYKw!Wq-)ZQoKx>1@wrck8RLCcaK8zZ) zX7h+eAtwLcbwzh{4y?g#*#~?Tw0mHCPEWkF>RxHkh8@D;DpxcKoC6lX<&5--RiFH?nG7%#xjO`e^(O*T9h(yFhuy7Y4u|udnKyufu>Tm&S z5D?|AZc%vlrvyb1ZMhbx2{j&2u!(sFju5?+rcC1|7SUR-Z$)?c(He{-@MGTHXvttC z!q#@<9|sXShn6)v+~v#?84Qm-CyL9q+&gc zjK5if<=X11r8PIuW2t#=nyOSPJ1k9KN)x`)_A^cltREVJZH5C47PR*UXOocS!8A;( z$ce!3qstKWH4jxz1#%dIAPz$Z%yAZ@&a0_f!U*B4%1H!PQBO|~^*CJqj7!O6l`kYWDf_#9aiF%X8Hfl+sU)@&Z|d(dQDbV4K7U7AcFx??IeK4~h7;X;Y``Eg^PLM?9XW4uR^sa25o18 zF>o=e;f1fS7{)UR3F(AJ{Q8n1F-61$AuJxAupD4w%)b3T$^QlY2+R*oL(KoV1QTwq zJ_s{_N5LW05{PNsq-sKpXE-{51ao-K{ZR1K2cZ&UQ6GZ9!9x>LhegegL57@$esd8kESdB` zcPJu(1eE`E>!0w!x_C_PfXg7D5Xe0O-%RbNXR}XzB0V zYnSO#Rar?`rbg}^h_#7fh)Og7f44v?uFDHwLbn{#pR75aWfC zl|3b*h&7UUb^miBn9oAvh2G)&CLv*Ath+~<6xBA0H3B-Q(uk{si-kEY3NC{6L2xU9 zJ{cnT1Q5@nk(ZZ8g9vRNz^UCKT%dH)6$l0Fn~K$!93+ z@NN*@tz%|%W{2VmA&f=gXlT zOA|U{@aHfXf+d31QyuoHe6+3;u7KNwlA2_m_gzpl*CNW#Dn6Wirg=VY zOyrjsfuzXHw3(Te<)~vmcI*mz0c*^=;Ct*?mJ1`*M%%c2L}h!?S5gAGy&E}RcZ(c69S)3h}a`&VFAhMz$;k(u%D80 z(CX`l4FRsz(ntl zVH!G5&(6`Mwd&OABgwkdL503+Tn4g}&jg7A?{)(!-mu-(`Bb-PAOe(J*)Vt=c{|?m z9bF0o(hx+ebLz*nlQSu+ly2fXBRQ*F%8gS>juVD^;do|$NdY2MNLiy!ddzM)e$U+< zfRmRP(Bi&eyHsg+clVMr`g(tJuRrSK4xT36wW|^s2Ovkxx^f%xx@&4`mbj6(5}6Fd zSdL&auB4>N!B%gQm7AA$j-l76U~D_R!#zT10pPAt@7bv-9XMzVsA9kV9jtz|W?6m7 z(GYU;J`u*b#@#YcPW~p>c^a`$}YdP3T=M9Ot{^Vi};J8&+YtCat zE$7bB?J(6Ks&eTYMtpy&wWk8IQ4Pd=67UVxv|C$=k^`pJCQI|!-5n2E3+aK3Vs&ex z3gALy0et1(Z@5$5k-F8Q1aCBe{EHbafo5Ji95p5qjF9h9QVNkOz{+|nW-|bph&cvc z)2`hW=?=uPCY@I?&g}ipx}Tqgo4aWsE%GGJxo>uy|-_0wuB^9}tpH(0@;kRMET!axiX( zJ}ABV-s2$j0r$Z9PiktZTN^4;{&LI8u-or_Hcl>C40R@H@7H4)o|@SUdIgCqF0ERZ zECz?D_gB_h6_WW(borkMb35d7O(bBaCAW3FZxIXQsB?;6Qc@(jwq$FX>sZUP_FIw> z0<3aM6vzt*veriMsyx8CxSw`ySI9YFo z?W}~z+oJF)Zzgfue4F*dgPRX}9SsWT@R~AU9QP!u87YWGVOeGf4(>yP^l=RJ2^`a| zf<|I0jL~TZIQ-BAf?O5?3{s`3`FUbN)z`QDb?qDk`G**b6T4x=)%)|~Kzu_Me;RUg zNCvMeVM8G~FemQqW)ceI7-^LPUqZ+|frAD{B%};R8oh_qK6}%tA7#9og-ClE*=K^2 zRHQGEFNCwh52CI^-T^Zz2Xqf?jC9nSFn7o_5|T|o#DJ6?%B%uG@gc zFr!*iSKr~$u0nmW)~**{a}1hA1>JI}@B=utV*oiqm_6&GIhUcKNnja~OI7nO0CDmY zn9LR$AEF>GW2ku&=BhK`YoVD9iL~Hk+BOw+{;p`i@hekZw*vswezoQun(tsA)> zPbt}#W-~S#QI>`{UD4%Gc}ZwwAJ~)inF|eE>Zl0fq@62f(2I43%e*1z^yF*tl)z@iN+- z$MC2K*-qQ}_W=Qf_T=Gq z#vkMQ$wl`w7Ix8imVecJ=x!;QD(JY<5|B7{LrgJX?Cb7gAFsZZZ`2$iti8RiBP{WL z6ey_-&3g(1k&yJZ%YibMLLjcbCPvWk7=6I{q;k}HM3lgmcWkCUE+6{*qt18W1~GP@ zA%xF@f;7PyTX$Wd!a*EGs8Sy$Jn;$|L?9m0&c=auQ&e{vW7`V18tWsKwsv ze4O8iYV%dh9P68c7VmA~4Ooct7Rssx#8i^G; zI|TLur3&#`-@c^7CFV`$mKP z1+qyqx*k>Bxdlz>wt^$>{3%n#gAX>p<_wmMohW*0)Sl3I+Ds(q)1+a>uUrB6#hDoIqD&@Aps;<+i1hE4GK9V+#ZoYZG2M>17JXlYd@STN*6u;)(Q(^u@()Nb~-DZ=F(^oiqDMRC{RZey?iAtwWrvv$kDc62*%S zEaQ=acSg!A`I6UmCe}!Mb{-`@Dh?T6W)s<1uNA5WMB;=a7PlUBFyvAd7RJRAOo z)^A?tx!Td)G_DME`8HdQFbR8Y)pq;X6Cz0R%SMt6U%2wJJZD=FRuw#RTh%{$v(L+6 zDJv(WbJoh*alOt*XKw1}t5n^pV9Bn->1P^Mh3qLGPS9N{{p>G)t!8D3tAcYVvSH*7 z|F7ZpGfy{}U)(ukmv}vFfAh67NeNET(%BBzTA3N|7CnDpHSl>_E!9ksJXorowf8|H zgNoMl>#77N{ZFi^v5Uz+8biUmKGaxY_=*x9-;^}v<%KyJe8B_hDxJ7ZwR^V zMZq{%n8C2=!bdjkIoZ56KNp8G;njfwm0zt*3Ut9C{^fHU#qI?Kf^KUSB@TVhBoA@v zQ9qodQ;l$VoU2Oy<_cTTECmUf(DI{M;p>-NHaeLX!fGNF?%fx)-E#>;l#}5tMh!-X zhXlMLErW;1D+1-B6wWKr<($oyiAF!^>DyYO|0CpR6`$+?X<-5gY{HoEHVoM+6nSr$ zyZ_xTD`OuoYbXW#!%=r6mbz;X+r|Q|h=cB#8Vk>#S-(X;byfr@$xx-8G~kncoAaTq zj^W;Fp%7(VSm~>}k}_`2A~CCLN3~sM7)cG?%9-Sayp&@v#F{b8%5x)q|{pcd4At-HZ9=_WKg!}@Ffwpn{- zsAgyO%z|Xo&RskEzV$u)8nm##Zq4OPA4Ss7GjB;3dxyeEruqUhrWdC5dnZD^hOVE& zOP_2zOjQ@c$j%&iTlns5ODscUw4_C(fSo~Ka4OfpP?JUdi(Tc%655_Ixi2~noVgO? zyv>VRYBY{@qjsq7*n5Me0|K^_<+bc@D{H^L>!&OF)$VpgEySCy#O!B|xjOnW{VR`W z>y0vPeziVKDOyoJ>z$@q`px0k<8H(B)9T}9LcX73bce zX|cE(ZAq%&zZdq{B12crI-bLS8`sDavw8ik- zH}~mTvODcmIvpk2tfwVqUlHS_r*GvDwNx{W6bR#r+a#b_Q>@9Ja0js-|I0BU!L;Sc z?$S=Mzva5~XGdf9?9Ow`lH*h~@dFBSHmb6?$DLov?M3CnrB3cJ=bp*=h6S z&YAw-y)Rz}J;?E~c&z1SGjtn4uUdgUvaM-y;$xZfxrc?w_Sd@3+Wk5rdo)PUr!Ci* zd-LXpm*u3B?p#|~4Q$dlYyZSh%c*?HI62Zn7G*kFEZ)--I;lIveQT_ge{TC-&WEp81X~ToE4b`Jz8Ey6*)-0YjS0W~ zQkq)JoPokP%&L??w4JL5;U1 z{gSm(*|49`-Vh;Ai_1*QJ(QL83lYDvXli5MzFDx|>}bGhy7&0Z4f(d$-&*oSQXs|C zrp6KctKB!ff*Rc_ zci3$#lahqw|Ni`|?^#1rVzZ;kgMSEl;vxEg(!8xfpFwdY4FR{O$9C4kmhe?w0zyKC zQ)IiXx(5dyyPXf8P3x)IlN|Gt#_y(=#=*@OKF*U|mX|3P<=T;vchAezRj;XoK}tsU zqt2ZZh?p@oYJP&nb`5kg8t+~Q1((fS>b-NPSIa6rgNsJ^eS6Zkq*kjs^<$YA-c+xm zy?sd`SgJ9mMtuq)SWn;Jd;e%f;3Eg$1DyTiqEx%J5YPQ$~_n?OVBs4vO07A>HiukT0r|f;t1z zrn*X&SN^)1R5P`Qs!4#V#5UxLl7@D`$XA*~j`9x^PVB$!O}+=SeC-WcPu`-M$NBQ& zP{vZpWB0==lrq;66ZW+1wQG6uQC3@D#&KX!@0HE)(eFkDDGf%TJ@S}Zss~E7M?Nz1 z5nP%19_7Yi`<0WnHSNv`c0$i;}RC8BZMGtuL}EMpMmdQOi0DYqkWYS$RS zl@NQ{5s4sJkk?&*m@m=aqIlg`hKh4)W^{7jKI)$uy7Ln6qL0n?b*45%-{tHHTc>a; zqK%b1+&>#X*;8NG)@b;>TSLIjd+7M{(r%-&(k9Q-Zb9c~m0z}46*iXDE(N`p@N%3j zmEYv>^I5DT{tcY@VNKFZMmqFtNGmDLLA<5GC^MI0J!yFUHnkUhi&gMDwu94B-n{y} zYV0177fua`c_ultsxC1H7$lr77rk{Vf%`&&z?sy?i78^!hYcFMUvGX@t!RACVCJB; z=kdhRZV#D(7}i6X1#;I(Uv|A|Jdj>8{_S%>*g91d(O_qrbK(zm?b9bJbV??QNE32q zwRtE0-4YNt%qr`Bfjr+tn32?%D6Vi}_;*SL5k2i6J`+D1N^O2M)-0W6KDVD_>q({?1RJuCn#)}6@?65Jrmr%TP)T7SO%s)e2K}=g;`IW0PNea zZfdz%J~%muwYsjC;ZhXi3D#=WXGsYx#_^~0Cpx3=$_G@0xlCEeRfL82hJWNp4t{)6 z_Nk9xjaX8xv?}?YSYMfSwqN7j9dyq)pi!iS1HeTPgyY~g`U_&vsq|9ll1q; zrf|z+???~kUt$<0zhvoJ%<5W6yH=?}UgBgMZFZAS)$&kmIE#0iJqL4Gs+*9caiSlQrUVn<=wSpYZn2n{0n{-I?$1{n_bH=Q3`f0YdLQXX(7Qx^u^_7|oTv z9Huq9EEBJhZzX@cx+=s*nK4^*#r)-e;41jByPJCU`~%r=G?11AA!sBV2D>RCdXEHG zSTMU`d10Zg+a8Vxas7P%(?K@Rkhc3zHoT(LE7- z*WPQ&P%rf<>u5P8WwpS8_uhMI-#x_PP9ORibXcl&J^7&#{f}pwwu;}|Nr%$gJ$%#ozysczaQu|%+*CL| z@!^gVpGit6I0i95EbXU8l*?!qTQIlh!@$>+9MxCkhsNSx=@}Z_N_%t8 z>5iz^TV784PDgt(GUv55seGH4n(D5MOzi&k@1GzIiwa`m4EYZVc<#>KbW0@Fl(j>@ z`W|9Ty^QKvq5pH#$z4cW$V3+Y(smZ|*H0sznx60PIZbx@&aWbVo398ER&`HbI?qhJ zeKRvlly#OqqF;Qf0|Y8gdVIPUQM&Y_KYn%T{#~Nl3SC?IDNV=8R(M*gr>Ai7XH>2E zrPSyR;ft((W46}ZQ{TAV^w*ODg#`N;ZPe(5m*;ewOMR>yHi}IrepeopKRDa6+rV}1 zzO{M)ebHidb*l0R@3Wwc{s6DB_F{@xr^4n%o$Dr&ExUeCMLDc2zBYB^v|#8ExBZUf zQ$fM_a6|BYCNb7vznW9;(}sZWuS(YD2Zwnr!k#DuredqRk;_KWV!^<^%X}_;Lkuf*lQ2v-{@l%F3HSYSS z4~(UlJg|j|y3ft=I4umzBiv2*sb8<^`dux*F!ltKZW0eZxMt0>~0XrnV@A@-%d-V&`iKNiW z0u~XQZ?FsTR@(Q$!6#a&sRJiL5nI+rOCGiQ=sZSEP&n19@3WcCC+Z zwoB;nw1%|ahJU>6qT)7)@iZ`INy>>)E~yfd_dj1{N+VC+BWSef!ZGe?!RrXIv5hHF zo)UK7p0(}aMu$z$(Rbyz!weiOXJ{YsnrJYk9ma1I71+I4*cj_}bXJ@%+L-=*j{8-} zu}AMK4}7A0{eJT3$&?#ZKdzCQQ)J!FDKdArbrA|Jb(279H+pO$ELGcE4lWv?T;MXV}|rbs$LfPwKJ#4u6gZKJ2l#AaOw`t_oOau<39~IbS^#auv`q53$r)5oT{f8{3>EoVDT>1 z7WGpF&ZAP}0tzV?gnj3-JePSlHt{xi*42DYibeWF{cvr_CX`Crd^S0k0^ zODog*d9B74QXY8_@_FFhXWfnzQ}huOoiYUL}6*vo2cE zH|{CwZS>t*_iNH^SsM~Q(b4uT-=tp6hcJjFam2@`(I4ISQe1L{^p?xbXij@xy~|Hh zrFqW2$zn^ajcerRwf>b^ZtfZJq*S#xyfkNLW$dOSxBlzP(7t~0CXQiaxdC6M{Lqt# zw1X#1$I8B>(eJ81C4PXdHFJ7fMvMBWIm1-Q#!7yxulcE$k7FWqxjva~x%Z3l-;YTW z-jt}xZo1W()9ro7)s91lKeX=EQd?h_js`W z+6|HhiIe}BWHS@jRb%-U3zAz=xIkYo&&;JaeB(apJtNXW$0*?<mrXFhZ%BVqTDR{i@Y!}mr|Si~4RiN5)E;5>B?; z){Jqlo8p|}UIyAE^`Q#?ULl?%Ja4kpZxPQv?R;B}3`Z10DL(1)t0oZqO~ zQ%Ee+ zQ#~WAe)R~gfWPJ4woUY6o>f;YPj*kNX?~x(oXsVgdPlT$aP7txpS|lvTQd#&dR3Oz zHTlrGL6Ioo%E1;wRN`UDDmE zE}N2!gVNi_c$2uBq51YG0HMK z^0r2q^*Qsstpe`#yS~*Ye5;SI+e8vV8^J~rE{kvLI z?Uy8tsH<~G#kmkU^Kb7jV5V@??=dD|vCzgC!5Bo@$;m0n{a_lVDB95acnM{N+tKgd zHMggPho2{221?Ko5Egj4%)!Fah-K9_*fJg%6A#(M8yF5g|MlquXwbY^DlZ#+RsmQY zpT%h&ZGxLkBB#-`_t}4)&%h(H+gc;f}@b8KIeqNrQO?9pd z8On$0f^N-^vfb9)UIa4%kOI@RB^L&OsD^4&QeKz%(=aO)kpHuc3YI z_u@spj=Fm(qNmV=~q+EhE!} zR%kPraN9bAV&VaF*!T_I_AO}DjqwG0C1Q(EczZ@HCZ)7lBI<<7q36~xe}Dg~FJE5Xq?VSI zHE*s%|8UfUHO1(qC9lf0YrZMP%Ol4bdW-JbYuYqia)Rg$5AZ@8)`#JYIrC=FZy3p;xY4v=_R?0vsHBNw;~?F(Z7H0QQu|zKd7Y1C5Yfj*%Bx5|1&i z>bvs`_S_2mr9Sl&Y;+-93(&U;ul3_G4$p@a;A+!uDsu8)kOyoA&uR`U2jwqxn68;-rf3zZLAOK+NWCoAHK%ij_tpe*S7^WN2(Dn3f)+$J zlq`?H9RfS4iP`4VB+1vEYJDMkIdvrGeo=zRbbh@7z=-hsEug0t8|!*dyw%^e*% z5La>m6>}Mz>EeMwBAz7BsOiPiUKW*ocZh%ik&L%cSw7-k8Udo2?PO2)h6G^4*RgMQ z1WSpB};18$Q*#T5bD9>i_v zz0nJdUSWI%*OY{xs4eEqJ9%KiEm3-I=B;)RD0;D`-N zvAtqxnFdwTNMO%Rz-nb-V#P20$Wdr#vvuuu5A1S)bPJL5l2gejA*P zF|4!Agg+PDA$%7oou(+&Qk~4U%_kvwbP|^l>hY<#Xv&!B`rxldNzyxtKip2X*M#47 zb@3^O6R;4m$^|_|ceiiV2PXHzic8Dgjd|^jXim4K>U<#B;Yk_33|MW=qJ?lm{j#53 zfo6cFT_Cv435c1M16D-%YQm%QfBl+rx-L9Q5Z4DEii*z}`Tzx(|Bt0Ur-uv*qK@K? z8z-e`gq-s&cvt^)9AJU_lfTf6JRs$`3VZK?M0kjZiyDG_BX64q zQ$cr1Rh9I3PZ0s*QN%jB-KF&~58EGQ&%(nwPoGwx(zJOA5m0P7;{oA8!iP!G*f<^+ zDhV!gh1Fq8qGyyot{Fas?@ekVV3lmn6@m8bRpuR zt_v~732qzfa0}PLVek~;!1V=U#02kYb@uQX+3PS$GN!BP&lUW3py`D<9*L~yoQwYd!w6QN?(?I~VtFQLr9Bq3x4O`{? zv=L|_wi1QW{+;0OAkx@-BtX%3+Wgd_uah~r~rXO~5kAq^4{Xhu+(Z}u>)THLq0`b34aaqq!gKRVj$zR~H zUW2kO;k%GEBLy;oBr}14Epvg^y(Zykfc!?vR2HYgV@D1LMRWSrBLX`{R)l;$5ehKa z(RkUHpRF@Z*Bw58BNr!3Wc~Qltj&#hzI*6}ZU9)E!n;QbEG0#B1>j$#XHtIO#SVsz zb$~Xnf^?A&Iczrp^)O_Z$m@+jU&6I|^;1*S4j@8yks@g;t8~D1342UTO1gsVYq`#C z{d!_IT+=+rBG-sr>J8I>Rn^ui<6;95sjvDPp9k7S5nvtjJD9!mNj!z~MnKJi7z4}( zUJDctS=(*JVJ-`Sa12D68yC#*$Kb;AkTTDK9%T$^YIdhk3<2POwV&KXt-^1zrsdH0 z7!vDkSf?Arqd5i4S{8V}0v73H<|{z_^Xb1y{!^Q723LIqsbm9Dp#b!DN?2G^du>Do z?wAS`+~xV}1_m+su(lAQ%ldBA$zRGvq*z4W=Y*V($dkb0OhA5%Oz0iX2;U&3aHcBU z_WqvIdYC${YXs;iEhE1{P-rH!7qMSU_}4@(;P0At?fPm+^6>}#f)cY7RB#%B`kL$PT~`L{g2?)y15V2$Yb_!11fC%hkJ<#`yoUZ&9TJ;lB9+Ix zsioa|Or-uqu7ev-R2f*n6N!Zx!=R76)>lOshf4BU-wLHLkX)p~+}87OC+5IBPK1=% zG63x}FzV z3mt*tbtaO&=-Ak{d_Jst^a~411xQvCSz8MvALwk%6ck<(1r^MJ1b4t`$qUpxWX2d;u(L5u-GhWERM8QsoP3ov!i(A zytZvH+%NuV8un`%R@Bf4KD<}*x#S^1kVTR}h=?ap%;6`b;SFK^6buZhs9a4D0<&T` zrwJrC@gyOwW(-HbzC6f#0IQS~fwE2>$D;5C;on_NzveAUvCu-T&>@W@|JTty)Lh~1 zYvmnqe)HIC(cBRl6qI1$GOB(vHuiQBXYryK{*B})S)Ea9>g4&1diCd>v#X;+9cFxi zF~b|Br&>4GI||a%t=L_RqX(Ut<)1yPaZ4eN^VgdPhUp1Qf?s_nX_R#YFTQ5m;FF){ z>%F4+npw5QoV~iBWH4i3qi5W%dK^uRw9LP|qA@p%eCKLpmibJ^Uk4C~>EDfv}y z)|trKpulJYq~LPE8uohDgX0hjs#;un`ZW~6Eg+1=g0S${yfyR_N9WtL+aMN^0Edj) zK^}aT#xQKQB$mt()iz2WELT(Bm=}y~iU&d81hOmwD9W*yGO=K?SRFtAW3q!fJ}#~v zX`L+=mt}v;f@H`7;r@uMrWs3+!(9N1R)#Gg^0lDb5q`B5*$nbd6}Ti@L|P+wkB&me z43I-o!lOSQ8^-qAHlo7;Q+QGoiY;2UhzQ~4#iu+h@&+i^P|r7G)mk|2;$P#W!Nm@L zJTbA)qB&K&B-|yUiRuJ1a|?~3i`F*>jkjceCs~=aa%3l%3%ZXt@#t|Eh3&a`X3zB} zpx4Qqk-eDCHfiXXW9?6k<{<)F3z90^@vOE3l@bj|Y5!c7$Vf3*buzy=?b$ow1cxPA zBkvl*s`rvw1Q>><)7G%0i?HBpc6N52VTrsNF7qu}6Ca+(czEn80(Iq|pszM2^ydzV zN5c0)j6SpYchTgqyXb0!T$o5QvEWuM+bocX%2GYi_uw^>fsnt!_f{5~7q5v*ng{~8 z>Fcg=oLhy#gQ4NlxtDF$9x1vuEboM+baNnisUy4)P8C@~0yrBcs7rj`5l;{2>;#5L z3t}jUS(k{-mHxiIktkEk#)b}<-dz}Lz{0h7)R;{SKgPTAt^@AbXr9x3{A~>YpL|$_ zZkqr>wHkvaB^AwR&^lL2$Nr!7+$(+6Wg?<>n5GVcL4fUHjiCGSU{S>eH4xM>*pT`Q zT^t&uta!Rnut3$lhmfD2xK*+_8={sXtrv|{u$RH6(>$l#iJEv|_w2rU%m}?x(X{mk zsq@sAyPCRC%pyL9+u(aFUynmYy1qb^9k^6b>_6ppl2r=XT{FJQF)4x_i*l70xuRPy z+B_}jo@BXgxDsVG60tvxhc-?7r2vm0uA2{_?T~^6L3Sfo`2+>kQ3l-oJ<)>XirMjD z2N2;^7;&VtMMp;uBZLzz5~4|km~|2!6Cw}Ozcb7``MQB;C(>Fp?S`~DOi|eUu?;LZ zMd_uAh};Nf3eVpua3UN7_yQQ;_OeTXj8rVLv1;vhzCGAlMOk?S+)LE%YQR?%lbl1g zhc;XbG8qu5k^os(Ge`PKG%S&-ON2@K5)X3HW%4f3;;^Y^&k=97Lu^LVPU2N9Ro-Wn z7Y9*J??b1OtpQ=M8O<`nhS5^-nt$=kU&BEq^*{*!WTpgP(iIuo~WKiSkJ`gZ}#6p*v@J z9Hw-Db~nX-7#4(JY~ZtPxI`s2BPT_Bc8dyPEOLG{Z1#~qMv7v(u*0*ru2~mB4 zuCn}_$izSc_btqD#`-!UA&{1mdiitDGapzo{1DIR|7!2eqp9xuu+d%aG|^m&(4aD> zLZwJ4B0}aVl_7HzD%xnE$&guwka^BLliX26rcDSs{-d z_nbdoYd<}!JA3cn@B8}>pU?HVuIux@up_-T;k&wO+FTDM!pLv zge>A(Md;sGW*eZZ;h{G+0&ldJ|GpLSryb^9IA$XW&zv`XP13YV1xO+wEPN8CvF7%M zoT`ZGAOTE(pqxx%vOJt?nxT{-X;ZL-U82)?Id^~Dp=tBK>9G~R^AR*JS7O(?QY&;l z$puR%1)-DpH5F0hR`wxa zx!I6HnueuqTY)+Iv}(-luiqCgZ40d@HW89m2AK4X|M*O1`!6+)y>iHS5CdE;Mh7mE zU6p>ijEg2&z#7@E5>&si(UOS#a$yI;>(QYD7eBZlT=w(#-_|Iajf9wloS&S)n@uAD z9`U6_?N}l$BfXc!(^gDU}p1w9=Z7u^Fga8mhg= zzSoANwW&R4U3s6ath1N}Mfz?}p#Yv2Dw}xa>kH$B9Buzb&xpOelseV0L(Zp{-Ic*c zix-Ysz@#E9vkQY$lauvN80seMH+-#j?%a5`IT@f$dACx&4vCy7vDCgfz@n4!tNkFY z9mU~4!CKc?>*sXi*Hf(nqpysvfBB)UTf&I8594ioc3OV&>o%(1uOIX4v1!FZ{K30t zkJ{e%7iF4K`_Sd6&z0@8%E^Ra#!BoUI6sbdhkE1Sv`|0(>qW)qwi^*grwb~~ zJN=d#=Q^fM2gPm<=?n9FXBxblWk_k68&9JsPxY`+2F0?2pqmLn^CiGod?5v>)Jli8r4G=6l<4I%*I%vz6w8o z&L_cI{$06!F(vHq2lbayMa;kJkw;?@+5^G%Zy&I!|GC~R64@gB!oz9@&zwYu1Uy3ZF(qX+2Xm0Z;HLLPGlhYJ(vg1N1F52mW)w2a`!a>`je;2h~ zNcr#He8b)kOSdUDPSIV@tdo{AorAlb2Uf@0kcsXx`dUS){-)v9mV4bphbca5#uZjL ze3l~j94u&Sp!1sJ&16n~hYco-^MNGq3#RiTgoZn=eX=i{J_`!S_Y7u0Fw!U^VAFHuJ2hIk+PIZ z-NPcoU=f##!7o;P6e@J%Av_#qTX1kD!vATIP*j%F{^<@|YHLBxJZU)^oG?jLz3 z>rcu0$oSZPPPj4NxXSmiS!d zmdHBk^Up0&al)+`mbKnrn~`R(V)-gws-o~ovN`*3UQ8rgbZ^bu2Vc?!i%06^J9eip zEEBA&)yO~SVB#2AtC7beFXOoFgpXn)i?(u3Z1KwP)PcvecvAh1sEfGO_i&!=Uw597 z&#$|*pmtI-Q)!0JJ*EF`C!c$<|K-@qQw~pUe>}1+&h1Ig;gpCQxck;zI``;)t6!{( zv*d)mVr0(qYjh7E_t`!=^t7aJF^!fUz*6q_CG3U%lKj)gI=kO|FiB(C06v0Cv&^G^ z%JDh8?+Y?~ZpCh5WwoLkzhpyh(Y;i7BX@k5y>!5e^ zpus1^{hR63lDq0xY0j+m+M#f-#i1QSNzDZrC2cw&fBf@P7der5hAED3RI`BH=PYea zu1<-4=b2^^p6b;HUDNl5F}QjL-ujpa`yA{v2>8f)R_KBT$j(Dv7n5)5sK48k@X_{u zqOR>4)(&aaX^o&TCCNzjVnr*ZO_o74jSR7QN#@O=&-He3OT@Y?Tl^1Y0vpWvrgs+D zjFw$rYMjK>-p{{Z&Fx@7B}b8i;Po%wpj&8F>dxEjmHT$GVT-`Gz(}KqBfI7gJRYmK zcbwm}933Oete!hGxNXo+w|TW_i7{0pv*e<<*^Pj0<;kssh4;%_?)>32U}{_1-A!h_ z8-blhQ(Ahpwh-OWNb@GW#-TlUchYSg88;J$vDTt+>gVAUWxd&p^Lvi4-nhX!%QAoE ztEW-%0zuYhDPJoDyRH6OlQDHmz45z}hCXMq+nr3GouL{vqLtZlkr1dKl)JcMimwziN~g zp@%oTOH8O@DBu3J)M{<3#AAkMY1zx&k4x5b%1dgbGv2$Xbo~^Js1=J(%-QaqQk;{# zMt8G-^CmsDl^i7s&5sUa=lSPHqTmCcd&~!hQF)3GeW@ms*qS%&vP#E|U&Z&87F-tp z9_k?&z%a_!j*zYUDd;nrJztx<>t{|u%Oh!xM9x=}&EBjWuM)S{G5$lPqJ+uz2B+hq zZ@1l5bk#K!vD8WA98@ToaG$1SM$)d|oZh?7>6Ff<#_lmY!X%W7v+ai9BZ(1gGY|4WGQFJv92rdb8y#hcTL>-o}C%>ocYQHOCs4 zqy#WhBsngL2wd1iUusgMw%+k7hELB>TJK8ekh_w;{yOQXCbkdEDNFS#N8Lc^;cpFo zQuOxHf35qoO@zkBpYy#^Oe%=MrPrY>O-oKQhk_Ihia<4oI;q z_!Qj#&W%Z@T;vb&39Gnr6?(myyD{t{#psQz~ zoL`ry?QD{4ekW_GAt#-_Rpb%tjZ~5@|Ne0~x$_#kQ9|ScouOUxK3e4Qc`!+&@fBpw z_e@B$XOlj$SW8IYwc%Qh@laN4HuFs!4pRSh51Wte_D=_Csl6ojTux+ydvUS$%!=l& zOp^slRCaYiJvkMQljE0|;=NS6eEI#Hi+h3}G=nVkT*~r=w*1P!GQ=vc=dSwCr7TOD zNpPnxH?{O!y84X*t6OHtjD^=WU9V-*5waRjTCNx!y|_ZaRqsGf!NdNaZs8gGo(cWe zgN+6YQKo$Xb7qPCj8V$>kICu>R(M7Sc~RKz=^HIErVmxdul-x$!6tYAQtP~38+QNK zK%Q^TN^qZ+TgaScr(Ww8BD=q#?|#%;@p+5ZNzg7`T(7q}ulcl|=HV%(@^^K751HEk zWnocVPNwcs+i+LCQe$D($5^q^QGG{tqag>skByqmJ`0{E&Dfcy=o;?b;m#^4{5|_W zbVACeTM6#BlT4{XRC%QVbB}2%%{x;!v3TqIkxEK1|Mv;qsO^HRDFGT`T`gi7mw0X_ z&&4JGJTuRo@7KJ@rg4J&muM>UqE)1keIb{jrDAsT6ORu!DQ0)RYox8@Y<*skZs(eA zHy5P+S@*7W=8ENav&zb>YBZC|E{ea;swnHRG`qnVT3EOHh2&VU)&{+)egE~0`Dg}` zdaK_|wre_b%kSfOCpCWKW1L{Bojt$l&G>s?Wbb}Io47_|;L_(8@7gN=dtN2&Dobwq zo>kE~RGwzEA&c3XbH0orrKY9sO0B@JuoaOs218j*-`V-U7M5Dlp&(WZo$0QEII&R% zThqhRp-F`^mSe1&g4u-+FQ*PRTP+_ixM}`?PU87Lw^UqkyH(m-$#SFZ9gVAXYK^g} zRl1b=rn)Qj?XjK%9`O%Yubw{Ax~}f~LvczLr}wW_|IB@f+p)}W7H9awTLES!&<)`TlMbesE{H%TIRy1cMOO!IZ`A?(h(W0 zuJc`Y&4XvGOQZwN{6mEOZgGQQCG&#uGJD^q0$uT_ha;2wai4#=rGqG?DZ;V7ZoahM zs`Y=nEj3nZy{M!&-+xISF8?WaoIS}OyH@Vb*M^?_mQMC)XmADdlZIqHPqgYQ`hWs zhtK||bBiz8cbl5@H`MFQSVvx+TKVdqr|fM$p`c4i*%sVVvDjqmn#uX>?60JL^vgLI z{VZAUv5XSjLt8#(R^9p8;d|_BpIZXv)cAmZzI}^~$kHt5`Vy{_yzPHQ`ezu13T}t( z^vxaLG9%WDNmnP^=?vBw)jE)s_2c9^$-}pbD;c=9gV=L3n-oyi`>~T*F)V^GHRPVE; zYu8`zuz$JUgS$cR?vjU$#`7(Gjki{(bMgQCP8ZWnejeV3*^J{Y1OJk5XiJ$I@pVr2 z=b0X&YE>KQNEn`u$#{^cy=>*b?~q=zqN?I}X!-WSn!@M{Ix&r<(>LQZD=m)y`x_Kp zN~9Hw{()_BUB#CYeO79Jt9Z8Q{)|fflnOM){D3<5+&F?Ig@$h;e|F&Hx1*G1^ zByDHW%x&Vyf6rw-^XpmX)R&0CP_dJe4Qj?Z0aB6|Pbmw|N^=h#Iz5zE!SXHULYK&~ zs0>H`+Ot2ElLX~m&!1p~IF}?*D<9a71#a(cbE8B{u?uDMr-Trk%HMBhTQ-ebB=tp76l3z@-Z$HXiIp2HZy8pW3Y?<8CQnDS5 zK8z~28`BQ;g~0(KF&9oBl9!n>t+Lspq1o3|@pc*gM>luxs{|i2^o02LM|TZwpQqx0 z?N@!*f><8>wp~$g(aCUu#sr@XS%&W#?zsFwPoKtaP5lMZ9%kRh}5CvJw4ToFpgOMp%-Vt zrIAw(m(=4jNTY@Zx@-^*iILqtsrS1n*8xRZxJ^Rvep43~naP>1 zcwUgFe*Z{MovFZ-t8%t7pfocG8&C{!Q|i^CfjN zO~QRveGu>`ZCTF~sj{dZoVRPqOV#6WH7LRc@VS>txul zHkSu`T~c%YpBtmNR-W%Q)An}0o`bi!ew-< zftk_b-KUxaw#IZyy$#grQ@>QMw!82>*V-pStc5!_*QS;g@41zuA+hzE^uJ#x&4HAq zG)~J}b?A+{$(Uk`|7zxhs=nsC6NbIYX}{!rY`+_)*FH&8xqKwF*{UOsTWUIX_TAa( z-63n3Te_eB*b{s(*$e+(H+1@jGCgM?kS8XN$EdAwt0MA7S9o#@eYTV z>ls7dsm|7&QQq6^d-+J-xjCz>5e(!Nhu40+=R{U;L{`|rYf8(w@~>BE%L>u zcn_1$spXRsw{k~Pie6XsH7d1AHk#-(~rr7&E)jcDAr6e z(HXvW5HIk_$V(#3;n3_or%YQTce&PszLzI^59~cjd*<{QGkzxF-s;caP{N*AxYUk5 z6!`L*A4RuKX0K9{NmM2n2*$bXCU^zMDmMC^UGMW{mW3j1$txhx(h#U=QL8oV7ZkLD z{_*#Ph%WZe2zztlP)HQ^^`%oyElbFU{itksh5&LP)x@5(xHC*u(h zS!1(9vzq^uX6ODz`mPc7mjC?JdH*N$M*_C=+~m36|CqHnz~rUFBFfWOBJSGD=TTh5 zZ~w{VcO71|)Yd8z$)7HOmp{537tOWoO)F~WbB646XGpdzJ`efC%0JnR?y)oD{d2J& zr%c{=nh47aXg}iq$WL6>v9XshyJh^9C0)64eb!`&ILp>=_SG4S0QQD4|N9y0dD1y0 z%P9kTX6re|SGKt!f~(UZH7D{Dp)r0$%d2wr=oK^G6Vgkwc1A`f4V8;3&7N-*Ezem< ziHO?zk4Q@T;o`8^eIh{&%$&lG!ym2A=urlg&5%(BX9x=Ly0fyHCLmz4WxkW4TDMga z#sB7H?d8C`Yx-;}Fe3Poh`)H2glwth$0o1MF80^Rr?Z?}Y<4pzB~={W%tl4I zd*t;Z2jQtij6|>CB9o{y+Fhv%$B*A*h)^P0LAU9)FEo;5A)m*2^o)P<(3LYHg|^ee z(^N)f`o=9Tn!~fh+bu@@%4U|dJ%4a55nxx?&DM*n$s2IL*N-r@D#V?b)&41;e0M>F z|G`32xjNf!MYUy=UaLQ;VBOOf8dZab>@|gRcT{X;s?$}dO0><2Z*n$bz6oVZ<{z{J zW5Q}oA?eKkGb}y6di;p%7l2|C6n_#4lylKa%vBVteu+ zZ|p&BJS(G{-Uf9Qhz<~Q9OiCwo<zVWj4Mf?en4o^*)D<-sBp0?*A2+tGPzfz;NztBAXi z(mq5Qbns#tK|D=G;q$M7ozQ*|((*J6gYVZ+qC`CjVYfY3+11rmm1_e&S)u?PKl%3T z+1gzG`-{xheVz9(5~UtK5O}KtcLwsHcxDEpugQkMl4vM(G&kIC>}vw$Mij+G){Xl_ z`ln~RW~ajmxeT>n`36vmMqr$r)AkwAz4R0~fhd&6UNX93B)MkpJ6ud7Pl?MChB_fO zgh^OPB6LbJ6f!)RRj1U$w=?`7t>C6d{vJ}%r3lwkMax*``0Sm8yWMX~CK6IA$Ysx=1@v|MGp($vN!c^;2l7 z)Pkl;R6@RXo@(#19sVMZMxIJt6SY@ClKH}1c?t|+LL*0w@b;VrWD?|52HsKMKMpmq%%oJ)6x3WZ{Q91%*1-L$cR*rjI$JPsGy z_|h&{W$?sRr?53slbw@06Wi0+K>Ea$B4fyKA*qK7$074 z`$b*e$_eX>V&=QZ#OMt891dR}pSN(0^j6#)3jQG~iPO*{X@b{#8k7pjU*F5wrEcUs zx%O!>hJ}bp90v1yz+7Jei9xoi5h=lwe>Aw-VTZ{JR(JEKmk)_C;JqncUfxGMN?`Az zMPr_D$@n?KlLQA=>-zQl)cmi(vL1_jS-_Jdnhf$3iSVQ7`p;iewNE6IAaEl(54?N{ zArUNmOBnKjCQei@=z@^!Sl$*aU5mFgKt!;Ld5k0 zOw6ZuEcAOEko-}nquVw=+wQIE+KmUI9Mi($FT7#jdAB20ZCgy@3d?iJ^sYGqEKNkBpBvZ z&q^G|Ed%4VWFII9B-+M5Q>PZhSbPndx0|JJ%2}_Y{}AB-XBqejNOwe7T)#F?6r9x4=QdS2m=1)A5}m$06Pn2SDnRWMr@#y z!h76s!-fq$MQh9OoM^tvQVCc%ec;mM!dX3vnkv}NB7t0j$o(R8 zt)aNMt>0~&`Pa zmc27jCt#$ua^XmB%igJ6ld*pOMiFCnH=AIoBM3}|F?c5Oi!X`C@Kn(H2@xQSEz)Ws zTHvl>V=LS{NyvEEP6#iJ>>>d?(@<8a9y{jhG&|LG!Ux`*DXS zR@gq(crnW^-x^c$G7m;D?xwmY{T7Z>H`Wl4qGH!=V4_4^xi>pI&~aUxX4g6UqotLi zW2~xUyz;MOM^&$IvU3Ego~Sly(5o3}eq0b|-f!bX6BT<%Gpp{E)S`>-G2bI`D!9AN z&tGrw)RM=AdAEGFz}Wf6#@dPLk1sc@T(n}D+{cN$RN?N>p<$_wkv}Jjq#owxVh8*} zrzbsnv}roRQ2Cgw?5oP2uUZI_MX8RS;Tmb4-VZD|<8@{wwGYn-eW4G;WU@W<^Y+*K z`0kO*x+ROpXAVmp(@O2XaaP`AEIV+&pO%V#_Z6wrrrWYu6TS!0G(T?xR8{w8Mb*<= z=-okuVmU)MB{fF*1f(z8+S&vAcPKycv$bB{dKos{ggp;JdlI%m0a4MWVpk@!6=%;{ zi(YzRrX#rSag8Zn8$4wF19a`atB}xw->_?)!eD6p=zx*Q?(`*6cvLPGKgXP%Q|{z! zW^alrKILnK1jlYz|K?ZfaJD@cw65KT1y7%yaUR%jujy4feSgUVg>CYjTl8KVi;8Ls z?I{1FuE(sawype>;tD$eUh?yMczx0^J@6xsz-Q z;PDaNAH+~yk0AL7<1vQ}q#xW${6Y#&213W}?{g6@=obTayd__ zg&ovW=?hZodZKcqeTALJ(#8ip+;#a6k1bhd7I|iNoo@Poi)jqCbyN0@{GL0^whz^= z-77U!o=xZ4V5egmr5ai0R8=d`l*bkz`ig*=b)w`s!F*J5X8iLc-EcM$3QIMx_dpHy z<$rUlSQV!5Tu$R>i>F819Uw(B@EU_8`R&1abl9C3NJ`snY4J4F9Ut?ujLqqjBr7kNjSP-lA`uT?+?w`Z(W0p zP7X$Ua(<>gb@g(Wjbd@LtiItt3spUZ(iN9D@>}}t+aD{E*9I2m z7H6zUjW>SQpTIn1Adc+=vp#9$JvfykXvZV|t{9CeB0(}1eaE1PN`b`e=V!d_@5+MF zxy;W+udMFLV)iDGxThbE!JE>y^ z%7ODfh_77#?$peT(-Yx2Dh@wiu|;5cpZcS4FRqd_FSk)e742uGZLSNdTH2r9Ztb!A zp#CJTnh+op|IKdoIui#Lu4Utj{zyH*k7qHk^;S1lWWwKxZ%b<%eu)*@364GeKfkH{ zg=O{C-t6uJ2Mq`?sB&Ib`9DAig`%|KPhN(9q~!gZX#X$zn|EvD0?`GsTU*6lV#~}# zk*>XIG$G$@#*A6uboo5)hf;U1S8f4C^!%L+*5@BDUMu*EVz%O!6dA@kZJ(!leV(4G z7**-5P%Zzk#gw_mBI8RwVk3UH)`TPHxzkSpsglkYHFHHVI0}SZGM9&Pa{)Q@>hXDU{p(}qVz!G(IuKK!NmP7-T3pq+^lJrk z9Im{WYmSZrA|fi9NgDI!&0}>KKzkMvjS>-%y1HMq<7jB}!sr%5<0nxL-BkDgfg#4VJ26Q#V%j3cQ z`{v)L=I1_uRl?eJ>#D3$r_$!K&b&PBC|Qq!zA3{3TOBkH@2`uTRx+GhmhZRWGKs$A zI~}@oLvWaBkWlc*6QKcyswuF5n-N;Q96IShxm&Skb{8NXgd#4LCSOBOA9l$Msp(+4Fo4Hh0SxQNwA z((Hqb+}E=njmtb;ZE&w)^%@72*x@Uu-`-pNIDVX;1-?J&k78h#A6<2Gvmd2J#r>T|A61 zt1BD&cKK77lW5?h5jRwg*|SZasAdEn`A6Tox5&iAgx06~e1LcV{)yPPl2^XEqs45=CrXajiAEwoSRyzx^B!U2J8+m0ba)Cx-t@%D~{%(S3HSU{i=Omd=` z-z?+S3mNxA65$|v5Fa@)pBO|m?lva{RTquxF`tlH3JsP4+g6N<8?3oC$RUiT&w4bM;Cyx9ndHMUD*LyfY z(JpNuB7k4NZjcAU?KB<GJq~IM47V(GsEN zCgumJQV-f7gKSWC8eZMff|gkjPF`Vnpg|HJdKIXw%T0l($pXxGpJ-^ow0f_;0-^(j zsx3r1<`D7}T>Al|=5O({lWDU)X=xW+uaJ}#njOso9BT28>v4)`;h}0E2DjAI!=EHp z1V*G#u&xdy{9{;$s@JaNu`u5z;s#(AEs9N-v79uZkvA4)r^PC9Ky|4IIm;tF6wWJH zaM*;EFt|&WEem*gj`)ON4!&B}baUg&L5WxPM3%OJ-UVMh5 zi|F+r%WJ+i2)!k7GNF#Pp7)7{=871)Ac6%l7ihWvGbVI%!uAjLtJbfNujF!6JTzXm zJn_a1WRF#E-ZVjRz<{EwA5uRFoDDpDSg`0c1m8q;>a~9Khdprn}Ocrc;VZ% zH}#aTS&+FpF|J<9t_iUVN!e^V3i_b9!aTehcHqo&3Wf}Of;`-dN&!c3B-vtDU@@(7 zI8LP2uoQu~0?^NKVlslMubWdOzIp%+-Xy4#Sx!*QX-Qm#-eqlx4OEA&Y3PK9JOnR& zua|%S%?q>O7ng|O0n1zL@|Rajyr!n6=s4XT+`AXgpyyxwc#DNu#h)fvk~oT2-x7RBvyNho&+%7NR7Phc`%^rDc3ujz2+wyQT-P0tC>E znF+W|@GpP>O(l}no8Ff|CD(*T8Bk_rw;2&E7i#IS{a0iOKnX1a{XIg9YST<|olr~K zBxlT{n4MZ=B56#FQ)+9QAt0eWJ+>4FmpK|z0G_zaiDqj(ZBsM@v~Y|@ySN7HmNa>S zF7!bytcn9@?dsK0*c0J5b=(KrJp<^2W3to-&9l27qiIX`WWm8uYcsS+?|YaXV!Zn? zd5N-{h_V}t{5pTu^~H-5Z3P1Y)*Yk%dKMTH%0*!1q&BgbWGNyR)(JJ zv2(r(2bHS6i}7zhs^~m6=qS8e&nbC|J?3koI@>F97-KtB!Eh1nB_z|pt&edftu_-B z(#?9rgB6K*Lp|ubDzt0K>DBWo5wAD-F&;to(1%-gfVy-IH@9Km1e!jgW7P?WV(s;K zIoR0Z;DeHYfB;%#Mu8@ZDp_CP_J?ExEs)J9kbL z>lvb_1c+-GiA$wB{#v-u;(G*l)wx~hpIU7tUVTO+KC3BF=B`)&`~06sGBg6eoWw@r z$HLrK;5o-aQPP{#+Hl#=Ut=P)#!1MGb-Cr%zC)48kXIvrg2Gxy=kafsg zOTDYKm=9nNfM3}g(@X$sTA%axGG|~WlT}9qZ;)RKh>L3yV;{sU{RTTO7Vcs9K#)iL z9Bfere4m4f@C88?aD(Bov9#fdh=@%@!HF&~r!c$GN>3QVK8PoId3d5vo>;0C2a^zT zC=&xPiz+`p1S~2}P9@OpHQ|6+k~wVAkZN!MLqTv}VoN3L?CeZMl-UM@6j(B84qV5{ zj^@&H4lR%mp%qMPcIXcjH}tFbGsQo~nGJnj4AG#$No~7tLhV-V;-aE8>}|SOUZ$Bk zfjimyp5NRm;j~4stn4P9LHMdqMjb!r>JjgUCG79Dq1mGgG_+3nkys?rSL?YJcK?ZZTAg^R+T;s9@rD&yT6`Ephow{G3yF<5Gh?STv; zdZkV!7@RJd^T}D*YuPQ6$NHqqh-45T^NPG_v z?*hw5>|}vq$G3oa6;zS=}abR-wTg z?a5y2Hc$$=GX29FP)RH5_wQjY7)miuD=TwXMms%rrB7(3mxmy;Y~A$@34+pq!GXrLUh%n&o2BvF|p%=U!py zC}s*FDfSA7nTZ}6CTng{fL{IiaB3{^5J2*z1;HTWIn(l9&jW+sZFQtG{Q|F^rth_? z_ZQII_IIwDf&b~X?bKV!~c z=Q5eDo5sIoi$0%$F9Nnxrh8^X$Tq8@qp$CdO5#BS*<#Y!u5lZAavLIZJD3pMZ$oSb z(|}&NLzCXWcf4pKfb8t-T(W%mnC*QZauS>(&K-04H;O7Tj~+!Vag+fBIrrl-d3NHH zu32yQ!?2Tau#6L!)7-;W4)p^>K*XgA;x_Cfe;e#vKq(2NSwQ9b*mA?>%vQmu`d7m* z$*1&x(=;quFa6nQ;v7Z#N`<1%a*_2cL|lotf9^Z=`flubzu6YFMAg9ss8c@w{iyI^7eg{ztvuGfQfN7Hrm&;a zY>bKW!CvlPx^eFQxW?ArF{?K#VC&G%`7f*_dYDu=5Rh3i^bI^QRCaPm$Pj=KXGtQx z2Sg1k;K9bNUI(8N-y#nSv`P%pOx5RuLUj@CljiwsT?Q-yq26q4jCn5O35yh@3yJaZ zuNq_K?zGNW%$^%<+(=ObV(SYI+rN?0Hv9&3ISZkZ=J%4k_WgrW2OODxEsRWFh%fJh zUkVL#{3&Wy#0!#GrO3+4dh~E%GbcqZxHqszo_b$}5J~hx=Rv@RFlW?q7!05N6=zx- znn0}3;LWjibP~S|f|Ss2G7sc9onB<6tc)kR3GT|7H8#m~zd|KlB!=H^Ll0(BDv$r3&n3CK43VQfHZ zq=RVUJtR4Uf0xQG1<7u33NqJ(Py z5kkkUnfaf*Y>^fbdmCcS2)~#H-dZ%)BQ^EN$jG%^UY?%KXsg@pz&f}BF=Ru-sfqFN zrfbPB&w0N#zI=i+H~2R)qv^0S>GJeg?YVT~;Ys%T?91H>IMY%zTjuUQf)D!w0vVga znK4Egf==@vpI-h0^&@E{Ct%AiOzj3(Dj8HdUcYXR4FspS8bFjzrzvZoKLt;`+}&*% zJLFp?Rh%Xp!!62gEwDgw0WBTr`pyap4*=Lm68-=NjyML)4V>f1yRIXMwh(mtg@p|` zSYa#fZ_iDG|3a1pjUSGM#5ijbE@i})hn#N+M(Y6k5gRXJU;t|;pJ-wTf@~4Z)}Q2D z=pqr;%=8r9TaL>+JUpBSWx>ABUWb~i`~~a=-|xTf=xB*#hpY{HP@+ZNSf?ZUmrkER zE~^O;!+?$hxxFkNb9+=%46Qc_X` zq#(H=TrHK5sr$EDHN)vb42LBmC_I%@#A}mS1TI*x0Hxvv7{=~F655^;x#?h1fm9H{ z6%6ii;#q`^;!{79MQcV35YZj-DDemHyY!TVo88%{?k5ljm&1n-(>hBrhYDavNOH{V z3tgRzq4XSV3~>bZArY$6_uJezhSC9nwPe1PN&>LjbPYI1yyTHqy?fYB5dS63QynC5 z98ymPvTY^Y39VL8|Jj+FT+|U&$sd2OCMW=5J`jHwU;xdeIu6gWlWz~r77>j%9zRfs zzvPY{?NxT3^hJPY_v6#CVz^Kd%Sl=H^{UpavQesNz+Q*`-bq-s3I#cFvRGNjl@}YQ zT>;KY>S1`w?BZ71uFSf~k)_5zFu|%$9&dyt>P4!wA>1C&)zn~!hOLoU`V#5{&|DwV z%aUNNK)4bwzJ2lHh>-R(X>5Q#(Ev9Su$vI;D|!&n4>Qa!VnKwk^V6qK77PbMBSKv* z-}FjFMFl};EV@dHF@9Q~zbPVqz|KibF31Oq3}^nDz>eAfq3rfkt))|AuI) z`fT}k?`~j>0|z3hCv@eOK%nr{kSjObS-iRl;EQ|%Ada=`*AvVLaS89HP15*gjiX2J zL|d{x!%*rY`>O-IN8I%auU_z2zw3x;W`5gPrntv2y(^P=YK2K;zxdhRf&@?<5eNZ* zK79C~(DGw!ObgfrF{^~rUBhOwqeQ$$LRSyhohahE-~fXL5~HGXXfGOCH_0rQF()HdE!ddppfaf9 zoAsH(v@o~P9ea)_qpcleKhPGF+v#v(W@ZKnVrFH@&L{S0U`s`a8Z1REz;oPYK+io6 z7!8RM@@c;(Pf`it0$|MU$BJY{k^sq~P#D`Y)-zeT2<@>3qhZ4(U0+`hEL8$L8<_c| z0QakEY0)D233_7di+%a}wO~6J%-t-0jsF<_@x!~ZFS(_-+VF%1RRl>eS*G)un2^4A z4-KWk`ZzCOHoJWQn=jUziGSDLBpSb=VV7>Fump*&V8_yrC3!sg z^^h83FAZ2Ok(1G~5pH`VHN}0_W2gMQWS$P_aiqjDkBK>+)QhXDLGlSElO;Z$m+`Gt zjd*}yVxlosG%7c^*!&}on3PCK1jNL$8>mc7OpJF%UgjuR`>1zYkyDnCy|BBV4l@ia zJ5xt|=K2k1Cj&_VYvyM-9a*0mtSQGl`~7$>T)0pZv@5DD#{1CJw>{YT0Q8iqAu>ka zZp?k%qyo77*?s?TnCvXbw(E#h81hfz@aq!|M8^Vk5eGQXl0pzhpF9+DR#@KY1GpRo zM^H=nV(At;WCQ4k#$O8u(T_Cl)vM#vAD24=+av(n8`CQuL+6!Jo!=6$^sajPKga62$1a9=pN zw9IzO$;!fBMu9l0JTqx>na2d!Wv6_9L(D@E62X4%EwDd#?kP@P)FyTjkP#fpwhWVp zfZNJAHxdhgd6cYQ9x6{%I+}BRe}gfrJp8l^izm zgi2GPj+KNQ;6t!XGpM*2HuHGK26Rp_5e0ra_Dz0pN)F zca16W@8W0KRC*e43KDl4htd|u!F)O7=DHci@-bx}_7ZP!bc#(N=@wAw{DdiRq8|X5 zi3bWrGQeod!y1T3o;c53e_2tXxi1ybXg0g|x(yq2%r*6K^b5SvA7L=;YM%I|3WaCD z5t29(qy2LzB9&AWmilB&HN<{>zk8?&QR!0{zLGr(50>oSmiAks5lU29WNT`F%6|{1 zr8O&7s6?*Zfa!$R%0O~pn0OM0Cpp!C2c=>kOTq=Dey{7Z1;W;}{#JpEt!-9OQ4!jj zuUWmi@yt~5Iuu)W?2yAj^r+sqNm%mF3+VKR5Nih~@ zQ;xNse9NddUsuSs&6^J!f_&;)d_gbEERxu51NvF_@Fne9Qr~p47j6L4Kuhj0!qb?p z)h&AfXu%Aa@uZkc$cu$!`~5Fe7+6j{Ik-@@QU}{05c~r~g8q*leJ^hDRzI7>i6-!o zhrawD;N=U5xEKyfxd$G;dllX=Osqwn(G-+ zKEBrsF27Pk>}UiS!Y%8+b-i;Zk6AS^AfU=hoJ4T|*#d2acxr2E>|De5It~p_wd5?{ zj^WTuqODa7QQU6VTX&fFB%w4xfF@$^kKmtFq)*b)22KNQBV`*U9n>+AW8k(=@Au8r79pMt)m!$|z){K(0~nyKrVB>YTEDY`-&_i4{QgZ(I!Zjo@Nop*>qGh44zkdvIT*UF`|3V$jB5s$dn7bBUwl6H! zq%OwB26jk-_`%c^;v0`E$(FDO-Cz<1eKA2nLHr97m?$o7dzx=73g+kL=5}>+BXvt+ znFQ}e%xr;g`}KSQQ&*!~0&)d4jOxJ*zrle`yLX?0>3tpW4FlGDII@u2TOw4(F@*@1 zAm2!4^m|aB;Kx3P^#o_Db1}<@2(tjkvw)yH^}x@cKh>e?MX3E8U2(_Qo5$Te=Fc?I+QNLP`CTHFGHe@X)rw|r* zTFE3BT{2`ei3i(3SRNlott|eT+$yq6M0a3qEn#J)p_XWp*{ZIq3qgV=-`>5soh{1{ zoFkftK41&%?%KsZUq&64_40Ik7+@rvCfP{0usSu~IrRK}e>HYGEk#9lggnTN5o+tu z>7AD{f{#Ob{d}kdygA9{uq#%g!zqP&1(kIr=85#O}tkT%9xUkYwbTVa; zPNp@o)R5LKC?;as)e{$gQX~N>1w58!Fct`2fPE3phSNm#v1Q8^QT(feGdH~F2)i9| zO_|*Q)-@q)_z>SnLKz{Jw>Wu8n2gKQc*iZq!*djj8h_dNL6GZE)1M5Vo#4iviVhh% z*lX30MY=8HO#Jf281s@2MGIO6`6Bg3rwR5iUDnoJZ~KkUpSJ{@k}CTS6HClt#0)rB zH8KVqbu^UVM_?N(04590ZVBg^8?Kfc7;Zci%F_ArM-Qv-+qjJS<0TtPTbla%`o)HG znxglfNRA>Ga^FxPpc=v@1VW-{T|)c~J6pupvw-8{e&fas(74k`2N$F?{h075Yos&B z&x{5FXa=0UteD&DA^7S3vx0IGZ-}B;mDIL zSWM}T7ZN6=f`B!VnlEXHR|(y%v?xelsj?8)gvG@%2bNbk-+xgLvR5VBB63ep&o&@$2f zubGfn2R@$>We;KOjwBouf;h6Bz7|3A9!QcxCFQ6d=Zk zYEn-HxVd(8I0dB`Qus*fDldvjFf`np7cc87j-z zp^_W-L!svK)m_r$k{V&^;)x$78xw#eg-vsV36i2VQUsLuP#Vx1G7=A=XIbr{P|n0! zrHH7llfF`>I2XvUx<1aJ*!+#ZNMA7>vHiFD66;mBmQokGvZ|9uN}6otzklLckF+|R zk!J<1v$Tu+CsDt|Hnyz&E?@75Q}Gc*78ma_kJPa!?>)p9))l4Sg?w-S7Qd7z`XS!$ zALmJ{*?t}pb*d!aWVUGUXjEM@C3uI^DBShdMp_A}uT{}U!?xRhxx{{%^jtMxmweLR zq=Hcl^IV9bDb?}BP~NYLm|87#>noH(bO$*=DHgOT|JwKYen$#RWCy>Qkh=h z4ai3NY#j;&De-JL>k}@2p3_sZzwnsmYjAGcObG^USLf{0rBoEzzTz0jM%jb^uQXK5 zVK`};`S@`r#pVQN4)N-LZJd~M>8K1L8%rBd4V@p@rU;!XIk((;S%f+N(4pdzuE@m4 z8NZfcIPLCa*x4FMt8%?yXJN)Z0rd7YF6HCJJofc(o-Vj3kYK|%I(&1RpaIciMnr0~ zgl{oeYKmr-(|ppaFHuWnt{=KxZ>L6IQLm;uVaWg7}C=HQJf)!INCQw{bBGaWNOETc6%A52JG|(HPiu zf@%Kql=#FmIf>qhqMqd4qFMBX`HkW8MU`lb10pLnV$N)^66XlNOz*8=KBBR8f0D() zx(Lb#c@42^HY{fr8_(A!gdFAs^TH;L6 zk2xy^74DHZN=>;3b@9jnWMiy*Oz4rZ74tn7QgSo;+2v_e1g{hd>&=-p5!WNSey6$| z(gy5HMFlC>ju@~@h&~{{Aj&+c<`R3`2_S<-#qdj36h~KyiLDy1oA*KU@1gDFS3ErM z851AQ!yfubD|6*SGQcRu7DOH*X9?I{s(Re`-cDk literal 119959 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

K(|2dG%nHV3{BCc>oV$7AVSeY|#;xJhu(2 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 From 79f5ec0bf85a2d5945a75b278d29a0c7b79bbaec Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 20 Jan 2026 19:17:50 +0300 Subject: [PATCH 14/20] feat: Implement database storage and pass all tests --- pom.xml | 62 ++------ .../filmorate/controller/FilmController.java | 35 ++--- .../filmorate/controller/GenreController.java | 29 ++++ .../filmorate/controller/MpaController.java | 29 ++++ .../filmorate/controller/UserController.java | 31 ++-- .../practicum/filmorate/model/Film.java | 7 +- .../practicum/filmorate/model/Genre.java | 16 ++ .../practicum/filmorate/model/MpaRating.java | 16 ++ .../practicum/filmorate/model/User.java | 6 - .../filmorate/service/FilmService.java | 73 ++++------ .../filmorate/service/GenreService.java | 25 ++++ .../filmorate/service/MpaService.java | 25 ++++ .../filmorate/service/UserService.java | 69 +++------ .../filmorate/storage/FilmStorage.java | 11 +- .../filmorate/storage/GenreStorage.java | 10 ++ .../storage/InMemoryFilmStorage.java | 58 -------- .../storage/InMemoryUserStorage.java | 58 -------- .../filmorate/storage/MpaStorage.java | 10 ++ .../filmorate/storage/UserStorage.java | 13 +- .../filmorate/storage/dao/FilmDbStorage.java | 136 +++++++++++++++++ .../filmorate/storage/dao/GenreDbStorage.java | 41 ++++++ .../filmorate/storage/dao/MpaDbStorage.java | 41 ++++++ .../filmorate/storage/dao/UserDbStorage.java | 120 +++++++++++++++ src/main/resources/application.properties | 11 ++ src/main/resources/data.sql | 14 ++ src/main/resources/schema.sql | 51 +++++++ .../filmorate/FilmControllerTest.java | 122 ---------------- .../filmorate/FilmorateApplicationTests.java | 13 -- .../filmorate/UserControllerTest.java | 122 ---------------- .../storage/dao/FilmDbStorageTest.java | 137 ++++++++++++++++++ .../storage/dao/GenreDbStorageTest.java | 40 +++++ .../storage/dao/MpaDbStorageTest.java | 44 ++++++ .../storage/dao/UserDbStorageTest.java | 121 ++++++++++++++++ 33 files changed, 1027 insertions(+), 569 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/MpaController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/Genre.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/MpaRating.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java create mode 100644 src/main/resources/data.sql create mode 100644 src/main/resources/schema.sql delete mode 100644 src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java delete mode 100644 src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java delete mode 100644 src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorageTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorageTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorageTest.java diff --git a/pom.xml b/pom.xml index cca16ab..c21376e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,86 +1,54 @@ - + 4.0.0 - org.springframework.boot spring-boot-starter-parent - 3.2.0 + 3.2.5 - ru.yandex.practicum filmorate - 1.0.0 - + 0.0.1-SNAPSHOT - 17 - 3.9.0 + 21 - - org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-validation - - - - org.zalando - logbook-spring-boot-starter - ${logbook.version} - - - org.projectlombok lombok - provided + true - - org.springframework.boot spring-boot-starter-test test + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-jdbc + - org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.projectlombok - lombok - ${lombok.version} - - - - - - - - central - https://repo.maven.apache.org/maven2 - - \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index e138bc5..6cc0c9e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,45 +1,36 @@ package ru.yandex.practicum.filmorate.controller; - import jakarta.validation.Valid; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.service.FilmService; - import java.util.List; - @RestController @RequestMapping("/films") -@Slf4j +@RequiredArgsConstructor public class FilmController { private final FilmService filmService; - @Autowired - public FilmController(FilmService filmService) { - this.filmService = filmService; + @PostMapping + public Film create(@Valid @RequestBody Film film) { + return filmService.create(film); + } + + @PutMapping + public Film update(@Valid @RequestBody Film film) { + return filmService.update(film); } @GetMapping - public List getAllFilms() { + public List getAll() { return filmService.getAll(); } @GetMapping("/{id}") - public Film getFilmById(@PathVariable int id) { + public Film getById(@PathVariable int id) { return filmService.getById(id); } - @PostMapping - public Film createFilm(@Valid @RequestBody Film film) { - return filmService.create(film); - } - - @PutMapping - public Film updateFilm(@Valid @RequestBody Film film) { - return filmService.update(film); - } - @PutMapping("/{id}/like/{userId}") public void addLike(@PathVariable int id, @PathVariable int userId) { filmService.addLike(id, userId); @@ -51,7 +42,7 @@ public void removeLike(@PathVariable int id, @PathVariable int userId) { } @GetMapping("/popular") - public List getPopularFilms(@RequestParam(defaultValue = "10") int count) { + public List getPopularFilms(@RequestParam(defaultValue = "10", required = false) int count) { return filmService.getPopularFilms(count); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java new file mode 100644 index 0000000..5a75f88 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java @@ -0,0 +1,29 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.service.GenreService; + +import java.util.List; + +@RestController +@RequestMapping("/genres") +@RequiredArgsConstructor +public class GenreController { + + private final GenreService genreService; + + @GetMapping + public List getAll() { + return genreService.getAll(); + } + + @GetMapping("/{id}") + public Genre getById(@PathVariable int id) { + return genreService.getById(id); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/MpaController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/MpaController.java new file mode 100644 index 0000000..0824690 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/MpaController.java @@ -0,0 +1,29 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.yandex.practicum.filmorate.model.MpaRating; +import ru.yandex.practicum.filmorate.service.MpaService; + +import java.util.List; + +@RestController +@RequestMapping("/mpa") +@RequiredArgsConstructor +public class MpaController { + + private final MpaService mpaService; + + @GetMapping + public List getAll() { + return mpaService.getAll(); + } + + @GetMapping("/{id}") + public MpaRating getById(@PathVariable int id) { + return mpaService.getById(id); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 961e226..09a2a18 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,8 +1,7 @@ package ru.yandex.practicum.filmorate.controller; import jakarta.validation.Valid; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.service.UserService; @@ -11,35 +10,31 @@ @RestController @RequestMapping("/users") -@Slf4j +@RequiredArgsConstructor public class UserController { + private final UserService userService; - @Autowired - public UserController(UserService userService) { - this.userService = userService; + @PostMapping + public User create(@Valid @RequestBody User user) { + return userService.create(user); + } + + @PutMapping + public User update(@Valid @RequestBody User user) { + return userService.update(user); } @GetMapping - public List getAllUsers() { + public List getAll() { return userService.getAll(); } @GetMapping("/{id}") - public User getUserById(@PathVariable int id) { + public User getById(@PathVariable int id) { return userService.getById(id); } - @PostMapping - public User createUser(@Valid @RequestBody User user) { - return userService.create(user); - } - - @PutMapping - public User updateUser(@Valid @RequestBody User user) { - return userService.update(user); - } - @PutMapping("/{id}/friends/{friendId}") public void addFriend(@PathVariable int id, @PathVariable int friendId) { userService.addFriend(id, friendId); diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index ecb293e..dae0ab0 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -6,10 +6,9 @@ import lombok.AccessLevel; import lombok.Data; import lombok.experimental.FieldDefaults; -import com.fasterxml.jackson.annotation.JsonIgnore; import java.time.LocalDate; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; @Data @@ -28,6 +27,6 @@ public class Film { @Positive(message = "Продолжительность фильма должна быть положительной.") int duration; - @JsonIgnore - Set likes = new HashSet<>(); + MpaRating mpa; + Set genres = new LinkedHashSet<>(); // Используем LinkedHashSet для сохранения порядка } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Genre.java b/src/main/java/ru/yandex/practicum/filmorate/model/Genre.java new file mode 100644 index 0000000..0f6a5f1 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Genre.java @@ -0,0 +1,16 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE) +public class Genre { + int id; + String name; +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/MpaRating.java b/src/main/java/ru/yandex/practicum/filmorate/model/MpaRating.java new file mode 100644 index 0000000..6b60b91 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/MpaRating.java @@ -0,0 +1,16 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE) +public class MpaRating { + int id; + String name; +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index f360e27..df67aae 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -7,11 +7,8 @@ import lombok.AccessLevel; import lombok.Data; import lombok.experimental.FieldDefaults; -import com.fasterxml.jackson.annotation.JsonIgnore; import java.time.LocalDate; -import java.util.HashSet; -import java.util.Set; @Data @FieldDefaults(level = AccessLevel.PRIVATE) @@ -30,7 +27,4 @@ public class User { @PastOrPresent(message = "Дата рождения не может быть в будущем.") LocalDate birthday; - - @JsonIgnore - Set friends = new HashSet<>(); } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java index c10bd71..a127ef6 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -1,32 +1,28 @@ package ru.yandex.practicum.filmorate.service; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genre; import ru.yandex.practicum.filmorate.storage.FilmStorage; +import ru.yandex.practicum.filmorate.storage.GenreStorage; +import ru.yandex.practicum.filmorate.storage.MpaStorage; import ru.yandex.practicum.filmorate.storage.UserStorage; import java.time.LocalDate; -import java.util.Comparator; import java.util.List; -import java.util.stream.Collectors; @Service -@Slf4j +@RequiredArgsConstructor public class FilmService { - private static final LocalDate EARLIEST_RELEASE_DATE = LocalDate.of(1895, 12, 28); + private static final LocalDate EARLIEST_RELEASE_DATE = LocalDate.of(1895, 12, 28); private final FilmStorage filmStorage; private final UserStorage userStorage; - - @Autowired - public FilmService(FilmStorage filmStorage, UserStorage userStorage) { - this.filmStorage = filmStorage; - this.userStorage = userStorage; - } + private final GenreStorage genreStorage; + private final MpaStorage mpaStorage; public Film create(Film film) { validateFilm(film); @@ -34,12 +30,14 @@ public Film create(Film film) { } public Film update(Film film) { + getById(film.getId()); // Проверяем, что фильм существует validateFilm(film); return filmStorage.update(film); } public Film getById(int id) { - return filmStorage.getById(id); + return filmStorage.getById(id) + .orElseThrow(() -> new NotFoundException("Фильм с id=" + id + " не найден.")); } public List getAll() { @@ -47,47 +45,36 @@ public List getAll() { } public void addLike(int filmId, int userId) { - Film film = filmStorage.getById(filmId); - userStorage.getById(userId); // Проверяем существование пользователя - - film.getLikes().add(userId); - filmStorage.update(film); - - log.info("Пользователь с id={} поставил лайк фильму с id={}", userId, filmId); + getById(filmId); + userStorage.getById(userId) + .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден.")); + filmStorage.addLike(filmId, userId); } public void removeLike(int filmId, int userId) { - Film film = filmStorage.getById(filmId); - - if (!film.getLikes().contains(userId)) { - throw new NotFoundException("Лайк от пользователя с id=" + userId + " не найден."); - } - - film.getLikes().remove(userId); - filmStorage.update(film); - - log.info("Пользователь с id={} удалил лайк фильму с id={}", userId, filmId); + getById(filmId); + userStorage.getById(userId) + .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден.")); + filmStorage.removeLike(filmId, userId); } public List getPopularFilms(int count) { - return filmStorage.getAll().stream() - .sorted(Comparator.comparingInt((Film f) -> f.getLikes().size()).reversed()) - .limit(count) - .collect(Collectors.toList()); + return filmStorage.getPopularFilms(count); } private void validateFilm(Film film) { - if (film.getName() == null || film.getName().isBlank()) { - throw new ValidationException("Название фильма не может быть пустым."); - } - if (film.getDescription() != null && film.getDescription().length() > 200) { - throw new ValidationException("Описание не должно превышать 200 символов."); - } - if (film.getReleaseDate() == null || film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) { + if (film.getReleaseDate() != null && film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) { throw new ValidationException("Дата релиза не может быть раньше 28 декабря 1895 года."); } - if (film.getDuration() <= 0) { - throw new ValidationException("Продолжительность фильма должна быть положительной."); + if (film.getMpa() != null) { + mpaStorage.getById(film.getMpa().getId()) + .orElseThrow(() -> new NotFoundException("Рейтинг MPA с id=" + film.getMpa().getId() + " не найден.")); + } + if (film.getGenres() != null) { + for (Genre genre : film.getGenres()) { + genreStorage.getById(genre.getId()) + .orElseThrow(() -> new NotFoundException("Жанр с id=" + genre.getId() + " не найден.")); + } } } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java b/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java new file mode 100644 index 0000000..7b145e7 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java @@ -0,0 +1,25 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.storage.GenreStorage; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class GenreService { + + private final GenreStorage genreStorage; + + public List getAll() { + return genreStorage.getAll(); + } + + public Genre getById(int id) { + return genreStorage.getById(id) + .orElseThrow(() -> new NotFoundException("Жанр с id=" + id + " не найден.")); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java b/src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java new file mode 100644 index 0000000..0f72001 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java @@ -0,0 +1,25 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.model.MpaRating; +import ru.yandex.practicum.filmorate.storage.MpaStorage; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class MpaService { + + private final MpaStorage mpaStorage; + + public List getAll() { + return mpaStorage.getAll(); + } + + public MpaRating getById(int id) { + return mpaStorage.getById(id) + .orElseThrow(() -> new NotFoundException("Рейтинг MPA с id=" + id + " не найден.")); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java index 42f81ec..c2f3832 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -1,25 +1,18 @@ package ru.yandex.practicum.filmorate.service; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.UserStorage; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; @Service -@Slf4j +@RequiredArgsConstructor public class UserService { - private final UserStorage userStorage; - @Autowired - public UserService(UserStorage userStorage) { - this.userStorage = userStorage; - } + private final UserStorage userStorage; public User create(User user) { if (user.getName() == null || user.getName().isBlank()) { @@ -29,6 +22,7 @@ public User create(User user) { } public User update(User user) { + getById(user.getId()); if (user.getName() == null || user.getName().isBlank()) { user.setName(user.getLogin()); } @@ -36,7 +30,8 @@ public User update(User user) { } public User getById(int id) { - return userStorage.getById(id); + return userStorage.getById(id) + .orElseThrow(() -> new NotFoundException("Пользователь с id=" + id + " не найден.")); } public List getAll() { @@ -44,54 +39,24 @@ public List getAll() { } public void addFriend(int userId, int friendId) { - User user = userStorage.getById(userId); - User friend = userStorage.getById(friendId); - - user.getFriends().add(friendId); - friend.getFriends().add(userId); - - userStorage.update(user); - userStorage.update(friend); - - log.info("Пользователь с id={} добавил в друзья пользователя с id={}", userId, friendId); + getById(userId); + getById(friendId); + userStorage.addFriend(userId, friendId); } public void removeFriend(int userId, int friendId) { - User user = userStorage.getById(userId); - User friend = userStorage.getById(friendId); - - user.getFriends().remove(friendId); - friend.getFriends().remove(userId); - - userStorage.update(user); - userStorage.update(friend); - - log.info("Пользователь с id={} удалил из друзей пользователя с id={}", userId, friendId); + // Добавляем проверку, чтобы вернуть 404, если пользователь не найден + getById(userId); + getById(friendId); + userStorage.removeFriend(userId, friendId); } public List getFriends(int userId) { - User user = userStorage.getById(userId); - List friends = new ArrayList<>(); - - for (Integer friendId : user.getFriends()) { - friends.add(userStorage.getById(friendId)); - } - - return friends; + getById(userId); + return userStorage.getFriends(userId); } public List getCommonFriends(int userId, int otherId) { - User user = userStorage.getById(userId); - User other = userStorage.getById(otherId); - - Set commonFriendIds = new HashSet<>(user.getFriends()); - commonFriendIds.retainAll(other.getFriends()); - - List commonFriends = new ArrayList<>(); - for (Integer friendId : commonFriendIds) { - commonFriends.add(userStorage.getById(friendId)); - } - - return commonFriends; + return userStorage.getCommonFriends(userId, otherId); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java index 8c4f56d..8830cbf 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -2,16 +2,23 @@ import ru.yandex.practicum.filmorate.model.Film; import java.util.List; +import java.util.Optional; public interface FilmStorage { - Film create(Film film); Film update(Film film); - Film getById(int id); + Optional getById(int id); List getAll(); void delete(int id); + + // НОВЫЕ МЕТОДЫ ДЛЯ ЛАЙКОВ + void addLike(int filmId, int userId); + + void removeLike(int filmId, int userId); + + List getPopularFilms(int count); } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java new file mode 100644 index 0000000..9720260 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java @@ -0,0 +1,10 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.Genre; +import java.util.List; +import java.util.Optional; + +public interface GenreStorage { + List getAll(); + Optional getById(int id); +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java deleted file mode 100644 index 61c6774..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ /dev/null @@ -1,58 +0,0 @@ -package ru.yandex.practicum.filmorate.storage; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.model.Film; -import ru.yandex.practicum.filmorate.storage.FilmStorage; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Component -@Slf4j -public class InMemoryFilmStorage implements FilmStorage { - private final Map films = new HashMap<>(); - private int nextId = 1; - - @Override - public Film create(Film film) { - film.setId(nextId++); - films.put(film.getId(), film); - log.info("Фильм '{}' с id={} успешно создан.", film.getName(), film.getId()); - return film; - } - - @Override - public Film update(Film film) { - if (!films.containsKey(film.getId())) { - throw new NotFoundException("Фильм с id=" + film.getId() + " не найден."); - } - films.put(film.getId(), film); - log.info("Фильм '{}' с id={} успешно обновлен.", film.getName(), film.getId()); - return film; - } - - @Override - public Film getById(int id) { - Film film = films.get(id); - if (film == null) { - throw new NotFoundException("Фильм с id=" + id + " не найден."); - } - return film; - } - - @Override - public List getAll() { - return new ArrayList<>(films.values()); - } - - @Override - public void delete(int id) { - if (!films.containsKey(id)) { - throw new NotFoundException("Фильм с id=" + id + " не найден."); - } - films.remove(id); - } -} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java deleted file mode 100644 index 403d2c8..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ /dev/null @@ -1,58 +0,0 @@ -package ru.yandex.practicum.filmorate.storage.user; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.model.User; -import ru.yandex.practicum.filmorate.storage.UserStorage; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Component -@Slf4j -public class InMemoryUserStorage implements UserStorage { - private final Map users = new HashMap<>(); - private int nextId = 1; - - @Override - public User create(User user) { - user.setId(nextId++); - users.put(user.getId(), user); - log.info("Пользователь '{}' с id={} успешно создан.", user.getLogin(), user.getId()); - return user; - } - - @Override - public User update(User user) { - if (!users.containsKey(user.getId())) { - throw new NotFoundException("Пользователь с id=" + user.getId() + " не найден."); - } - users.put(user.getId(), user); - log.info("Пользователь '{}' с id={} успешно обновлен.", user.getLogin(), user.getId()); - return user; - } - - @Override - public User getById(int id) { - User user = users.get(id); - if (user == null) { - throw new NotFoundException("Пользователь с id=" + id + " не найден."); - } - return user; - } - - @Override - public List getAll() { - return new ArrayList<>(users.values()); - } - - @Override - public void delete(int id) { - if (!users.containsKey(id)) { - throw new NotFoundException("Пользователь с id=" + id + " не найден."); - } - users.remove(id); - } -} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java new file mode 100644 index 0000000..adb8e63 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java @@ -0,0 +1,10 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.MpaRating; +import java.util.List; +import java.util.Optional; + +public interface MpaStorage { + List getAll(); + Optional getById(int id); +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java index b34fd80..5db9853 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -2,16 +2,25 @@ import ru.yandex.practicum.filmorate.model.User; import java.util.List; +import java.util.Optional; public interface UserStorage { - User create(User user); User update(User user); - User getById(int id); + Optional getById(int id); List getAll(); void delete(int id); + + + void addFriend(int userId, int friendId); + + void removeFriend(int userId, int friendId); + + List getFriends(int userId); + + List getCommonFriends(int userId, int otherId); } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java new file mode 100644 index 0000000..532710f --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java @@ -0,0 +1,136 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.model.MpaRating; +import ru.yandex.practicum.filmorate.storage.FilmStorage; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +@Repository +@Primary +@RequiredArgsConstructor +public class FilmDbStorage implements FilmStorage { + + private final JdbcTemplate jdbcTemplate; + + @Override + public Film create(Film film) { + String sql = "INSERT INTO films (name, description, release_date, duration, mpa_rating_id) VALUES (?, ?, ?, ?, ?)"; + KeyHolder keyHolder = new GeneratedKeyHolder(); + + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"}); + ps.setString(1, film.getName()); + ps.setString(2, film.getDescription()); + ps.setDate(3, Date.valueOf(film.getReleaseDate())); + ps.setInt(4, film.getDuration()); + ps.setInt(5, film.getMpa().getId()); + return ps; + }, keyHolder); + + film.setId(Objects.requireNonNull(keyHolder.getKey()).intValue()); + updateFilmGenres(film); + return getById(film.getId()).orElse(null); + } + + @Override + public Film update(Film film) { + String sql = "UPDATE films SET name = ?, description = ?, release_date = ?, duration = ?, mpa_rating_id = ? WHERE id = ?"; + jdbcTemplate.update(sql, + film.getName(), + film.getDescription(), + film.getReleaseDate(), + film.getDuration(), + film.getMpa().getId(), + film.getId()); + updateFilmGenres(film); + return getById(film.getId()).orElse(null); + } + + @Override + public Optional getById(int id) { + String sql = "SELECT f.*, m.name AS mpa_name " + + "FROM films AS f " + + "JOIN mpa_ratings AS m ON f.mpa_rating_id = m.id " + + "WHERE f.id = ?"; + List films = jdbcTemplate.query(sql, this::mapRowToFilm, id); + return films.stream().findFirst(); + } + + @Override + public List getAll() { + String sql = "SELECT f.*, m.name AS mpa_name " + + "FROM films AS f " + + "JOIN mpa_ratings AS m ON f.mpa_rating_id = m.id"; + return jdbcTemplate.query(sql, this::mapRowToFilm); + } + + @Override + public void delete(int id) { + String sql = "DELETE FROM films WHERE id = ?"; + jdbcTemplate.update(sql, id); + } + + @Override + public void addLike(int filmId, int userId) { + String sql = "INSERT INTO film_likes (film_id, user_id) VALUES (?, ?)"; + jdbcTemplate.update(sql, filmId, userId); + } + + @Override + public void removeLike(int filmId, int userId) { + String sql = "DELETE FROM film_likes WHERE film_id = ? AND user_id = ?"; + jdbcTemplate.update(sql, filmId, userId); + } + + @Override + public List getPopularFilms(int count) { + String sql = "SELECT f.*, m.name AS mpa_name " + + "FROM films AS f " + + "JOIN mpa_ratings AS m ON f.mpa_rating_id = m.id " + + "LEFT JOIN film_likes AS fl ON f.id = fl.film_id " + + "GROUP BY f.id, m.name " + + "ORDER BY COUNT(fl.user_id) DESC " + + "LIMIT ?"; + return jdbcTemplate.query(sql, this::mapRowToFilm, count); + } + + private void updateFilmGenres(Film film) { + jdbcTemplate.update("DELETE FROM film_genres WHERE film_id = ?", film.getId()); + if (film.getGenres() != null && !film.getGenres().isEmpty()) { + Set uniqueGenres = new HashSet<>(film.getGenres()); + String sql = "INSERT INTO film_genres (film_id, genre_id) VALUES (?, ?)"; + for (Genre genre : uniqueGenres) { + jdbcTemplate.update(sql, film.getId(), genre.getId()); + } + } + } + + private Film mapRowToFilm(ResultSet rs, int rowNum) throws SQLException { + Film film = new Film(); + film.setId(rs.getInt("id")); + film.setName(rs.getString("name")); + film.setDescription(rs.getString("description")); + film.setReleaseDate(rs.getDate("release_date").toLocalDate()); + film.setDuration(rs.getInt("duration")); + film.setMpa(new MpaRating(rs.getInt("mpa_rating_id"), rs.getString("mpa_name"))); + + String genresSql = "SELECT g.id, g.name FROM genres AS g JOIN film_genres AS fg ON g.id = fg.genre_id WHERE fg.film_id = ?"; + List genres = jdbcTemplate.query(genresSql, (g_rs, g_rowNum) -> + new Genre(g_rs.getInt("id"), g_rs.getString("name")), film.getId()); + film.setGenres(new LinkedHashSet<>(genres)); + + return film; + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java new file mode 100644 index 0000000..177d94f --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java @@ -0,0 +1,41 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.storage.GenreStorage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.Optional; + +@Repository +@Primary // Делаем эту реализацию основной для интерфейса GenreStorage +@RequiredArgsConstructor +public class GenreDbStorage implements GenreStorage { + + private final JdbcTemplate jdbcTemplate; + + @Override + public List getAll() { + String sql = "SELECT * FROM genres ORDER BY id"; + return jdbcTemplate.query(sql, this::mapRowToGenre); + } + + @Override + public Optional getById(int id) { + String sql = "SELECT * FROM genres WHERE id = ?"; + List genres = jdbcTemplate.query(sql, this::mapRowToGenre, id); + return genres.stream().findFirst(); + } + + private Genre mapRowToGenre(ResultSet rs, int rowNum) throws SQLException { + return new Genre( + rs.getInt("id"), + rs.getString("name") + ); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java new file mode 100644 index 0000000..e3a334c --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java @@ -0,0 +1,41 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.MpaRating; +import ru.yandex.practicum.filmorate.storage.MpaStorage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.Optional; + +@Repository +@Primary // Делаем эту реализацию основной для интерфейса MpaStorage +@RequiredArgsConstructor +public class MpaDbStorage implements MpaStorage { + + private final JdbcTemplate jdbcTemplate; + + @Override + public List getAll() { + String sql = "SELECT * FROM mpa_ratings ORDER BY id"; + return jdbcTemplate.query(sql, this::mapRowToMpaRating); + } + + @Override + public Optional getById(int id) { + String sql = "SELECT * FROM mpa_ratings WHERE id = ?"; + List ratings = jdbcTemplate.query(sql, this::mapRowToMpaRating, id); + return ratings.stream().findFirst(); + } + + private MpaRating mapRowToMpaRating(ResultSet rs, int rowNum) throws SQLException { + return new MpaRating( + rs.getInt("id"), + rs.getString("name") + ); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java new file mode 100644 index 0000000..97219cf --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java @@ -0,0 +1,120 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +@Repository +@Primary +@RequiredArgsConstructor +public class UserDbStorage implements UserStorage { + + private final JdbcTemplate jdbcTemplate; + + @Override + public User create(User user) { + String sql = "INSERT INTO users (email, login, name, birthday) VALUES (?, ?, ?, ?)"; + KeyHolder keyHolder = new GeneratedKeyHolder(); + + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"}); + ps.setString(1, user.getEmail()); + ps.setString(2, user.getLogin()); + ps.setString(3, user.getName()); + ps.setDate(4, Date.valueOf(user.getBirthday())); + return ps; + }, keyHolder); + + user.setId(Objects.requireNonNull(keyHolder.getKey()).intValue()); + return user; + } + + @Override + public User update(User user) { + String sql = "UPDATE users SET email = ?, login = ?, name = ?, birthday = ? WHERE id = ?"; + jdbcTemplate.update(sql, + user.getEmail(), + user.getLogin(), + user.getName(), + user.getBirthday(), + user.getId()); + return getById(user.getId()).orElse(null); + } + + @Override + public void delete(int id) { + String sql = "DELETE FROM users WHERE id = ?"; + jdbcTemplate.update(sql, id); + } + + @Override + public Optional getById(int id) { + String sql = "SELECT * FROM users WHERE id = ?"; + List users = jdbcTemplate.query(sql, this::mapRowToUser, id); + return users.stream().findFirst(); + } + + @Override + public List getAll() { + String sql = "SELECT * FROM users ORDER BY id"; + return jdbcTemplate.query(sql, this::mapRowToUser); + } + + @Override + public void addFriend(int userId, int friendId) { + // Добавляем запись о дружбе. Статус true означает, что заявка подтверждена (для односторонней дружбы) + String sql = "INSERT INTO friendships (user_id, friend_id, status) VALUES (?, ?, ?)"; + jdbcTemplate.update(sql, userId, friendId, true); + } + + @Override + public void removeFriend(int userId, int friendId) { + String sql = "DELETE FROM friendships WHERE user_id = ? AND friend_id = ?"; + jdbcTemplate.update(sql, userId, friendId); + } + + @Override + public List getFriends(int userId) { + // Выбираем пользователей, которые являются друзьями для userId + String sql = "SELECT u.* FROM users u " + + "JOIN friendships f ON u.id = f.friend_id " + + "WHERE f.user_id = ?"; + return jdbcTemplate.query(sql, this::mapRowToUser, userId); + } + + @Override + public List getCommonFriends(int userId, int otherId) { + // Находим пересечение списков друзей с помощью INTERSECT + String sql = "SELECT u.* " + + "FROM users u " + + "WHERE u.id IN (" + + " SELECT friend_id FROM friendships WHERE user_id = ? " + + " INTERSECT " + + " SELECT friend_id FROM friendships WHERE user_id = ?" + + ")"; + return jdbcTemplate.query(sql, this::mapRowToUser, userId, otherId); + } + + private User mapRowToUser(ResultSet rs, int rowNum) throws SQLException { + User user = new User(); + user.setId(rs.getInt("id")); + user.setEmail(rs.getString("email")); + user.setLogin(rs.getString("login")); + user.setName(rs.getString("name")); + user.setBirthday(rs.getDate("birthday").toLocalDate()); + return user; + } +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 636895c..3922898 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,13 @@ # Logbook configuration logging.level.org.zalando.logbook=TRACE +# ???????? ????????????? ?? ??? ?????? ?????????? +spring.sql.init.mode=always + +# ????????? ??? ??????????? ? H2 ? ???????? ?????? +spring.datasource.url=jdbc:h2:file:./db/filmorate +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password + +# ???????? ???-??????? H2 ??? ??????? (?????????????, ?? ????? ??????) +spring.h2.console.enabled=true \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..a5fd197 --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,14 @@ +-- Заполняем справочник MPA-рейтингов. Используем MERGE для идемпотентности. +MERGE INTO mpa_ratings (id, name) VALUES (1, 'G'); +MERGE INTO mpa_ratings (id, name) VALUES (2, 'PG'); +MERGE INTO mpa_ratings (id, name) VALUES (3, 'PG-13'); +MERGE INTO mpa_ratings (id, name) VALUES (4, 'R'); +MERGE INTO mpa_ratings (id, name) VALUES (5, 'NC-17'); + +-- Заполняем справочник жанров. +MERGE INTO genres (id, name) VALUES (1, 'Комедия'); +MERGE INTO genres (id, name) VALUES (2, 'Драма'); +MERGE INTO genres (id, name) VALUES (3, 'Мультфильм'); +MERGE INTO genres (id, name) VALUES (4, 'Триллер'); +MERGE INTO genres (id, name) VALUES (5, 'Документальный'); +MERGE INTO genres (id, name) VALUES (6, 'Боевик'); \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000..e776aad --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,51 @@ +-- Удаляем таблицы в правильном порядке, если они существуют +DROP TABLE IF EXISTS film_like, film_genre, friendship, film, users, mpa_rating, genre CASCADE; + +-- Справочники +CREATE TABLE IF NOT EXISTS mpa_rating ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR(10) NOT NULL UNIQUE +); + +CREATE TABLE IF NOT EXISTS genre ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR(50) NOT NULL UNIQUE +); + +-- Основные сущности +CREATE TABLE IF NOT EXISTS film ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description VARCHAR(200), + release_date DATE, + duration INT, + mpa_rating_id INT REFERENCES mpa_rating(id) ON DELETE RESTRICT +); + +CREATE TABLE IF NOT EXISTS users ( -- Название во множественном числе, чтобы избежать конфликта с SQL + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE, + login VARCHAR(255) NOT NULL UNIQUE, + name VARCHAR(255), + birthday DATE +); + +-- Таблицы-связки +CREATE TABLE IF NOT EXISTS film_genre ( + film_id INT REFERENCES film(id) ON DELETE CASCADE, + genre_id INT REFERENCES genre(id) ON DELETE RESTRICT, + PRIMARY KEY (film_id, genre_id) +); + +CREATE TABLE IF NOT EXISTS film_like ( + film_id INT REFERENCES film(id) ON DELETE CASCADE, + user_id INT REFERENCES users(id) ON DELETE CASCADE, + PRIMARY KEY (film_id, user_id) +); + +CREATE TABLE IF NOT EXISTS friendship ( + user_id INT REFERENCES users(id) ON DELETE CASCADE, + friend_id INT REFERENCES users(id) ON DELETE CASCADE, + is_confirmed BOOLEAN NOT NULL, + PRIMARY KEY (user_id, friend_id) +); \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java deleted file mode 100644 index 63c6d6e..0000000 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package ru.yandex.practicum.filmorate; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -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.web.servlet.MockMvc; -import ru.yandex.practicum.filmorate.controller.FilmController; -import ru.yandex.practicum.filmorate.model.Film; -import ru.yandex.practicum.filmorate.service.FilmService; - -import java.time.LocalDate; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -@WebMvcTest(FilmController.class) -class FilmControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private FilmService filmService; - - @Autowired - private ObjectMapper objectMapper; - - private Film validFilm; - - @BeforeEach - void setUp() { - validFilm = new Film(); - validFilm.setId(1); - validFilm.setName("Test Film"); - validFilm.setDescription("Test Description"); - validFilm.setReleaseDate(LocalDate.of(2000, 1, 1)); - validFilm.setDuration(120); - } - - @Test - void shouldCreateFilm() throws Exception { - when(filmService.create(any(Film.class))).thenReturn(validFilm); - - mockMvc.perform(post("/films") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(validFilm))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)) - .andExpect(jsonPath("$.name").value("Test Film")) - .andExpect(jsonPath("$.duration").value(120)); - } - - @Test - void shouldGetAllFilms() throws Exception { - when(filmService.getAll()).thenReturn(List.of(validFilm)); - - mockMvc.perform(get("/films")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(1)) - .andExpect(jsonPath("$[0].name").value("Test Film")); - } - - @Test - void shouldGetFilmById() throws Exception { - when(filmService.getById(1)).thenReturn(validFilm); - - mockMvc.perform(get("/films/1")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)) - .andExpect(jsonPath("$.name").value("Test Film")); - } - - @Test - void shouldUpdateFilm() throws Exception { - when(filmService.update(any(Film.class))).thenReturn(validFilm); - - mockMvc.perform(put("/films") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(validFilm))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)) - .andExpect(jsonPath("$.name").value("Test Film")); - } - - @Test - void shouldAddLike() throws Exception { - mockMvc.perform(put("/films/1/like/2")) - .andExpect(status().isOk()); - } - - @Test - void shouldRemoveLike() throws Exception { - mockMvc.perform(delete("/films/1/like/2")) - .andExpect(status().isOk()); - } - - @Test - void shouldGetPopularFilms() throws Exception { - when(filmService.getPopularFilms(anyInt())).thenReturn(List.of(validFilm)); - - mockMvc.perform(get("/films/popular?count=10")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(1)); - } - - @Test - void shouldGetPopularFilmsWithDefaultCount() throws Exception { - when(filmService.getPopularFilms(10)).thenReturn(List.of(validFilm)); - - mockMvc.perform(get("/films/popular")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(1)); - } -} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java deleted file mode 100644 index 660412e..0000000 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.yandex.practicum.filmorate; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class FilmorateApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java deleted file mode 100644 index 1fd378d..0000000 --- a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package ru.yandex.practicum.filmorate; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -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.web.servlet.MockMvc; -import ru.yandex.practicum.filmorate.controller.UserController; -import ru.yandex.practicum.filmorate.model.User; -import ru.yandex.practicum.filmorate.service.UserService; - -import java.time.LocalDate; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -@WebMvcTest(UserController.class) -class UserControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private UserService userService; - - @Autowired - private ObjectMapper objectMapper; - - private User validUser; - - @BeforeEach - void setUp() { - validUser = new User(); - validUser.setId(1); - validUser.setEmail("test@example.com"); - validUser.setLogin("testLogin"); - validUser.setName("Test Name"); - validUser.setBirthday(LocalDate.of(1990, 1, 1)); - } - - @Test - void shouldCreateUser() throws Exception { - when(userService.create(any(User.class))).thenReturn(validUser); - - mockMvc.perform(post("/users") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(validUser))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)) - .andExpect(jsonPath("$.email").value("test@example.com")) - .andExpect(jsonPath("$.login").value("testLogin")); - } - - @Test - void shouldGetAllUsers() throws Exception { - when(userService.getAll()).thenReturn(List.of(validUser)); - - mockMvc.perform(get("/users")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(1)) - .andExpect(jsonPath("$[0].email").value("test@example.com")); - } - - @Test - void shouldGetUserById() throws Exception { - when(userService.getById(1)).thenReturn(validUser); - - mockMvc.perform(get("/users/1")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)) - .andExpect(jsonPath("$.email").value("test@example.com")); - } - - @Test - void shouldUpdateUser() throws Exception { - when(userService.update(any(User.class))).thenReturn(validUser); - - mockMvc.perform(put("/users") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(validUser))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)) - .andExpect(jsonPath("$.email").value("test@example.com")); - } - - @Test - void shouldAddFriend() throws Exception { - mockMvc.perform(put("/users/1/friends/2")) - .andExpect(status().isOk()); - } - - @Test - void shouldRemoveFriend() throws Exception { - mockMvc.perform(delete("/users/1/friends/2")) - .andExpect(status().isOk()); - } - - @Test - void shouldGetFriends() throws Exception { - when(userService.getFriends(anyInt())).thenReturn(List.of(validUser)); - - mockMvc.perform(get("/users/1/friends")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(1)); - } - - @Test - void shouldGetCommonFriends() throws Exception { - when(userService.getCommonFriends(anyInt(), anyInt())).thenReturn(List.of(validUser)); - - mockMvc.perform(get("/users/1/friends/common/2")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(1)); - } -} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java new file mode 100644 index 0000000..29e0d12 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java @@ -0,0 +1,137 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.BeforeEach; +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.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.MpaRating; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +class FilmDbStorageTest { + + private final FilmDbStorage filmStorage; + private final UserStorage userStorage; + private final JdbcTemplate jdbcTemplate; + + @BeforeEach + void clearDb() { + jdbcTemplate.update("DELETE FROM film_likes"); + jdbcTemplate.update("DELETE FROM film_genres"); + jdbcTemplate.update("DELETE FROM films"); + jdbcTemplate.execute("ALTER TABLE films ALTER COLUMN id RESTART WITH 1"); + } + + @Test + public void testCreateAndGetFilmById() { + Film film = createFilm(1); + Film createdFilm = filmStorage.create(film); + Optional filmOptional = filmStorage.getById(createdFilm.getId()); + + assertThat(filmOptional) + .isPresent() + .hasValueSatisfying(f -> { + assertThat(f).hasFieldOrPropertyWithValue("name", "Film 1"); + assertThat(f.getMpa()).hasFieldOrPropertyWithValue("id", 1); + }); + } + + @Test + public void testGetAllFilms() { + filmStorage.create(createFilm(1)); + filmStorage.create(createFilm(2)); + List films = filmStorage.getAll(); + assertThat(films).hasSize(2); + } + + @Test + public void testUpdateFilm() { + Film film = filmStorage.create(createFilm(1)); + film.setName("Updated Film Name"); + filmStorage.update(film); + Optional updatedFilmOpt = filmStorage.getById(film.getId()); + + assertThat(updatedFilmOpt) + .isPresent() + .hasValueSatisfying(f -> assertThat(f).hasFieldOrPropertyWithValue("name", "Updated Film Name")); + } + + @Test + public void testDeleteFilm() { + Film film = filmStorage.create(createFilm(1)); + filmStorage.delete(film.getId()); + Optional deletedFilmOpt = filmStorage.getById(film.getId()); + assertThat(deletedFilmOpt).isEmpty(); + } + + @Test + public void testAddAndRemoveLike() { + Film film = filmStorage.create(createFilm(1)); + User user = userStorage.create(createUser(1)); + + filmStorage.addLike(film.getId(), user.getId()); + + // Проверяем, что лайк добавился (в списке популярных фильм будет) + List popular = filmStorage.getPopularFilms(1); + assertThat(popular).hasSize(1); + assertThat(popular.get(0).getId()).isEqualTo(film.getId()); + + filmStorage.removeLike(film.getId(), user.getId()); + + // Проверяем, что после удаления лайка фильм не в топе + // (Этот тест может быть неточным, если есть другие фильмы с лайками, но в чистой БД сработает) + } + + @Test + public void testGetPopularFilms() { + Film film1 = filmStorage.create(createFilm(1)); // 0 лайков + Film film2 = filmStorage.create(createFilm(2)); // 1 лайк + Film film3 = filmStorage.create(createFilm(3)); // 2 лайка + User user1 = userStorage.create(createUser(1)); + User user2 = userStorage.create(createUser(2)); + + filmStorage.addLike(film2.getId(), user1.getId()); + filmStorage.addLike(film3.getId(), user1.getId()); + filmStorage.addLike(film3.getId(), user2.getId()); + + List popularFilms = filmStorage.getPopularFilms(3); + + assertThat(popularFilms).hasSize(3); + assertThat(popularFilms.get(0).getId()).isEqualTo(film3.getId()); + assertThat(popularFilms.get(1).getId()).isEqualTo(film2.getId()); + assertThat(popularFilms.get(2).getId()).isEqualTo(film1.getId()); + } + + // Вспомогательные методы + private Film createFilm(int index) { + Film film = new Film(); + film.setName("Film " + index); + film.setDescription("Description " + index); + film.setReleaseDate(LocalDate.of(2000 + index, 1, 1)); + film.setDuration(100 + index); + film.setMpa(new MpaRating(1, "G")); // Предполагаем, что MPA с ID=1 есть + return film; + } + + private User createUser(int index) { + User user = new User(); + user.setEmail("user" + index + "@mail.com"); + user.setLogin("login" + index); + user.setName("Name " + index); + user.setBirthday(LocalDate.of(1990 + index, 1, 1)); + return user; + } +} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorageTest.java new file mode 100644 index 0000000..75767ec --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorageTest.java @@ -0,0 +1,40 @@ +package ru.yandex.practicum.filmorate.storage.dao; +import lombok.RequiredArgsConstructor; +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.context.SpringBootTest; +import ru.yandex.practicum.filmorate.model.Genre; + +import java.util.List; +import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; +@SpringBootTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +class GenreDbStorageTest { + private final GenreDbStorage genreStorage; + + @Test + void testGetAllGenres() { + List genres = genreStorage.getAll(); + assertThat(genres).hasSize(6); // По data.sql у нас 6 жанров + } + + @Test + void testGetGenreById() { + Optional genreOptional = genreStorage.getById(1); + assertThat(genreOptional) + .isPresent() + .hasValueSatisfying(genre -> { + assertThat(genre).hasFieldOrPropertyWithValue("id", 1); + assertThat(genre).hasFieldOrPropertyWithValue("name", "Комедия"); + }); + } + + @Test + void testGetGenreByNonExistentId() { + Optional genreOptional = genreStorage.getById(999); + assertThat(genreOptional).isEmpty(); + } +} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorageTest.java new file mode 100644 index 0000000..6e71a13 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorageTest.java @@ -0,0 +1,44 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +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.context.SpringBootTest; +import ru.yandex.practicum.filmorate.model.MpaRating; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +class MpaDbStorageTest { + + private final MpaDbStorage mpaStorage; + + @Test + void testGetAllMpaRatings() { + List ratings = mpaStorage.getAll(); + assertThat(ratings).hasSize(5); // По data.sql у нас 5 рейтингов + } + + @Test + void testGetMpaRatingById() { + Optional ratingOptional = mpaStorage.getById(1); + assertThat(ratingOptional) + .isPresent() + .hasValueSatisfying(rating -> { + assertThat(rating).hasFieldOrPropertyWithValue("id", 1); + assertThat(rating).hasFieldOrPropertyWithValue("name", "G"); + }); + } + + @Test + void testGetMpaRatingByNonExistentId() { + Optional ratingOptional = mpaStorage.getById(999); + assertThat(ratingOptional).isEmpty(); + } +} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorageTest.java new file mode 100644 index 0000000..813b890 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorageTest.java @@ -0,0 +1,121 @@ +package ru.yandex.practicum.filmorate.storage.dao; + +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.BeforeEach; +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.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.yandex.practicum.filmorate.model.User; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +class UserDbStorageTest { + + private final UserDbStorage userStorage; + private final JdbcTemplate jdbcTemplate; + + // Этот метод будет очищать таблицы перед каждым тестом + @BeforeEach + void clearDb() { + jdbcTemplate.update("DELETE FROM friendships"); + jdbcTemplate.update("DELETE FROM users"); + jdbcTemplate.execute("ALTER TABLE users ALTER COLUMN id RESTART WITH 1"); + } + + @Test + public void testCreateAndGetUserById() { + User user = createUser(1); + User createdUser = userStorage.create(user); + + Optional userOptional = userStorage.getById(createdUser.getId()); + + assertThat(userOptional) + .isPresent() + .hasValueSatisfying(u -> { + assertThat(u).hasFieldOrPropertyWithValue("id", createdUser.getId()); + assertThat(u).hasFieldOrPropertyWithValue("email", "user1@mail.com"); + }); + } + + @Test + public void testGetAllUsers() { + userStorage.create(createUser(1)); + userStorage.create(createUser(2)); + List users = userStorage.getAll(); + assertThat(users).hasSize(2); + } + + @Test + public void testUpdateUser() { + User user = userStorage.create(createUser(1)); + user.setName("Updated Name"); + userStorage.update(user); + Optional updatedUserOpt = userStorage.getById(user.getId()); + + assertThat(updatedUserOpt) + .isPresent() + .hasValueSatisfying(u -> assertThat(u).hasFieldOrPropertyWithValue("name", "Updated Name")); + } + + @Test + public void testDeleteUser() { + User user = userStorage.create(createUser(1)); + userStorage.delete(user.getId()); + Optional deletedUserOpt = userStorage.getById(user.getId()); + assertThat(deletedUserOpt).isEmpty(); + } + + @Test + public void testAddAndGetFriends() { + User user1 = userStorage.create(createUser(1)); + User user2 = userStorage.create(createUser(2)); + userStorage.addFriend(user1.getId(), user2.getId()); + + List friends = userStorage.getFriends(user1.getId()); + assertThat(friends).hasSize(1); + assertThat(friends.get(0).getId()).isEqualTo(user2.getId()); + } + + @Test + public void testRemoveFriend() { + User user1 = userStorage.create(createUser(1)); + User user2 = userStorage.create(createUser(2)); + userStorage.addFriend(user1.getId(), user2.getId()); + userStorage.removeFriend(user1.getId(), user2.getId()); + + List friends = userStorage.getFriends(user1.getId()); + assertThat(friends).isEmpty(); + } + + @Test + public void testGetCommonFriends() { + User user1 = userStorage.create(createUser(1)); + User user2 = userStorage.create(createUser(2)); + User commonFriend = userStorage.create(createUser(3)); + userStorage.addFriend(user1.getId(), commonFriend.getId()); + userStorage.addFriend(user2.getId(), commonFriend.getId()); + + List commonFriends = userStorage.getCommonFriends(user1.getId(), user2.getId()); + assertThat(commonFriends).hasSize(1); + assertThat(commonFriends.get(0).getId()).isEqualTo(commonFriend.getId()); + } + + + private User createUser(int index) { + User user = new User(); + user.setEmail("user" + index + "@mail.com"); + user.setLogin("login" + index); + user.setName("Name " + index); + user.setBirthday(LocalDate.of(1990 + index, 1, 1)); + return user; + } +} \ No newline at end of file From 35306e3f9edefed8da087663252ac1d70b9d32c6 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 20 Jan 2026 19:41:58 +0300 Subject: [PATCH 15/20] fix: Fix Checkstyle issue in FilmController --- .../ru/yandex/practicum/filmorate/controller/FilmController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 6cc0c9e..aefc6f3 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -5,6 +5,7 @@ import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.service.FilmService; import java.util.List; + @RestController @RequestMapping("/films") @RequiredArgsConstructor From dcb946603a7aae2629c14177acee13bd459a9bbd Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 20 Jan 2026 19:48:50 +0300 Subject: [PATCH 16/20] fix checkstyle --- .../java/ru/yandex/practicum/filmorate/storage/GenreStorage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java index 9720260..b36227e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java @@ -6,5 +6,6 @@ public interface GenreStorage { List getAll(); + Optional getById(int id); } \ No newline at end of file From e950b1ddeb8ecf698c83409a308cd1110c6233b4 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 20 Jan 2026 20:17:00 +0300 Subject: [PATCH 17/20] fix checkstyle --- .../java/ru/yandex/practicum/filmorate/storage/MpaStorage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java index adb8e63..bdee512 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java @@ -6,5 +6,6 @@ public interface MpaStorage { List getAll(); + Optional getById(int id); } \ No newline at end of file From 2bebe4fbae586e7baf6ae8051469cc39dcaae7de Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 20 Jan 2026 20:25:31 +0300 Subject: [PATCH 18/20] fix database errors --- src/main/resources/schema.sql | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index e776aad..1cbec65 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,28 +1,28 @@ -- Удаляем таблицы в правильном порядке, если они существуют -DROP TABLE IF EXISTS film_like, film_genre, friendship, film, users, mpa_rating, genre CASCADE; +DROP TABLE IF EXISTS film_likes, film_genres, friendships, films, users, mpa_ratings, genres CASCADE; -- Справочники -CREATE TABLE IF NOT EXISTS mpa_rating ( +CREATE TABLE IF NOT EXISTS mpa_ratings ( id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(10) NOT NULL UNIQUE ); -CREATE TABLE IF NOT EXISTS genre ( +CREATE TABLE IF NOT EXISTS genres ( id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(50) NOT NULL UNIQUE ); -- Основные сущности -CREATE TABLE IF NOT EXISTS film ( +CREATE TABLE IF NOT EXISTS films ( id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(255) NOT NULL, description VARCHAR(200), release_date DATE, duration INT, - mpa_rating_id INT REFERENCES mpa_rating(id) ON DELETE RESTRICT + mpa_rating_id INT REFERENCES mpa_ratings(id) ON DELETE RESTRICT ); -CREATE TABLE IF NOT EXISTS users ( -- Название во множественном числе, чтобы избежать конфликта с SQL +CREATE TABLE IF NOT EXISTS users ( id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, login VARCHAR(255) NOT NULL UNIQUE, @@ -31,21 +31,27 @@ CREATE TABLE IF NOT EXISTS users ( -- Название во множествен ); -- Таблицы-связки -CREATE TABLE IF NOT EXISTS film_genre ( - film_id INT REFERENCES film(id) ON DELETE CASCADE, - genre_id INT REFERENCES genre(id) ON DELETE RESTRICT, +CREATE TABLE IF NOT EXISTS film_genres ( + film_id INT REFERENCES films(id) ON DELETE CASCADE, + genre_id INT REFERENCES genres(id) ON DELETE RESTRICT, PRIMARY KEY (film_id, genre_id) ); -CREATE TABLE IF NOT EXISTS film_like ( - film_id INT REFERENCES film(id) ON DELETE CASCADE, +CREATE TABLE IF NOT EXISTS film_likes ( + film_id INT REFERENCES films(id) ON DELETE CASCADE, user_id INT REFERENCES users(id) ON DELETE CASCADE, PRIMARY KEY (film_id, user_id) ); -CREATE TABLE IF NOT EXISTS friendship ( +CREATE TABLE IF NOT EXISTS friendships ( + film_id INT REFERENCES films(id) ON DELETE CASCADE, + user_id INT REFERENCES users(id) ON DELETE CASCADE, + PRIMARY KEY (film_id, user_id) +); + +CREATE TABLE IF NOT EXISTS friendships ( user_id INT REFERENCES users(id) ON DELETE CASCADE, friend_id INT REFERENCES users(id) ON DELETE CASCADE, - is_confirmed BOOLEAN NOT NULL, + status BOOLEAN NOT NULL, PRIMARY KEY (user_id, friend_id) -); \ No newline at end of file +); From 7d42bdcf5139b72c28b3d66fd6e29febe956b738 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Tue, 20 Jan 2026 20:31:02 +0300 Subject: [PATCH 19/20] fix errors --- src/main/resources/schema.sql | 8 +------- .../storage/dao/FilmDbStorageTest.java | 17 ++++++++--------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 1cbec65..0c0d075 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -43,15 +43,9 @@ CREATE TABLE IF NOT EXISTS film_likes ( PRIMARY KEY (film_id, user_id) ); -CREATE TABLE IF NOT EXISTS friendships ( - film_id INT REFERENCES films(id) ON DELETE CASCADE, - user_id INT REFERENCES users(id) ON DELETE CASCADE, - PRIMARY KEY (film_id, user_id) -); - CREATE TABLE IF NOT EXISTS friendships ( user_id INT REFERENCES users(id) ON DELETE CASCADE, friend_id INT REFERENCES users(id) ON DELETE CASCADE, status BOOLEAN NOT NULL, PRIMARY KEY (user_id, friend_id) -); +); \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java index 29e0d12..c52907f 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorageTest.java @@ -29,10 +29,14 @@ class FilmDbStorageTest { @BeforeEach void clearDb() { + // Очищаем ВСЕ таблицы перед каждым тестом jdbcTemplate.update("DELETE FROM film_likes"); jdbcTemplate.update("DELETE FROM film_genres"); + jdbcTemplate.update("DELETE FROM friendships"); jdbcTemplate.update("DELETE FROM films"); + jdbcTemplate.update("DELETE FROM users"); jdbcTemplate.execute("ALTER TABLE films ALTER COLUMN id RESTART WITH 1"); + jdbcTemplate.execute("ALTER TABLE users ALTER COLUMN id RESTART WITH 1"); } @Test @@ -84,22 +88,18 @@ public void testAddAndRemoveLike() { filmStorage.addLike(film.getId(), user.getId()); - // Проверяем, что лайк добавился (в списке популярных фильм будет) List popular = filmStorage.getPopularFilms(1); assertThat(popular).hasSize(1); assertThat(popular.get(0).getId()).isEqualTo(film.getId()); filmStorage.removeLike(film.getId(), user.getId()); - - // Проверяем, что после удаления лайка фильм не в топе - // (Этот тест может быть неточным, если есть другие фильмы с лайками, но в чистой БД сработает) } @Test public void testGetPopularFilms() { - Film film1 = filmStorage.create(createFilm(1)); // 0 лайков - Film film2 = filmStorage.create(createFilm(2)); // 1 лайк - Film film3 = filmStorage.create(createFilm(3)); // 2 лайка + Film film1 = filmStorage.create(createFilm(1)); + Film film2 = filmStorage.create(createFilm(2)); + Film film3 = filmStorage.create(createFilm(3)); User user1 = userStorage.create(createUser(1)); User user2 = userStorage.create(createUser(2)); @@ -115,14 +115,13 @@ public void testGetPopularFilms() { assertThat(popularFilms.get(2).getId()).isEqualTo(film1.getId()); } - // Вспомогательные методы private Film createFilm(int index) { Film film = new Film(); film.setName("Film " + index); film.setDescription("Description " + index); film.setReleaseDate(LocalDate.of(2000 + index, 1, 1)); film.setDuration(100 + index); - film.setMpa(new MpaRating(1, "G")); // Предполагаем, что MPA с ID=1 есть + film.setMpa(new MpaRating(1, "G")); return film; } From 960bbc51ac55040b2ab7c0e9b3769d446e7c1560 Mon Sep 17 00:00:00 2001 From: Darya346 Date: Wed, 21 Jan 2026 22:27:55 +0300 Subject: [PATCH 20/20] refactor: Apply review suggestions --- .../filmorate/controller/UserController.java | 5 +- .../filmorate/service/FilmService.java | 12 ++-- .../filmorate/storage/dao/FilmDbStorage.java | 67 +++++++++++-------- .../filmorate/storage/dao/GenreDbStorage.java | 8 +-- .../filmorate/storage/dao/MpaDbStorage.java | 8 +-- .../filmorate/storage/dao/UserDbStorage.java | 29 +++----- 6 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 09a2a18..0e226d0 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -14,6 +14,7 @@ public class UserController { private final UserService userService; + private static final String FRIEND_PATH = "/{id}/friends/{friendId}"; @PostMapping public User create(@Valid @RequestBody User user) { @@ -35,12 +36,12 @@ public User getById(@PathVariable int id) { return userService.getById(id); } - @PutMapping("/{id}/friends/{friendId}") + @PutMapping(FRIEND_PATH) public void addFriend(@PathVariable int id, @PathVariable int friendId) { userService.addFriend(id, friendId); } - @DeleteMapping("/{id}/friends/{friendId}") + @DeleteMapping(FRIEND_PATH) public void removeFriend(@PathVariable int id, @PathVariable int friendId) { userService.removeFriend(id, friendId); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java index a127ef6..136ee49 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -30,14 +30,14 @@ public Film create(Film film) { } public Film update(Film film) { - getById(film.getId()); // Проверяем, что фильм существует + getById(film.getId()); validateFilm(film); return filmStorage.update(film); } public Film getById(int id) { return filmStorage.getById(id) - .orElseThrow(() -> new NotFoundException("Фильм с id=" + id + " не найден.")); + .orElseThrow(() -> new NotFoundException(String.format("Фильм с id=%d не найден.", id))); } public List getAll() { @@ -47,14 +47,14 @@ public List getAll() { public void addLike(int filmId, int userId) { getById(filmId); userStorage.getById(userId) - .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден.")); + .orElseThrow(() -> new NotFoundException(String.format("Пользователь с id=%d не найден.", userId))); filmStorage.addLike(filmId, userId); } public void removeLike(int filmId, int userId) { getById(filmId); userStorage.getById(userId) - .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден.")); + .orElseThrow(() -> new NotFoundException(String.format("Пользователь с id=%d не найден.", userId))); filmStorage.removeLike(filmId, userId); } @@ -68,12 +68,12 @@ private void validateFilm(Film film) { } if (film.getMpa() != null) { mpaStorage.getById(film.getMpa().getId()) - .orElseThrow(() -> new NotFoundException("Рейтинг MPA с id=" + film.getMpa().getId() + " не найден.")); + .orElseThrow(() -> new NotFoundException(String.format("Рейтинг MPA с id=%d не найден.", film.getMpa().getId()))); } if (film.getGenres() != null) { for (Genre genre : film.getGenres()) { genreStorage.getById(genre.getId()) - .orElseThrow(() -> new NotFoundException("Жанр с id=" + genre.getId() + " не найден.")); + .orElseThrow(() -> new NotFoundException(String.format("Жанр с id=%d не найден.", genre.getId()))); } } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java index 532710f..26e5f50 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/FilmDbStorage.java @@ -16,6 +16,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; +import java.util.stream.Collectors; @Repository @Primary @@ -58,6 +59,12 @@ public Film update(Film film) { return getById(film.getId()).orElse(null); } + @Override + public void delete(int id) { + String sql = "DELETE FROM films WHERE id = ?"; + jdbcTemplate.update(sql, id); + } + @Override public Optional getById(int id) { String sql = "SELECT f.*, m.name AS mpa_name " + @@ -72,16 +79,11 @@ public Optional getById(int id) { public List getAll() { String sql = "SELECT f.*, m.name AS mpa_name " + "FROM films AS f " + - "JOIN mpa_ratings AS m ON f.mpa_rating_id = m.id"; + "JOIN mpa_ratings AS m ON f.mpa_rating_id = m.id " + + "ORDER BY f.id"; return jdbcTemplate.query(sql, this::mapRowToFilm); } - @Override - public void delete(int id) { - String sql = "DELETE FROM films WHERE id = ?"; - jdbcTemplate.update(sql, id); - } - @Override public void addLike(int filmId, int userId) { String sql = "INSERT INTO film_likes (film_id, user_id) VALUES (?, ?)"; @@ -96,40 +98,49 @@ public void removeLike(int filmId, int userId) { @Override public List getPopularFilms(int count) { - String sql = "SELECT f.*, m.name AS mpa_name " + - "FROM films AS f " + - "JOIN mpa_ratings AS m ON f.mpa_rating_id = m.id " + - "LEFT JOIN film_likes AS fl ON f.id = fl.film_id " + - "GROUP BY f.id, m.name " + - "ORDER BY COUNT(fl.user_id) DESC " + + String sql = "SELECT f.id FROM films AS f " + + "LEFT JOIN film_likes AS l ON f.id = l.film_id " + + "GROUP BY f.id " + + "ORDER BY COUNT(l.user_id) DESC " + "LIMIT ?"; - return jdbcTemplate.query(sql, this::mapRowToFilm, count); + List filmIds = jdbcTemplate.queryForList(sql, Integer.class, count); + return filmIds.stream() + .map(this::getById) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); } private void updateFilmGenres(Film film) { jdbcTemplate.update("DELETE FROM film_genres WHERE film_id = ?", film.getId()); - if (film.getGenres() != null && !film.getGenres().isEmpty()) { - Set uniqueGenres = new HashSet<>(film.getGenres()); - String sql = "INSERT INTO film_genres (film_id, genre_id) VALUES (?, ?)"; - for (Genre genre : uniqueGenres) { - jdbcTemplate.update(sql, film.getId(), genre.getId()); - } + + if (film.getGenres() == null || film.getGenres().isEmpty()) { + return; } + Set uniqueGenres = new HashSet<>(film.getGenres()); + + StringBuilder sqlBuilder = new StringBuilder("INSERT INTO film_genres (film_id, genre_id) VALUES "); + List values = uniqueGenres.stream() + .map(genre -> String.format("(%d, %d)", film.getId(), genre.getId())) + .collect(Collectors.toList()); + sqlBuilder.append(String.join(", ", values)); + + jdbcTemplate.update(sqlBuilder.toString()); } - private Film mapRowToFilm(ResultSet rs, int rowNum) throws SQLException { + private Film mapRowToFilm(ResultSet resultSet, int rowNum) throws SQLException { Film film = new Film(); - film.setId(rs.getInt("id")); - film.setName(rs.getString("name")); - film.setDescription(rs.getString("description")); - film.setReleaseDate(rs.getDate("release_date").toLocalDate()); - film.setDuration(rs.getInt("duration")); - film.setMpa(new MpaRating(rs.getInt("mpa_rating_id"), rs.getString("mpa_name"))); + film.setId(resultSet.getInt("id")); + film.setName(resultSet.getString("name")); + film.setDescription(resultSet.getString("description")); + film.setReleaseDate(resultSet.getDate("release_date").toLocalDate()); + film.setDuration(resultSet.getInt("duration")); + film.setMpa(new MpaRating(resultSet.getInt("mpa_rating_id"), resultSet.getString("mpa_name"))); String genresSql = "SELECT g.id, g.name FROM genres AS g JOIN film_genres AS fg ON g.id = fg.genre_id WHERE fg.film_id = ?"; List genres = jdbcTemplate.query(genresSql, (g_rs, g_rowNum) -> new Genre(g_rs.getInt("id"), g_rs.getString("name")), film.getId()); - film.setGenres(new LinkedHashSet<>(genres)); + film.getGenres().addAll(genres); return film; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java index 177d94f..352f616 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/GenreDbStorage.java @@ -13,7 +13,7 @@ import java.util.Optional; @Repository -@Primary // Делаем эту реализацию основной для интерфейса GenreStorage +@Primary @RequiredArgsConstructor public class GenreDbStorage implements GenreStorage { @@ -32,10 +32,10 @@ public Optional getById(int id) { return genres.stream().findFirst(); } - private Genre mapRowToGenre(ResultSet rs, int rowNum) throws SQLException { + private Genre mapRowToGenre(ResultSet resultSet, int rowNum) throws SQLException { return new Genre( - rs.getInt("id"), - rs.getString("name") + resultSet.getInt("id"), + resultSet.getString("name") ); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java index e3a334c..4c3b296 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/MpaDbStorage.java @@ -13,7 +13,7 @@ import java.util.Optional; @Repository -@Primary // Делаем эту реализацию основной для интерфейса MpaStorage +@Primary @RequiredArgsConstructor public class MpaDbStorage implements MpaStorage { @@ -32,10 +32,10 @@ public Optional getById(int id) { return ratings.stream().findFirst(); } - private MpaRating mapRowToMpaRating(ResultSet rs, int rowNum) throws SQLException { + private MpaRating mapRowToMpaRating(ResultSet resultSet, int rowNum) throws SQLException { return new MpaRating( - rs.getInt("id"), - rs.getString("name") + resultSet.getInt("id"), + resultSet.getString("name") ); } } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java index 97219cf..a61e902 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dao/UserDbStorage.java @@ -75,7 +75,6 @@ public List getAll() { @Override public void addFriend(int userId, int friendId) { - // Добавляем запись о дружбе. Статус true означает, что заявка подтверждена (для односторонней дружбы) String sql = "INSERT INTO friendships (user_id, friend_id, status) VALUES (?, ?, ?)"; jdbcTemplate.update(sql, userId, friendId, true); } @@ -88,33 +87,27 @@ public void removeFriend(int userId, int friendId) { @Override public List getFriends(int userId) { - // Выбираем пользователей, которые являются друзьями для userId - String sql = "SELECT u.* FROM users u " + - "JOIN friendships f ON u.id = f.friend_id " + - "WHERE f.user_id = ?"; + String sql = "SELECT u.* FROM users u JOIN friendships f ON u.id = f.friend_id WHERE f.user_id = ?"; return jdbcTemplate.query(sql, this::mapRowToUser, userId); } @Override public List getCommonFriends(int userId, int otherId) { - // Находим пересечение списков друзей с помощью INTERSECT String sql = "SELECT u.* " + - "FROM users u " + - "WHERE u.id IN (" + - " SELECT friend_id FROM friendships WHERE user_id = ? " + - " INTERSECT " + - " SELECT friend_id FROM friendships WHERE user_id = ?" + - ")"; + "FROM friendships f1 " + + "JOIN friendships f2 ON f1.friend_id = f2.friend_id " + + "JOIN users u ON f1.friend_id = u.id " + + "WHERE f1.user_id = ? AND f2.user_id = ?"; return jdbcTemplate.query(sql, this::mapRowToUser, userId, otherId); } - private User mapRowToUser(ResultSet rs, int rowNum) throws SQLException { + private User mapRowToUser(ResultSet resultSet, int rowNum) throws SQLException { User user = new User(); - user.setId(rs.getInt("id")); - user.setEmail(rs.getString("email")); - user.setLogin(rs.getString("login")); - user.setName(rs.getString("name")); - user.setBirthday(rs.getDate("birthday").toLocalDate()); + user.setId(resultSet.getInt("id")); + user.setEmail(resultSet.getString("email")); + user.setLogin(resultSet.getString("login")); + user.setName(resultSet.getString("name")); + user.setBirthday(resultSet.getDate("birthday").toLocalDate()); return user; } } \ No newline at end of file