Microsoft-ui-xaml: ์ œ์•ˆ: WinUI 3 ๋…น ์ง€์›

์— ๋งŒ๋“  2020๋…„ 05์›” 20์ผ  ยท  14์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: microsoft/microsoft-ui-xaml

Rust๋Š” ์ ์  ์ธ๊ธฐ๋ฅผ ์–ป๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ DirectX 12๋ฅผ ๊ตฌ๋™ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ „์ฒด ํ™”๋ฉด ๋ชจ๋“œ์—์„œ๋งŒ ๋˜๋Š” ์—”์ง€๋‹ˆ์–ด๊ฐ€ ์—”์ง€๋‹ˆ์–ด๋ฅผ ์œ„ํ•ด ๋งŒ๋“  ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋…น์— ๋Œ€ํ•œ WinUI3 ์ง€์›์„ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„๋Œ€์ ์ด๊ณ  ์„ธ๋ จ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๋…น ์•ฑ์„ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‚ด๋ถ€์ ์œผ๋กœ ๋…น์˜ ๋ชจ๋“  ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์—”์ง€๋‹ˆ์–ด์™€ ๋งˆ์ผ€ํŒ…์„ ํ–‰๋ณตํ•˜๊ฒŒ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์ด ์กฐํ•ฉ์„ ์ƒ์—…์šฉ ์•ฑ์— ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

feature proposal

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

winrt-rs ๋Š” ์—ฐ๊ฒฐ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ•„์š”ํ•œ ์ข…์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๊ณ  Hello World๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ช…์‹œ์ ์ธ winui3-rs ํฌ๋ ˆ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  14 ๋Œ“๊ธ€

์–ธ์–ด ๋งคํ•‘์€ ์ด๋ฏธ ์ž‘์—… ์ค‘์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค: https://github.com/microsoft/winrt-rs

winrt-rs ๋Š” ์—ฐ๊ฒฐ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ•„์š”ํ•œ ์ข…์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๊ณ  Hello World๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ช…์‹œ์ ์ธ winui3-rs ํฌ๋ ˆ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ winrt-rs ๊ฐ€ ์•ˆ์ •์ ์ด๊ธฐ ๋•Œ๋ฌธ์— (์•„๋งˆ๋„) ์ฐจ๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ @kennykerr

Rust winrt ํฌ๋ ˆ์ดํŠธ๋Š” VS ํ™•์žฅ ๋ฐ NuGet ์ง€์›์„ ํ†ตํ•ด C++/WinRT ์— ํ•„์ ํ•˜๋Š” ์–ธ์–ด ํ”„๋กœ์ ์…˜ ๋ฐ ํŒจํ‚ค์ง• ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ๊ฒƒ์ด ์˜ค๋Š˜๋‚  Rust/WinRT ์—์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๊ณง Xaml ์ƒ˜ํ”Œ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋‚ด ๋ชฉ๋ก์— ์žˆ์Šต๋‹ˆ๋‹ค. Rust์—์„œ ์ž์‹ ๋งŒ์˜ Xaml ์ปจํŠธ๋กค ๋นŒ๋“œ๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด ์•„์ง ๊ฐˆ ๊ธธ์ด ๋ฉ€์ง€๋งŒ, ์ด๋ฏธ ๊ธฐ๋ณธ Xaml ์•ฑ์„ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์™„์ „ํ•œ ์œ ํ˜• ์‹œ์Šคํ…œ ์ง€์›์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์—ด์‹ฌํžˆ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋ฌด์—‡์„ ์ฐพ๊ณ  ์žˆ๋Š”์ง€ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด Xaml ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ „ํ†ต์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์ข…๋ฅ˜์— ๋Œ€ํ•œ ์ง€์›์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ ์ด์ƒ์ด๋ผ๊ณ  ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‚ด๊ฐ€ ํ‹€๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋„ ์ด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜๋Š” ๊ฑธ ์ •๋ง ๋ณด๊ณ  ์‹ถ์–ด.
Rust๊ฐ€ ์ ์  ์ธ๊ธฐ๋ฅผ ์–ป๊ณ  ์žˆ๋Š” ๋ฐ๋Š” ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •๋ง ์ข‹์€ ์–ธ์–ด์ด๋ฉฐ Microsoft๋Š” Windows์˜ ์ผ๋ถ€๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ Rust๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๋งํ•˜๊ธฐ๊นŒ์ง€ ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋…น์„ ์ค‘์‹ฌ์œผ๋กœ ์•ฑ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌ์ถ•ํ•œ๋‹ค๋Š” ๊ฒƒ์€ C++ ์ˆ˜์ค€์˜ ์„ฑ๋Šฅ์„ ์˜๋ฏธํ•˜์ง€๋งŒ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ํ›จ์”ฌ ์ข‹๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๋ฒ„๊ทธ๊ฐ€ ์ ์Šต๋‹ˆ๋‹ค.

@kennykerr "๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋ฌด์—‡์„ ์ฐพ๊ณ  ์žˆ๋Š”์ง€ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค."
์ฃผ๋œ ๋™๊ธฐ๋Š” ๊ฐ€๋Šฅํ•œ ํ•œ ๋…น์Šฌ์ง€ ์•Š๊ฒŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž‘์„ฑ๋˜๋Š” ์ „๋ฌธ์ ์ธ ๋ชจ์–‘์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์–ด์ฉ์ง€ ์–ธ์–ด ๋””์ž์ธ ๋Šฅ๋ ฅ์ด ๋›ฐ์–ด๋‚œ ์‚ฌ๋žŒ์ด ์˜ˆ์ˆ ์  UI ์œ„์ ฏ ๋””์ž์ธ ๋Šฅ๋ ฅ์ด ๋›ฐ์–ด๋‚œ ์‚ฌ๋žŒ๊ณผ ๊ฐ™์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ WIN UI 3์šฉ ๋…น์˜ ๋ž˜ํผ๋Š” ๋ถ„ํ• ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ˆ˜ํ–‰ํ•œ ์˜ˆ๊ฐ€ ์—†๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ง„์ž… ์žฅ๋ฒฝ์ด ๋†’์Šต๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์„ ํ•จ๊ป˜ ๋ฌถ๋Š” hello world ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์‹ค์ œ๋กœ ๋›ฐ์–ด๋“ค๊ณ  ์‹ถ์–ดํ•˜๊ณ  ์Šค์Šค๋กœ ํŒŒ์ƒํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ WIN UI ์•ฑ ๋‚ด์˜ ํŒจ๋„์—์„œ WIN UI 3 ๋ฐ DirectX12๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋…น์˜ ์˜ˆ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. ๋…น์„ ๋ฐฐ์šฐ๊ธฐ ์‹œ์ž‘ํ•œ์ง€ โ€‹โ€‹์–ผ๋งˆ ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ์–ด๋ ค์›Œ ๋ณด์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์„ ์‹œ์ž‘ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ €๋Š” Rust์—์„œ ๋” ๋งŽ์€ GUI ์ž‘์—…์„ ํ•˜๊ธฐ๋ฅผ ๊ณ ๋Œ€ํ–ˆ์Šต๋‹ˆ๋‹ค. WinUI๋Š” ๋‹จ์ง€ ๊ทธ๊ฒƒ์„ ์‹œํ—˜ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ์žฅ์†Œ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

@kennykerr "๊ธฐ์ˆ ์„ ํ•จ๊ป˜ ๋ฌถ๋Š” hello world ์˜ˆ์ œ๊ฐ€ ์žˆ์œผ๋ฉด ๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์‹ค์ œ๋กœ ๋›ฐ์–ด๋“ค๊ณ  ์‹ถ์–ดํ•˜๊ณ  ์Šค์Šค๋กœ ํŒŒ์ƒํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค."

Hello World๋Š” UI๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ ํ•  ์ผ ์•ฑ์€ ๋ช‡ ๊ฐ€์ง€ ๊ฐ„๋‹จํ•œ ์ƒํ˜ธ ์ž‘์šฉ๊ณผ ์กฐ๊ฐ์ด ์„œ๋กœ ์–ด๋–ป๊ฒŒ ๋งž๋Š”์ง€ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

.Net MAUI ์— ๋Œ€ํ•œ ๋ฐœํ‘œ๋ฅผ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. WinUI์— ๊ทธ ๊ธฐ๋ฐ˜์ด ์–ผ๋งˆ๋‚˜ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์ €์—๊ฒŒ ์˜๊ฐ์€ vgtk๋ผ๋Š” Rust GUI ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์˜ต๋‹ˆ๋‹ค.
https://bodil.lol/vgtk/

์ด ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ตฌ๋ฌธ์€ ์„ ์–ธ์  UI๋ฅผ ๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•œ React์˜ jsx ๊ตฌ๋ฌธ์—์„œ ํฌ๊ฒŒ ์˜๊ฐ์„ ๋ฐ›์•˜์œผ๋ฉฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์€ ์˜ค๋Š˜๋‚  ์ธ๊ธฐ ์žˆ๋Š” MVU ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค.

์•ฑ์„ ์„ ์–ธํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

fn view(&self) -> VNode<Model> {
    gtk! {
        <Application::new_unwrap(None, ApplicationFlags::empty())>
            <Window border_width=20 on destroy=|_| Message::Exit>
                <HeaderBar title="inc!" show_close_button=true />
                <Box spacing=10 halign=Align::Center>
                    <Label label=self.counter.to_string() />
                    <Button label="inc!" image="add" always_show_image=true
                            on clicked=|_| Message::Inc />
                </Box>
            </Window>
        </Application>
    }
}

์ด๊ฒƒ์€ jsx์— ๋งค์šฐ ๊ฐ€๊น์ง€๋งŒ WinUI์— ์‚ฌ์šฉํ•˜๊ธฐ์— ์™„๋ฒฝํ•œ XAML์— ํ›จ์”ฌ ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. Rust์˜ ์ด ๊ตฌ๋ฌธ์€ Rust์˜ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ๊ธฐ๋Šฅ์— ์˜ํ•ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

์š”์ฆ˜์€ ์ด๋Ÿฐ UI ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋Œ€์„ธ์ธ ๊ฒƒ ๊ฐ™๊ณ , WinUI๋กœ ๋Ÿฌ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋ ค๋ฉด ์ด ๊ธฐ์ฐจ๋„ ํƒ€์•ผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์•„์š”. ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์ž‘์—…์€ ์ˆ˜์—†์ด ์ˆ˜ํ–‰๋˜์—ˆ์œผ๋ฉฐ Microsoft์—์„œ WinUI์šฉ ์ž‘์—…์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์•„๋งˆ๋„ ๋งค์šฐ ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๊ฒƒ์€ Rust GUI ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ๊ฐ„์ ˆํžˆ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ UI ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•œ ์ข‹์€ ๊ธฐํšŒ์ผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์ด๋Š” ์ด ๋ฌธ์ œ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€ XAML์—๋Š” '๋ถ€๋ถ„ ํด๋ž˜์Šค' ์ง€์›์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งž๋‚˜์š”? ๋”ฐ๋ผ์„œ UI ์š”์†Œ์— ์ปจํŠธ๋กค์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Rust๊ฐ€ ์ด๊ฒƒ์„ ์ง€์›ํ•ฉ๋‹ˆ๊นŒ? ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋กœ ๋ชจ๋ฐฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  ํ”ผ๋“œ๋ฐฑ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ๊ณ„์† ํ•˜์„ธ์š”.

@suleyth - Xaml API์—๋Š” ๋ถ€๋ถ„ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” Xaml ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” C# ์–ธ์–ด์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. C++์™€ ์ด์ œ Rust์˜ ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” ํ•ด๋‹น ์–ธ์–ด์— ๋” ์ž์—ฐ์Šค๋Ÿฌ์šด ์™„์ „ํžˆ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ํƒ๊ตฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋„ค, ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋Š” Rust์—์„œ ์ด๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. winrt-rs ์—์„œ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
ํŽธ์ง‘: winui๋กœ ๋…น์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ๋กœ๋“œ๋งต์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

WinUI ํŒ€์„ ๋Œ€๋ณ€ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ Rust์— ๋Œ€ํ•œ ์ง€์›์˜ ๋Œ€๋ถ€๋ถ„์€ Rust/WinRT ์–ธ์–ด ํ”„๋กœ์ ์…˜( winrt-rs )์—์„œ ๋‚˜์˜ต๋‹ˆ๋‹ค. ํŠนํžˆ, ์ €๋Š” ์ด์ œ Rust์—์„œ COM ๋ฐ WinRT ์œ ํ˜•์„ ์ •์˜ํ•˜๊ณ  ๊ตฌํ˜„ ํ•˜๊ธฐ ์œ„ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์™„์ „ํ•œ Xaml ํ†ตํ•ฉ์„ ์œ„ํ•œ ์ฃผ์š” ์ „์ œ ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค. ์ค€๋น„๊ฐ€ ๋˜๋ฉด Rust์—์„œ Xaml ๋ฐ”์ธ๋”ฉ ์ง€์›์„ ๋ณด๋‹ค ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์กฐ๋ช…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰