묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
홈 화면 화살표 버튼 눌렀을때 1월에서 2월로 안 가고 3월로 갑니다 나머지 달은 잘 작동합니다.
안녕하세요 또 이렇게 질문을 해서 죄송합니다. 마지막 강의까지 다 듣고 배포까지 했는데 갑자기 홈 화면에 오른 화살표를 클릭을 하면 지금 1월 인데 누르면 3월로 이동 됩니다. 그런데 1월에서 2월 넘어갈때만 그래요 뒤로 가는건 잘 작동합니다. 홈 강의 다시 보고 틀린거 있나 확인했는데 못 찾아서 이렇게 연락드려요 https://github.com/jeain/Diary
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
playground 오류 10-06-one-to-one
다음과 같이 playground에서 mutation한 결과 "Cannot return null for non-nullable field Product.productSalesLocation." 오류 메시지가 뜹니다. mutation안의 반환값으로 product의 column만 받을 때는 오류 없이 작동되었는데 productSalesLocation의 column을 반환하려 하면 다음과 같이 오류가 뜹니다.위 사진을 보시면 DBeaver에 product와 saleslocation에 생성한 값이 잘 입력되었지만product table에서 productSalesLocationID가 NULL값으로 되어있습니다.이 부분에 연관된 코드가 여러 파일로 나뉘어져있어 코드 어느 부분을 확인해야 하는지 알려주시면 해당 코드 캡처본을 보내드리겠습니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
token 재발급문제
강의 잘듣고 있습니다. 유투브에서 flutter 영상만 보다가 평소 관심있었던 nest 까지 이어왔습니다(자바스크립트, 타입스크립트 그리고 nestjs까지)토큰 관련 마지막강의해서 refresh token 이 만료되면 다시 ....refresh end point 로 요청을 보내서 다시 refresh 토큰을 받는다 말씀하셨는데요... 기간 만료된 refresh 토큰을 보내도 되는건가요? 아님 그 기능을 따로 구현해야 하는건가요?
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
SPA, MPA, 리액트 Hooks 등의 개념 어디서 참고하시나요?
강사님 SPA, MPA, SSR , CSR과 리액트 Hooks 등의 개념에 대해 찾다보면 참고 문서와 링크 없고, 내용에 틀린부분도 있어보이는 블로그가 종종 있더라구요. 이러한 경우 강사님은 어디서 주로 찾으시는지 궁금합니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
followeeCount, followerCount 증가, 감소를 위한 메소드 일반화하기 코드 공유
increment(conditions: FindOptionsWhere<Entity>, propertyPath: string, value: number | string)먼저 increment메소드의 propertyPath 부분이 특정 Model의 프로퍼티를 추론 하지 않고 string으로 박혀 있는게 마음에 들지 않아서 대상이 되는 프로퍼티 필드 명을 추론 하게 작성 했습니다.// users.service.ts async incrementFollowerCount( userId: number, fieldName: keyof Pick<UsersModel, 'followerCount' | 'followeeCount'>, incrementCount: number, qr?: QueryRunner, ) { const usersRepository = this.getUsersRepository(qr); await usersRepository.increment( { id: userId, }, fieldName, incrementCount, ); }1. fieldName: 어떤 프로퍼티를 증가, 감소를 할것인지 특정하는 파라미터2. incrementCount : 몇 증가 시킬것인지 증가 value// users.service.ts async decrementFollowerCount( userId: number, fieldName: keyof Pick<UsersModel, 'followerCount' | 'followeeCount'>, decrementCount: number, qr?: QueryRunner, ) { const usersRepository = this.getUsersRepository(qr); await usersRepository.decrement( { id: userId, }, fieldName, decrementCount, ); }contoller에서 사용하기// users.controller.ts @Patch('follow/:id/confirm') @UseInterceptors(TransactionInterceptoer) async patchFollowConfirm( @User() user: UsersModel, @Param('id', ParseIntPipe) followerId: number, @QueryRunnerDecorator() qr: QueryRunner, ) { await this.usersService.confirmFollow(followerId, user.id); await this.usersService.incrementFollowerCount( user.id, 'followerCount', 1, qr, ); await this.usersService.incrementFollowerCount( followerId, 'followeeCount', 1, qr, ); return true; } @Delete('follow/:id') @UseInterceptors(TransactionInterceptoer) async deleteFollow( @User() user: UsersModel, @Param('id', ParseIntPipe) followeeId: number, @QueryRunnerDecorator() qr: QueryRunner, ) { await this.usersService.deleteFollow(user.id, followeeId); await this.usersService.decrementFollowerCount( user.id, 'followerCount', 1, qr, ); await this.usersService.decrementFollowerCount( followeeId, 'followeeCount', 1, qr, ); return true; }filedName 파라미터를 특정 프로퍼티만 올 수 있게 자동완성 잘됩니다.팔로워 confirm 되면 나의 follower 증가 + 상대방 followee 증가팔로워 삭제 되면 나의 follower 감소 + 상대방 followee 감소await this.usersService.incrementFollowerCount( followerId, 'followeeCount', 1, qr, );userId가 오는 파라미터 자리에 user.id가 아닌 followerId가 들어간 이유는 followeeCount를 증가 해야 되기 때문이다. 즉, 팔로워를 수락 했으면 나의 followerCount를 증가 시키고 상대방 followeeCount를 증가 시켜야 되기 때문에, 삭제 했을때도 같은 원리[결과]2번 사용자가 1번 사용자를 팔로워하고, 1번 사용자가 팔로워를 수락 했을때
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
0은 양수가 아닌거아닌가요? a >= 0 ?이렇게하면 0도 양수가 되는데..
🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
vue3 모달창 트랜지션
<template> <transition appear name="modal"> <div class="modal-mask"> <div class="modal-wrapper"> <div class="modal-container"> <!-- Modal Header --> <div class="modal-header"> <slot name="header"> default header </slot> </div> <!-- Modal Body --> <div class="modal-body"> <slot name="body"> default body </slot> </div> <!-- Modal footer --> <!-- <div class="modal-footer"> <slot name="footer"> default footer <button class="modal-default-button" @click="$emit('close')"> OK </button> </slot> </div> --> </div> </div> </div> </transition> </template> <style scoped> .modal-mask { position: fixed; z-index: 9998; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: table; transition: opacity 0.3s ease; } .modal-wrapper { display: table-cell; vertical-align: middle; } .modal-container { width: 300px; margin: 0px auto; padding: 20px 30px; background-color: #fff; border-radius: 2px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33); transition: all 0.3s ease; font-family: Helvetica, Arial, sans-serif; } .modal-header { margin-top: 0; color: #42b983; } .modal-body { margin: 20px 0; } .modal-default-button { float: right; } .modal-enter-from { opacity: 0; } .modal-leave-active { opacity: 0; } .modal-enter-from .modal-container, .modal-leave-active .modal-container { -webkit-transform: scale(1.1); transform: scale(1.1); } </style>vue3인데 모달창 띄울 때 애니매이션 효과가 잘 작동하는데 왜 닫을 때는 작동을 안하는 지 잘 모르겠어요<AlertModal v-if="showModal" @close="showModal = false"> <!-- you can use custom content here to overwrite default content --> <template v-slot:header> <h3>경고! <span class="closeModalBtn" @click="showModal = false">x</span></h3> </template> <template v-slot:body> 아무것도 입력하지 않으셨습니다. </template> <!-- <template v-slot:footer> copy right </template> --> </AlertModal>참고로 vue3에서는 slot을 template 태그 안에 v-slot으로 적어야 한다해서 이렇게 작성했어요
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
2.1 테스트 구동 실패
안녕하세요 2.1 class 단위 테스트를 작성하고 `npm run test`로 테스트를 구동 했을 때, 다음과 같이 테스트를 실패하고 있습니다. `nvm use`, 'npm ci'를 모두 마친 상황인데, 어떤 문제를 해결해야 할까요? 혹시나 싶어 스토리북을 구동했을 때는, 문제 없이 scripts 명령어를 입력했을 때 실행이 되는 것을 확인할 수 있었습니다.!github branch의 unit-test-example을 pull 받아서 진행했습니다!운영체제: Windows 11 import { screen } from '@testing-library/react'; import React from 'react'; import TextField from '@/components/TextField'; import render from '@/utils/test/render'; it('className Prop으로 설정한 css class가 적용된다.', async () => { // Arrange - 테스트를 위한 환경 만들기 // -> className을 지닌 컴포넌트 렌더링 await render(<TextField className="my-class" />); // Act - 테스트할 동작 발생 // -> 렌더링에 대한 검증이기 때문에 이 단계는 생략 // -> 클릭이나 메서드 호출, prop 변경 등등에 대한 작업이 여기에 해당 합니다. // Assert - 올바른 동작이 실행되었는지 검증 // -> 렌덩링 이후 DOM에 해당 class가 존재하는지 검증 // TextField는 placeholder 요소가 있습니다. // vitest의 expect 함수를 사용하여 기대 결과를 검증 expect( screen .getByPlaceholderText('텍스트를 입력해 주세요.') .toHaveClass('my-class'), ); }); FAIL src/components/tests/TextField.spec.jsx [ src/components/tests/TextField.spec.jsx ] Error: C:\Users\js953\Desktop\Github\fe-test\test-example-shopping-mall\src\components\tests\TextField.spec.jsx 21:3 error Expect must have a corresponding matcher call vitest/valid-expect ✖ 1 problem (1 error, 0 warnings) ❯ formatError node_modules/vite/dist/node/chunks/dep-abb4f102.js:43916:46 ❯ TransformContext.error node_modules/vite/dist/node/chunks/dep-abb4f102.js:43912:19 ❯ TransformContext.transform node_modules/vite-plugin-eslint/dist/index.mjs:1:1989 ❯ Object.transform node_modules/vite/dist/node/chunks/dep-abb4f102.js:44206:30 ❯ loadAndTransform node_modules/vite/dist/node/chunks/dep-abb4f102.js:54851:29 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ Test Files 1 failed (1) Tests no tests Start at 12:45:37 Duration 1.63s (transform 743ms, setup 883ms, collect 0ms, tests 0ms, environment 408ms, prepare 109ms) FAIL Tests failed. Watching for file changes... press h to show help, press q to quit ```Test result not found. If you set `vitest.commandLine` please check: Did you set `vitest.commandLine` to `run` mode? (This extension requires `watch` mode to get the results from Vitest api) Does it have the ability to append extra arguments? (For example it should be `yarn test --` rather than `yarn test`) Are there tests with the same name? Can you run vitest successfully on this file? Does it need custom option to run? Vitest output: DEV v0.33.0 C:/Users/js953/Desktop/Github/fe-test/test-example-shopping-mall API started at http://127.0.0.1:60930 ❯ src/components/tests/TextField.spec.jsx (0 test)
-
미해결초보자도 만들 수 있는 스크롤 인터렉션. 1편 자바스크립트
반응형에 대해 질문이 있습니다 !
안녕하세요 깡코딩님, 다름이 아니라 모바일 뿐만아니라 pc도 반응형이 필요할텐데 맥북프로같은 경우는 해상도가 크더라구요 ..이럴경우 처음부터 크게 작업하고 미디어 쿼리로 점점 작게 진행해야하는걸까요???1920까지만 신경쓰고 최소로 280까지만 신경썼는데 이렇게 큰게 나오니 또 조정을 해야하나 싶습니다.
-
미해결처음 만난 리액트(React)
npm install을 하면 취약점 문제가 뜹니다.
npm install --save styled-componentsup to date, audited 1782 packages in 5s117 packages are looking for funding run npm fund for details131 vulnerabilities (1 low, 104 moderate, 22 high, 4 critical)To address issues that do not require attention, run: npm audit fixTo address all issues (including breaking changes), run: npm audit fix --forceRun npm audit for details.라고 뜨면서 안되는데 어떻게 해결하나요..?ㅜ
-
미해결[JS] Phaser 게임 제작 - 뱀파이어 서바이벌 클론
npm start 에러나와 문의드립니다.
https://github.com/photonstorm/phaser3-project-template 위 url로 이동해서 다운받았는데 아무래도 지난주에 소스가 수정된 것 같습니다. 다운 후 npm start 시 에러가 발생합니다. 어떻게 해야 할까요?url도 다른 소스로 이동하는 것 같습니다. - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
미해결제주코딩베이스캠프 Code Festival: JavaScript 100제
71번 깊이 우선 탐색 질문드립니다.
안녕하세요. 71번 문제의 출력엔 E D F A C B로 되어 있습니다. 그 앞에 깊이 우선 탐색을 그림으로 해설 하실때에도 E D F A C B로 설명해주시는데 하지만 정답 코드로는 E A B C D F 로 나오는데 해설에는 단지 출발 방향만 다르지 같다고 하시는데 이해가 되질 않아 문의드립니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
@IsPublic 어노테이션으로 RefreshTokenGuard에서 RefreshToken 검증을 하기 위한 코드 공유
// is-public.const.ts export enum IsPublicEnum { ISPUBLIC = 'ISPUBLIC', ISREFRESHTOKEN = 'ISREFRESHTOKEN', }// is-public.decorator.ts import { SetMetadata } from '@nestjs/common'; import { IsPublicEnum } from '../const/is-public.const'; export const ISPUBLIC_KEY = 'is_public'; export const IsPublic = (status: IsPublicEnum) => SetMetadata(ISPUBLIC_KEY, status);// bearer-token.guard.ts @Injectable() export class BearerTokenGuard implements CanActivate { constructor( private readonly authService: AuthService, private readonly usersService: UsersService, public readonly reflector: Reflector, ) {} async canActivate(context: ExecutionContext): Promise<boolean> { const req = context.switchToHttp().getRequest(); const requiredPublic = this.reflector.getAllAndOverride(ISPUBLIC_KEY, [ context.getHandler(), context.getClass, ]); if (requiredPublic) { req.requiredPublic = requiredPublic; } if (requiredPublic === IsPublicEnum.ISPUBLIC) { return true; } const rawToken = req.headers['authorization']; if (!rawToken) throw new UnauthorizedException('토큰이 없습니다!'); const token = this.authService.extractTokenFromHeader(rawToken, true); const result = await this.authService.verifyToken(token); const user = await this.usersService.getUserByEmail(result.email); req.user = user; req.token = token; req.tokenType = result.type; return true; } }추가된 코드if (requiredPublic) { req.requiredPublic = requiredPublic; }requiredPublic 있을때만 req에 담아줌.추가된 코드if (requiredPublic === IsPublicEnum.ISPUBLIC) { return true; }IsPublic일때만 return true 즉, ISREFRESHTOKEN 일때는 아래 로직들이 정상적으로 실행됨.// bearer-token.guard.ts @Injectable() export class AccessTokenGuard extends BearerTokenGuard { async canActivate(context: ExecutionContext): Promise<boolean> { await super.canActivate(context); const req = context.switchToHttp().getRequest(); if ( req.requiredPublic === IsPublicEnum.ISPUBLIC || IsPublicEnum.ISREFRESHTOKEN ) { return true; } if (req.tokenType !== 'access') { throw new UnauthorizedException('Access Token이 아닙니다.'); } return true; } }추가된 코드if (req.requiredPublic === IsPublicEnum.ISPUBLIC || IsPublicEnum.ISREFRESHTOKEN) { return true; }req.requiredPublic이 ISPUBLIC이거나 ISREFRESHTOKEN이면 return true로 global accessTokenGuard return true로 빠져나옴.// bearer-token-guard.ts @Injectable() export class RefreshTokenGuard extends BearerTokenGuard { async canActivate(context: ExecutionContext): Promise<boolean> { await super.canActivate(context); const req = context.switchToHttp().getRequest(); if (req.tokenType !== 'refresh') { throw new UnauthorizedException('Refresh Token이 아닙니다.'); } return true; } }변경 사항 없음. 왜냐하면 위에서 정상적으로 refreshToken을 verify하고 req에 값이 담겼기 때문에 RefreshTokenGuard가 정상적으로 실행 되어야함. auth.controller에 적용하기@Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @IsPublic(IsPublicEnum.ISREFRESHTOKEN) @Post('token/access') @UseGuards(RefreshTokenGuard) postTokenAccess(@Headers('authorization') rawToken: string) { ... } @IsPublic(IsPublicEnum.ISREFRESHTOKEN) @Post('token/refresh') @UseGuards(RefreshTokenGuard) postTokenRefresh(@Headers('authorization') rawToken: string) { ... } @IsPublic(IsPublicEnum.ISPUBLIC) @Post('login/email') @UseGuards(BasicTokenGuard) postLoginEmail(@Headers('authorization') rawToken: string) { ... } @IsPublic(IsPublicEnum.ISPUBLIC) @Post('register/email') postRegisterEmail(@Body() body: RegisterUserDto) { ... } }
-
해결됨Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
깃헙 권한 요청드립니다.
- 인프런 아이디: sju02135@hanmail.net- 인프런 이메일: sju02135@hanmail.net- 깃허브 아이디: sju02135@hanmail.net- 깃허브 username: minsung1129
-
미해결입문자를 위한 자바스크립트 기초 강의
생성자 함수 관련 질문 드립니다
생성자 함수로 객체를 생성하기 위해선, new연산을 통해 객체를 반환해야한다고 하셨는데, 객체를 반환을 해야 객체가 생성이 되는건가요? 아니면 객체가 생성이 되고 반환이 되는건가요? 생성과 반환이라는 개념이 약간 헷갈리는 것 같습니다. Date() 는 함수인가요? 객체인가요? 그냥 생성자 함수를 반환하는 것과 생성자 함수로 객체를 생성해서 반환하는 것의 어떤 차이가 있나요? 아직 제 눈에는 둘이 비슷해보여서요.. 함수를 반환하는 것과 객체를 반환하는 것의 목적이 많이 다른건지 설명해주시면 정말 감사하겠습니다.. Dog 함수를 콘솔로 출력시,console.log(Dog)--> Dog 함수를 반환new 연산 + Dog 함수호출문을 콘솔로 출력시,console.log(new Dog())--> Dog 객체 반환
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
별거 아니긴 한데 nest-cli 로 만들때
nest cli로 resource 만들때 경로를 / 넣어주면 아래에 바로 생성 됩니다.nest g resource posts/comments이렇게 하면 posts폴더 아래에 comments가 생깁니다!
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
가드와 미들웨어 질문드립니다.
안녕하세요.,강의 잘 보고있습니다. 가드랑 미들웨어 용도를 이렇게 이해하면 좋을까요? 1.가드:-특정 컨트롤러로 들어온 파라매터, 혹은 context데이터를 가공하거나 검증하고 싶을때 2.미들웨어:-특정 규칙을 가진 패쓰 혹은 컨트롤러 전체에 데이터를 검증하고 싶을때 아주 맨 처음에 저는 token 을 검증하는 BearerTokenGuard이 가드보다는 middleware 로 가는것이 맞지 않나 싶었는데요.context.user 데이터를 controller 에 내려주기 위해IsCommentMine Guard 처럼 다른 가드로 유저데이터를 넘겨줘야하는 경우가 있어서가드로 사용하는것으로 이해했는데 맞을까요?(그리고 middleware 로는 불가능한걸까요?)
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
update comment 관련
안녕하세요.update comment 관련 두가지 질문이 있습니다.update(patch) 에서는 query runner를사용하지 않아도 되나요?update 시에repository.update 가 아닌 save 를 사용한 이유가 있을까요?항상 강의 잘 보고있습니다.감사합니다!
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
섹션5의 2번째 강의 질문-setMap 비동기 처리 이유
제가 이해한 바가 맞는지 질문드립니다.질문1. 마커를 찍을 시: 1. 주소를 좌표로 변환 2. 해당 좌표를 마커로 지도에 표시의 처리 순서가 보장되어야 하므로, async await를 이용한 비동기처리를 해준 것이 맞나요?질문 2. 비동기처리를 해주기 전에도 마커는 잘 찍혔는데, 그 말은 즉 주소를 좌표로 변환하고-> 좌표를 마커로 표시하는 순서로 코드가 실행되었다는 것 아닌가요? 그렇다면 api가 비동기적으로 이루어진다는 말이 잘 와닿지 않아서 질문드립니다.감사합니다!
-
해결됨Vue 3 시작하기
파일이름을 소문자로시작하는건 어떤경우인가요
파일이름을 소문자로 시작해서 하는건 상관없는건가요?그리고 컴포넌트를 가져올때 상대경로로 보통 가져오신다고했는데 다른폴더에있는 컴포넌트를 가져올때 ../ 이런식으로도 찾는게 맞나요?