diff --git a/back/volume/src/chat/chat.controller.ts b/back/volume/src/chat/chat.controller.ts index 92df932..55bb409 100644 --- a/back/volume/src/chat/chat.controller.ts +++ b/back/volume/src/chat/chat.controller.ts @@ -33,33 +33,37 @@ export class ChatController { @Post(':id/invite') async addUser ( @Param('id', ParseIntPipe) id: number, - @Body() target: IdDto, - @Profile42() profile: Profile + @Body() target: IdDto, + @Profile42() profile: Profile ): Promise { const channel = await this.channelService.getFullChannel(id) const user: User | null = await this.usersService.findUser(target.id) - if (user == null) + if (user == null) { throw new NotFoundException(`User #${target.id} not found`) - if (channel.isPrivate && channel.password === '') + } + if (channel.isPrivate && channel.password === '') { throw new BadRequestException('You cannot add more users to a DM') + } if (!(await this.channelService.isUser(channel.id, +profile.id))) { throw new BadRequestException( 'You are not allowed to invite users to this channel' ) } - if (await this.channelService.isUser(channel.id, target.id)) + if (await this.channelService.isUser(channel.id, target.id)) { throw new BadRequestException('User is already in this channel') - if (await this.channelService.isBanned(channel.id, target.id)) + } + if (await this.channelService.isBanned(channel.id, target.id)) { throw new BadRequestException('User is banned from this channel') + } channel.users.push(user) - this.channelService.save(channel) + await this.channelService.save(channel) } @Delete(':id/kick') async removeUser ( @Param('id', ParseIntPipe) id: number, - @Body() target: IdDto, - @Profile42() profile: Profile + @Body() target: IdDto, + @Profile42() profile: Profile ): Promise { const channel = await this.channelService.getFullChannel(id) if (!(await this.channelService.isAdmin(channel.id, +profile.id))) { @@ -67,118 +71,136 @@ export class ChatController { 'You are not allowed to kick users from this channel' ) } - if (!(await this.channelService.isUser(channel.id, target.id))) + if (!(await this.channelService.isUser(channel.id, target.id))) { throw new BadRequestException('User is not in this channel') - if (await this.channelService.isOwner(channel.id, target.id)) + } + if (await this.channelService.isOwner(channel.id, target.id)) { throw new BadRequestException('You cannot kick the owner of the channel') + } channel.users = channel.users.filter((usr: User) => { return usr.ftId !== target.id }) - this.channelService.save(channel) + await this.channelService.save(channel) } @Post(':id/admin') async addAdmin ( @Param('id', ParseIntPipe) id: number, - @Body() target: IdDto, - @Profile42() profile: Profile + @Body() target: IdDto, + @Profile42() profile: Profile ): Promise { const channel = await this.channelService.getFullChannel(id) const user: User | null = await this.usersService.findUser(target.id) - if (user == null) + if (user == null) { throw new NotFoundException(`User #${target.id} not found`) - if (!(await this.channelService.isOwner(channel.id, +profile.id))) + } + if (!(await this.channelService.isOwner(channel.id, +profile.id))) { throw new BadRequestException('You are not the owner of this channel') - if (!(await this.channelService.isUser(channel.id, target.id))) + } + if (!(await this.channelService.isUser(channel.id, target.id))) { throw new BadRequestException('User is not in this channel') - if (await this.channelService.isAdmin(channel.id, target.id)) + } + if (await this.channelService.isAdmin(channel.id, target.id)) { throw new BadRequestException('User is already an admin of this channel') + } channel.admins.push(user) - this.channelService.save(channel) + await this.channelService.save(channel) } @Delete(':id/admin') async removeAdmin ( @Param('id', ParseIntPipe) id: number, - @Body() target: IdDto, - @Profile42() profile: Profile + @Body() target: IdDto, + @Profile42() profile: Profile ): Promise { const channel = await this.channelService.getFullChannel(id) - if (!(await this.channelService.isOwner(channel.id, +profile.id))) + if (!(await this.channelService.isOwner(channel.id, +profile.id))) { throw new BadRequestException('You are not the owner of this channel') - if (!(await this.channelService.isAdmin(channel.id, target.id))) + } + if (!(await this.channelService.isAdmin(channel.id, target.id))) { throw new BadRequestException('User is not an admin of this channel') + } channel.admins = channel.admins.filter((usr: User) => { return usr.ftId !== target.id }) - this.channelService.save(channel) + await this.channelService.save(channel) } @Post(':id/ban') async addBan ( @Param('id', ParseIntPipe) id: number, - @Body() target: IdDto, - @Profile42() profile: Profile - ):Promise { + @Body() target: IdDto, + @Profile42() profile: Profile + ): Promise { const channel = await this.channelService.getFullChannel(id) const user: User | null = await this.usersService.findUser(target.id) - if (user == null) + if (user == null) { throw new NotFoundException(`User #${target.id} not found`) + } if (!(await this.channelService.isAdmin(channel.id, +profile.id))) { throw new BadRequestException( 'You are not allowed to ban users from this channel' ) } - if (await this.channelService.isOwner(channel.id, target.id)) + if (await this.channelService.isOwner(channel.id, target.id)) { throw new BadRequestException('You cannot ban the owner of the channel') - if (await this.channelService.isBanned(channel.id, target.id)) + } + if (await this.channelService.isBanned(channel.id, target.id)) { throw new BadRequestException('User is already banned from this channel') + } channel.banned.push(user) - this.channelService.save(channel) + await this.channelService.save(channel) } @Post(':id/mute') async addMute ( @Param('id', ParseIntPipe) id: number, - @Body() mute: MuteDto, // [userId, duration] - @Profile42() profile: Profile + @Body() mute: MuteDto, // [userId, duration] + @Profile42() profile: Profile ): Promise { const channel = await this.channelService.getFullChannel(id) const user: User | null = await this.usersService.findUser(mute.data[0]) - if (user == null) + if (user == null) { throw new NotFoundException(`User #${mute.data[0]} not found`) + } if (!(await this.channelService.isAdmin(channel.id, +profile.id))) { throw new BadRequestException( 'You are not allowed to mute users from this channel' ) } - if (await this.channelService.isOwner(channel.id, mute.data[0])) + if (await this.channelService.isOwner(channel.id, mute.data[0])) { throw new BadRequestException('You cannot mute the owner of the channel') - if (await this.channelService.getMuteDuration(channel.id, mute.data[0]) > 0) + } + if ( + (await this.channelService.getMuteDuration(channel.id, mute.data[0])) > 0 + ) { throw new BadRequestException('User is already muted from this channel') + } const newMute: number[] = [mute.data[0], Date.now() + mute.data[1] * 1000] channel.muted.push(newMute) - this.channelService.save(channel) + await this.channelService.save(channel) } @Delete(':id') async deleteChannel ( - @Profile42() profile: Profile, - @Param('id', ParseIntPipe) id: number + @Profile42() profile: Profile, + @Param('id', ParseIntPipe) id: number ): Promise { - if (!(await this.channelService.isOwner(id, +profile.id))) + if (!(await this.channelService.isOwner(id, +profile.id))) { throw new BadRequestException('You are not the owner of this channel') + } await this.channelService.removeChannel(id) } @Post(':id/password') async updatePassword ( - @Profile42() profile: Profile, - @Param('id', ParseIntPipe) id: number, - @Body() data: PasswordDto + @Profile42() profile: Profile, + @Param('id', ParseIntPipe) id: number, + @Body() data: PasswordDto ): Promise { - if (await this.channelService.isOwner(id, +profile.id)) + if (await this.channelService.isOwner(id, +profile.id)) { throw new BadRequestException('You are not the owner of this channel') + } await this.channelService.updatePassword(id, data.password) } diff --git a/back/volume/src/chat/chat.gateway.ts b/back/volume/src/chat/chat.gateway.ts index d1f942c..e61ec65 100644 --- a/back/volume/src/chat/chat.gateway.ts +++ b/back/volume/src/chat/chat.gateway.ts @@ -4,7 +4,7 @@ import { SubscribeMessage, WebSocketGateway, WebSocketServer, - WsException, + WsException } from '@nestjs/websockets' import { Socket, Server } from 'socket.io' // import { User } from 'users/user.entity'; @@ -20,7 +20,6 @@ import { Repository } from 'typeorm' import ConnectedUser from './entity/connection.entity' import { ConnectionDto } from './dto/connection.dto' - @WebSocketGateway({ cors: { origin: /^(http|ws):\/\/localhost(:\d+)?$/ } }) @@ -36,7 +35,9 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { private readonly connectedUserRepository: Repository ) {} - async handleConnection (socket: Socket): Promise {} + async handleConnection (socket: Socket): Promise { + console.log('Client connected: ' + socket.id) + } handleDisconnect (socket: Socket): void { socket.disconnect() @@ -44,20 +45,25 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { @SubscribeMessage('joinChannel') async onJoinChannel (socket: Socket, connect: ConnectionDto): Promise { - const channel = await this.chatService.getChannel(connect.ChannelId) - if (channel.banned.find((ban) => ban.id === connect.UserId) !== null) + console.log(connect.ChannelId, connect.UserId, connect.pwd) + const channel = await this.chatService.getFullChannel(connect.ChannelId) + if (channel.banned.find((ban) => ban.id === connect.UserId) !== null) { throw new WsException('You are banned from entering this channel') + } const user = (await this.userService.findUser(connect.UserId)) as User // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // We don't need to verify if the user is already in imo // - //if ( + // if ( // channel.users.find((usr) => usr.id === user.id) == null && // channel.password !== '' - //) { - if (channel.password !== '' && !(await bcrypt.compare(channel.password, connect.pwd))) - throw new WsException('Wrong password') - else await this.chatService.addUserToChannel(channel, user) + // ) { + if ( + channel.password !== '' && + !(await bcrypt.compare(channel.password, connect.pwd)) + ) { + throw new WsException('Wrong password') + } else await this.chatService.addUserToChannel(channel, user) { const conUser = new ConnectedUser() @@ -67,8 +73,10 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { await this.connectedUserRepository.save(conUser) } - const messages = - await this.messageService.findMessagesInChannelForUser(channel, user) + const messages = await this.messageService.findMessagesInChannelForUser( + channel, + user + ) this.server.to(socket.id).emit('messages', messages) await socket.join(channel.name) } diff --git a/back/volume/src/chat/chat.module.ts b/back/volume/src/chat/chat.module.ts index 381ca03..8909b26 100644 --- a/back/volume/src/chat/chat.module.ts +++ b/back/volume/src/chat/chat.module.ts @@ -1,4 +1,4 @@ -import { forwardRef, Module } from '@nestjs/common' +import { Module } from '@nestjs/common' import { TypeOrmModule } from '@nestjs/typeorm' import { AuthModule } from 'src/auth/auth.module' diff --git a/back/volume/src/chat/chat.service.ts b/back/volume/src/chat/chat.service.ts index a13719d..4cdf59f 100644 --- a/back/volume/src/chat/chat.service.ts +++ b/back/volume/src/chat/chat.service.ts @@ -56,7 +56,7 @@ export class ChatService { return newDM } - async updatePassword (id: number, password: string) { + async updatePassword (id: number, password: string): Promise { const channel: Channel | null = await this.ChannelRepository.findOneBy({ id }) @@ -113,7 +113,7 @@ export class ChatService { async getFullChannel (id: number): Promise { const channel = await this.ChannelRepository.findOne({ where: { id }, - relations: ['users', 'admins', 'banned', 'muted', 'owner'] + relations: ['users', 'admins', 'banned', 'owner'] }) if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) @@ -121,15 +121,15 @@ export class ChatService { return channel } - async update (channel: Channel) { + async update (channel: Channel): Promise { await this.ChannelRepository.update(channel.id, channel) } - async save (channel: Channel) { + async save (channel: Channel): Promise { await this.ChannelRepository.save(channel) } - async removeChannel (channelId: number) { + async removeChannel (channelId: number): Promise { await this.ChannelRepository.delete(channelId) } @@ -138,7 +138,7 @@ export class ChatService { where: { id }, relations: { owner: true } }) - if (channel == null) { + if (channel === null) { throw new NotFoundException(`Channel #${id} not found`) } return channel.owner.ftId === userId @@ -149,10 +149,10 @@ export class ChatService { where: { id }, relations: { admins: true } }) - if (channel == null) { + if (channel === null) { throw new NotFoundException(`Channel #${id} not found`) } - return channel.admins.findIndex((user) => user.ftId === userId) != -1 + return channel.admins.findIndex((user) => user.ftId === userId) !== -1 } async isUser (id: number, userId: number): Promise { @@ -160,10 +160,10 @@ export class ChatService { where: { id }, relations: { users: true } }) - if (channel == null) { + if (channel === null) { throw new NotFoundException(`Channel #${id} not found`) } - return channel.users.findIndex((user) => user.ftId === userId) != -1 + return channel.users.findIndex((user) => user.ftId === userId) !== -1 } async isBanned (id: number, userId: number): Promise { @@ -171,10 +171,10 @@ export class ChatService { where: { id }, relations: { banned: true } }) - if (channel == null) { + if (channel === null) { throw new NotFoundException(`Channel #${id} not found`) } - return channel.banned.findIndex((user) => user.ftId === userId) != -1 + return channel.banned.findIndex((user) => user.ftId === userId) !== -1 } async getMuteDuration (id: number, userId: number): Promise { @@ -182,16 +182,14 @@ export class ChatService { where: { id }, relations: { muted: true } }) - if (channel == null) { + if (channel === null) { throw new NotFoundException(`Channel #${id} not found`) } const mutation: number[] | undefined = channel.muted.find( (mutation) => mutation[0] === userId ) - if (mutation == null) { - return 0 - } + if (mutation == null) return 0 return mutation[1] } } diff --git a/back/volume/src/chat/entity/channel.entity.ts b/back/volume/src/chat/entity/channel.entity.ts index f6ead93..384f8d7 100644 --- a/back/volume/src/chat/entity/channel.entity.ts +++ b/back/volume/src/chat/entity/channel.entity.ts @@ -28,7 +28,7 @@ export default class Channel { password: string @BeforeInsert() - async hashPassword () { + async hashPassword (): Promise { if (this.password === '') return this.password = await bcrypt.hash( this.password, diff --git a/back/volume/src/chat/entity/connection.entity.ts b/back/volume/src/chat/entity/connection.entity.ts index afe45e8..b188175 100644 --- a/back/volume/src/chat/entity/connection.entity.ts +++ b/back/volume/src/chat/entity/connection.entity.ts @@ -1,10 +1,4 @@ -import { - Column, - Entity, - JoinColumn, - OneToOne, - PrimaryGeneratedColumn -} from 'typeorm' +import { Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from 'typeorm' import Channel from './channel.entity' import User from 'src/users/entity/user.entity' diff --git a/back/volume/src/users/entity/user.entity.ts b/back/volume/src/users/entity/user.entity.ts index a52ce7f..e9cb7db 100644 --- a/back/volume/src/users/entity/user.entity.ts +++ b/back/volume/src/users/entity/user.entity.ts @@ -2,13 +2,10 @@ import { Entity, PrimaryGeneratedColumn, Column, - OneToMany, ManyToMany, JoinTable } from 'typeorm' -import Message from 'src/chat/entity/message.entity' -import Channel from 'src/chat/entity/channel.entity' import Result from 'src/pong/entity/result.entity' @Entity() diff --git a/back/volume/src/users/users.controller.ts b/back/volume/src/users/users.controller.ts index 4ade093..8a3a286 100644 --- a/back/volume/src/users/users.controller.ts +++ b/back/volume/src/users/users.controller.ts @@ -11,16 +11,16 @@ import { Res, StreamableFile, BadRequestException, - Redirect + Redirect, + Delete } from '@nestjs/common' import { FileInterceptor } from '@nestjs/platform-express' import { diskStorage } from 'multer' -import { type User } from "./entity/user.entity"; -import { UsersService } from "./users.service"; -import { UserDto, AvatarUploadDto } from "./dto/user.dto"; -import { PongService } from "src/pong/pong.service"; +import { type User } from './entity/user.entity' +import { UsersService } from './users.service' +import { UserDto, AvatarUploadDto } from './dto/user.dto' import { AuthenticatedGuard } from 'src/auth/42-auth.guard' import { Profile42 } from 'src/auth/42.decorator' @@ -35,24 +35,33 @@ import { join } from 'path' export class UsersController { constructor (private readonly usersService: UsersService) {} - @Post('block/:id') + @Get('block/:id') @UseGuards(AuthenticatedGuard) - @Post("block/:id") - async blockUser(@Profile42() profile :Profile, @Param('id') id:number) { - const user = await this.usersService.findUser(id) as User - user.blocked.push((await this.usersService.findUser(+profile.id)) as User) - this.usersService.save(user) + async blockUser ( + @Profile42() profile: Profile, + @Param('id') id: number + ): Promise { + const user = await this.usersService.findUser(profile.id) + const target = await this.usersService.findUser(id) + if (user === null || target === null) { + throw new BadRequestException('User not found') + } + user.blocked.push(target) + await this.usersService.save(user) } - @Post('unblock/:id') + @Delete('block/:id') @UseGuards(AuthenticatedGuard) - @Post("unblock/:id") - async unblockUser(@Profile42() profile :Profile, @Param('id') id:number) { - const user = await this.usersService.findUser(id) as User - user.blocked = user.blocked.filter((usr: User) => { + async unblockUser ( + @Profile42() profile: Profile, + @Param('id') id: number + ): Promise { + const user = await this.usersService.findUser(profile.id) + if (user === null) throw new BadRequestException('User not found') + user.blocked = user.blocked.filter((usr: User) => { return usr.id !== id }) - this.usersService.save(user) + await this.usersService.save(user) } @Get('all') @@ -100,10 +109,10 @@ export class UsersController { } }) ) - @ApiConsumes("multipart/form-data") + @ApiConsumes('multipart/form-data') @ApiBody({ - description: "A new avatar for the user", - type: AvatarUploadDto, + description: 'A new avatar for the user', + type: AvatarUploadDto }) async changeAvatar ( @Profile42() profile: Profile, diff --git a/back/volume/src/users/users.module.ts b/back/volume/src/users/users.module.ts index f0cf838..f4f5190 100644 --- a/back/volume/src/users/users.module.ts +++ b/back/volume/src/users/users.module.ts @@ -4,7 +4,6 @@ import { User } from './entity/user.entity' import { UsersController } from './users.controller' import { UsersService } from './users.service' import { PongModule } from 'src/pong/pong.module' -import { ChatModule } from 'src/chat/chat.module' @Module({ imports: [forwardRef(() => PongModule), TypeOrmModule.forFeature([User])], diff --git a/back/volume/src/users/users.service.ts b/back/volume/src/users/users.service.ts index 6db23a3..39c91f3 100644 --- a/back/volume/src/users/users.service.ts +++ b/back/volume/src/users/users.service.ts @@ -46,7 +46,7 @@ export class UsersService { }) } }) - this.getLeaderboard() + await this.getLeaderboard() } async findUser (ftId: number): Promise { @@ -125,7 +125,9 @@ export class UsersService { let r = 0 ret.forEach((usr) => { usr.rank = r++ - this.usersRepository.save(usr) + this.usersRepository.save(usr).catch((err) => { + console.log(err) + }) usr.socketKey = '' }) return ret diff --git a/docker-compose.yml b/docker-compose.yml index c2e86d3..d36268d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,4 +34,4 @@ services: - ./postgres:/var/lib/postgresql/data networks: [transcendence] restart: always - env_file: .env \ No newline at end of file + env_file: .env diff --git a/front/volume/src/App.svelte b/front/volume/src/App.svelte index 16cd502..c0a742f 100644 --- a/front/volume/src/App.svelte +++ b/front/volume/src/App.svelte @@ -244,4 +244,4 @@ outline: none; box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.25); } - \ No newline at end of file + diff --git a/front/volume/src/Auth.ts b/front/volume/src/Auth.ts index 137f52d..cc783a5 100644 --- a/front/volume/src/Auth.ts +++ b/front/volume/src/Auth.ts @@ -11,7 +11,7 @@ export const API_URL = `http://${import.meta.env.VITE_HOST}:${ import.meta.env.VITE_BACK_PORT }`; -export async function getUser(bypass: boolean = false) { +export async function getUser() { const res = await fetch(API_URL + "/users", { method: "get", mode: "cors", diff --git a/front/volume/src/components/Channels.svelte b/front/volume/src/components/Channels.svelte index 2f71ad3..8533cff 100644 --- a/front/volume/src/components/Channels.svelte +++ b/front/volume/src/components/Channels.svelte @@ -14,10 +14,13 @@ - -
+
-
- { #each chatMessages as message } -

- { #if !blockedUsers.filter((user) => user.username == message.author).length } - openProfile(message.author)} - on:keydown = {() => openProfile(message.author)} - style = "cursor: pointer;" - > - { message.author } - : {message.text} +

+ {#each chatMessages as message} +

+ {#if !blockedUsers.filter((user) => user.username == message.author).length} + openProfile(message.author)} + on:keydown={() => openProfile(message.author)} + style="cursor: pointer;" + > + {message.author} + : {message.text} {/if}

{/each}
- { #if showProfileMenu } -
-
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - { #if !blockedUsers.filter((user) => user.username = selectedUser).length } - - {:else } - - {/if} -
  • -
  • -
-
+ {#if showProfileMenu} +
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + {#if !blockedUsers.filter((user) => (user.username = selectedUser)).length} + + {:else} + + {/if} +
  • +
  • +
+
{/if} -
- - + + +
- - { #if showChatMembers } + + {#if showChatMembers}
-
+ />
    - { #each chatMembers as member } + {#each chatMembers as member}
  • - { member.username } - - - - - + {member.username} + + + + +

  • {/each} @@ -351,7 +420,7 @@ import type User from "./Profile.svelte"; } button { - background-color: #6B8E23; + background-color: #6b8e23; color: #ffffff; border: none; border-radius: 5px; @@ -396,4 +465,4 @@ import type User from "./Profile.svelte"; li:last-child { margin-bottom: 0; } - \ No newline at end of file + diff --git a/front/volume/src/components/Friends.svelte b/front/volume/src/components/Friends.svelte index 14ce234..dd62aa7 100644 --- a/front/volume/src/components/Friends.svelte +++ b/front/volume/src/components/Friends.svelte @@ -123,7 +123,8 @@ color: #e8e6e3; } - h2, h3 { + h2, + h3 { color: #e8e6e3; } @@ -133,7 +134,8 @@ max-height: 200px; } - input[type="text"], button { + input[type="text"], + button { background-color: #198754; border: none; color: #e8e6e3; @@ -168,4 +170,4 @@ button { flex-shrink: 0; } - \ No newline at end of file + diff --git a/front/volume/src/components/Leaderboard.svelte b/front/volume/src/components/Leaderboard.svelte index 3683151..50374da 100644 --- a/front/volume/src/components/Leaderboard.svelte +++ b/front/volume/src/components/Leaderboard.svelte @@ -101,4 +101,4 @@ table tbody tr:nth-child(odd) { background-color: rgba(255, 255, 255, 0.1); } - \ No newline at end of file + diff --git a/front/volume/src/components/MatchHistory.svelte b/front/volume/src/components/MatchHistory.svelte index d9f43c1..b6a08d5 100644 --- a/front/volume/src/components/MatchHistory.svelte +++ b/front/volume/src/components/MatchHistory.svelte @@ -14,12 +14,6 @@ import { onMount } from "svelte"; export let username: string = "Global"; - function formatDate(str: string) { - const splitT = str.split("T"); - const splitDate = splitT[0].split("-"); - const splitDot = splitT[1].split("."); - return `${splitDate[1]}/${splitDate[2]}-${splitDot[0]}`; - } let page: number = 1; let data: Array = []; let newBatch: Array = []; @@ -159,4 +153,4 @@ p { color: #e8e6e3; } - \ No newline at end of file + diff --git a/front/volume/src/components/NavBar.svelte b/front/volume/src/components/NavBar.svelte index fe2d214..7e79019 100644 --- a/front/volume/src/components/NavBar.svelte +++ b/front/volume/src/components/NavBar.svelte @@ -1,5 +1,9 @@