Skip to content

Commit 96da180

Browse files
authored
Merge pull request #46 from rustfs/feature/translate-korean-docs
Feature/translate korean docs
2 parents fa91d21 + dc8eba7 commit 96da180

37 files changed

Lines changed: 1569 additions & 81 deletions

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1. 如果在目标语言下不存在对应的文件,则需要翻译,加入 todolist.
1313
1. 如果已经存在对应的文件,则检查内容是否需要更新。
1414
1. 开始翻译中文对应的内容为目标语言,如果是外链,代码,则不翻译,并且删除在中文目录下没有的仅在目标语言目录中存在的文件。
15+
1. 记住:是需要翻译全部中文内容为目标语言,不要仅翻译一部分。
1516
1. 图片则直接从中文对应的目录拷贝。
1617
1. 其他非文本内容(如音频、视频等)则直接从中文对应的目录拷贝。
1718
1. 翻译完成后请仔细检查,确保所有内容都已翻译。
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: "RustFS 액세스 키 관리"
3+
description: "RustFS 액세스 키의 생성, 사용 및 삭제."
4+
---
5+
6+
# 액세스 키
7+
8+
RustFS 액세스 키는 RustFS 시스템의 핵심 자격 증명으로, 신원 인증과 작업 권한 부여에 사용되며 API 및 SDK 환경에서 매우 유용합니다. 이 장에서는 RustFS 액세스 키의 생성과 삭제에 대해 설명합니다.
9+
10+
전제 조건:
11+
12+
- 사용 가능한 RustFS 인스턴스. 설치는 [설치 가이드](../../installation/index.md)를 참조하세요.
13+
14+
## 액세스 키 생성
15+
16+
1. RustFS UI 콘솔에 로그인합니다.
17+
1. 왼쪽 탐색 패널에서 **액세스 키**를 선택합니다.
18+
1. 액세스 키 페이지에서 오른쪽 상단의 **액세스 키 추가**를 클릭합니다.
19+
1. 키의 **만료 시간, 이름 및 설명**을 입력한 후 **제출**을 클릭합니다.
20+
1. (선택사항이지만 권장) 표시되는 액세스 키 페이지에서 **복사** 또는 **내보내기**를 선택하여 나중에 사용할 수 있도록 액세스 키를 저장합니다.
21+
22+
![access key list page](images/access_token_creation.png)
23+
24+
## 액세스 키 삭제
25+
26+
1. RustFS UI 콘솔에 로그인합니다.
27+
1. 왼쪽 탐색 패널에서 **액세스 키**를 선택합니다.
28+
1. 액세스 키 페이지에서 삭제할 액세스 키를 선택합니다.
29+
1. 액세스 키 오른쪽의 **삭제** 버튼을 선택하거나 오른쪽 상단의 **선택한 항목 삭제**를 선택하여 액세스 키를 삭제합니다.
30+
31+
![access key deletion](images/access_token_deletion.png)
189 KB
Loading
173 KB
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: "RustFS IAM 관리"
3+
description: "RustFS에서 사용자/사용자 그룹/정책/AK&SK 등의 내용을 자세히 설명합니다."
4+
---
5+
6+
본 장의 내용:
7+
8+
- 사용자 관리
9+
- 사용자 그룹 관리
10+
- 정책 관리
11+
- 버킷 정책
12+
- AK/SK

docs/ko/concepts/architecture.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: "RustFS 아키텍처"
3+
description: "RustFS 아키텍처 소개"
4+
---
5+
6+
# RustFS 아키텍처
7+
8+
RustFS는 잘 알려진 AWS S3와 유사한 객체 저장 시스템입니다. MinIO의 대안 제품으로서 RustFS는 MinIO의 간결하고 경량이며 확장 가능하고 우아한 아키텍처를 참조했습니다.
9+
10+
객체는 문서, 비디오, PDF 파일 등이 될 수 있습니다. 객체를 저장하기 위해 MinIO는 데이터를 저장, 액세스 및 관리할 수 있는 확장 가능하고 유연하며 효율적인 솔루션을 제공합니다. AWS S3 API와의 호환성은 AWS S3 기반 애플리케이션과의 원활한 통합을 가능하게 합니다.
11+
12+
아키텍처 다이어그램은 다음과 같습니다:
13+
14+
![RustFS 아키텍처 다이어그램](./images/s2-1.png)
15+
16+
이것은 RustFS의 기본 아키텍처로, 분산 그리드는 여러 노드를 사용하여 단일 작업을 수행하는 컴퓨터 아키텍처입니다. 노드들은 네트워크를 통해 서로 연결되어 있어 서로 통신할 수 있습니다.
17+
18+
## 일관성 설계
19+
20+
분산 및 단일 머신 모드에서 모든 읽기/쓰기 작업은 read-after-write 일관성 모델을 엄격하게 준수합니다.
21+
22+
## RustFS의 중요한 개념들
23+
24+
**Object(객체)**: RustFS에 저장되는 기본 객체로, 파일, 바이트 스트림, 무엇이든...
25+
26+
**Bucket(버킷)**: Object를 저장하는 논리적 공간입니다. 각 Bucket 간의 데이터는 서로 격리됩니다. 클라이언트에게는 파일을 저장하는 최상위 폴더와 같습니다.
27+
28+
**Drive(드라이브)**: 데이터를 저장하는 디스크로, RustFS 시작 시 매개변수로 전달됩니다. RustFS의 모든 객체 데이터는 Drive에 저장됩니다.
29+
30+
**Set(세트)**: Drive들의 집합으로, 분산 배포는 클러스터 규모에 따라 자동으로 하나 이상의 Set으로 나뉩니다. 각 Set의 Drive들은 서로 다른 위치에 분산됩니다. 하나의 객체는 하나의 Set에 저장됩니다. (Set의 조합을 **Strips(스트라이프)**라고도 부릅니다).
31+
32+
따라서 아키텍처 설계 및 장비 배포 전에 주의해야 할 사항은:
33+
34+
1. 하나의 객체는 하나의 Set에 저장됩니다;
35+
36+
2. 하나의 클러스터는 여러 Set으로 나뉩니다;
37+
38+
3. 하나의 Set에 포함된 Drive 수는 고정되어 있으며, 기본적으로 시스템이 클러스터 규모에 따라 자동으로 계산합니다;
39+
40+
4. 하나의 Set 내의 Drive들은 가능한 한 서로 다른 노드에 분산됩니다;
41+
42+
## 특별 감사
43+
44+
전통적인 분산 저장 아키텍처에는 Master 노드, MetaData 노드, Data Node 노드가 반드시 존재해야 합니다. 그러나 이러한 모드 설계는 사용자의 배포를 매우 복잡하게 만듭니다. 동시에 분산 저장에 대한 풍부한 관리 경험이 없다면 메타데이터가 손실될 경우 데이터 손실의 위험이 있습니다.
45+
46+
모든 노드는 동일한 계층 관계의 노드로, 아키텍처 설계를 크게 단순화하고 메타데이터 손실을 걱정할 필요가 없으며, 단일 명령으로 시작할 수 있습니다.
47+
48+
우아함, 단순함, 신뢰성을 잃지 않으며, RustFS는 MinIO와 동일한 아키텍처 설계를 채택했습니다.
49+
50+
전 세계 사용자들에게 편의를 제공하고 S3 프로토콜을 널리 보급한 MinIO의 아키텍처 개념에 감사드립니다.

docs/ko/concepts/comparison.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: RustFS와 다른 스토리지 제품 비교
3+
description: RustFS와 주류 객체 스토리지 제품의 비교
4+
---
5+
6+
# RustFS와 다른 스토리지 제품 비교
7+
8+
| 매개변수 | Ceph | MinIO | RustFS |
9+
| - | - | - | - |
10+
| 개발 언어 | C++ | Go | Rust |
11+
| 오픈소스 라이선스 | GPL-2.0, LGPL-2.1, LGPL-3.0 | AGPL-3.0 | Apache-2.0 |
12+
| 메타데이터 센터 || x | x |
13+
| 블록 스토리지 || x | x |
14+
| 파일 스토리지 || x | x |
15+
| 아키텍처 | 중량 아키텍처 설계 | 경량 아키텍처 설계 | 경량 아키텍처 설계 |
16+
| 커뮤니티 활성도 ||||
17+
| 라이선스 친화도 || 낮음 | 우수 |
18+
| 성능 | 하드웨어와 구성에 의존 | 고성능, 저지연, 고속 읽기/쓰기와 대규모 객체 액세스에 적합 | 고성능, 저지연, 고속 읽기/쓰기와 대규모 객체 액세스에 적합 |
19+
| 파일 프로토콜 | S3, RBD, CephFS 등 다양한 프로토콜 지원 | S3 | S3 |
20+
| 사용 난이도 | 높음 | 낮음 | 낮음 |
21+
| 확장성 | EB 급 | EB 급 | EB 급 |
22+
| 하드웨어 요구사항 | 하드웨어 리소스 점유율 높음 | 리소스 점유율 중간, 하드웨어 요구사항 중간 | 리소스 점유율 낮음, 하드웨어 요구사항 낮음 |
23+
| 메모리 안정성 | 안정 | 고동시성에서 떨림 높음 | 안정 |
24+
| 확장 | 난이도 높음 | 난이도 낮음 | 난이도 낮음 |
25+
| 리밸런싱 | 리소스 점유율 높음 | 리소스 점유율 낮음 | 리소스 점유율 낮음 |
26+
| 상업적 지원 ||||
27+
28+
## 글로벌 객체 스토리지 아키텍처 파벌
29+
30+
현재 전 세계의 분산 객체 스토리지 제품은 주로 두 개의 파벌로 나뉩니다:
31+
32+
1. 메타데이터 센터가 있는 것, 메타데이터 센터가 있는 대표적인 제품: Ceph;
33+
34+
2. 메타데이터 센터가 없는 것, 메타데이터 센터가 없는 대표적인 제품: RustFS와 MinIO.
35+
36+
메타데이터 센터 유무의 장단점 비교는 다음과 같습니다:
37+
38+
| 특성 | 메타데이터 센터 있음 | 메타데이터 센터 없음 |
39+
| - | - | - |
40+
| 아키텍처 특징 | 전용 메타데이터 서버 또는 센터가 메타데이터를 통합 관리 | 메타데이터가 스토리지 노드에 분산되어 있어 전용 메타데이터 서버 없음 |
41+
| 메타데이터 관리 | 효율적인 중앙 집중 관리, 빠른 조회 및 업데이트 속도 | 메타데이터 분산 저장, 단일점 병목 회피 |
42+
| 단일점 장애 | 메타데이터 서버가 단일점 장애점이 될 수 있어 추가 고가용성 방안 필요 | 단일 노드 장애 위험 없음 |
43+
| 배포 복잡도 | 배포 및 유지보수 복잡, 전문 운영 기술 필요 | 배포 및 유지보수 상대적으로 간단, 클라우드 네이티브 및 컨테이너화 환경에 적합 |
44+
| 성능 문제 | 고동시성 환경에서 메타데이터 서버가 성능 병목이 될 수 있음 | 소파일 지원 시 더 많은 IOPS 점유 |
45+
| 일반적인 시나리오 | 파일 시스템(예: Lustre, CephFS) 및 복잡한 메타데이터가 필요한 시나리오 | 객체 스토리지(RustFS, MinIO) 및 대규모 분산 시스템 |
46+
47+
## 스토리지 속도에 대해
48+
49+
RustFS와 MinIO는 동일한 설계를 채택했으며, 전체적인 속도는 스토리지 노드의 네트워크와 하드 디스크 속도에 따라 결정됩니다. 평가 결과 RustFS는 323 GB/s의 읽기 속도와 183 GB/s의 쓰기 속도에 달할 수 있습니다.
50+
51+
RustFS와 MinIO는 전 세계에서 속도가 유일하게 선도적인 두 분산 객체 스토리지 제품이라고 할 수 있습니다. 동일한 구성에서 이들의 속도는 Ceph보다 훨씬 빠릅니다.

docs/ko/concepts/index.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: "RustFS 아키텍처 설계와 핵심 개념 상세 해설"
3+
description: "본 문서는 객체 스토리지에서 자주 사용되는 용어를 소개하여 사용자가 객체 스토리지를 빠르게 이해할 수 있도록 합니다"
4+
---
5+
6+
본 장에서 포함하는 내용은:
7+
8+
- [RustFS 소개](./introduction.md)
9+
- [RustFS 설계 아키텍처](./architecture.md)
10+
- [주류 스토리지 제품 비교](./comparison.md)
11+
- [자주 사용하는 용어](./glossary.md)
12+
- [핵심 개념](./principle/index.md)
13+
- [사용 제한](./limit.md)

docs/ko/concepts/introduction.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
title: "RustFS란 무엇인가?"
3+
description: "RustFS는 Apache2 라이선스로 배포되는 오픈소스 분산 객체 스토리지 솔루션입니다."
4+
---
5+
6+
# RustFS란 무엇인가?
7+
8+
RustFS는 단순하고 효율적이며 분산된 객체 스토리지입니다.
9+
동시에 효율적이고 오픈소스이며 자유로운 객체 스토리지 솔루션이기도 합니다. S3 프로토콜과 100% 호환되며 Apache2 라이선스로 배포되는 오픈소스 소프트웨어입니다. RustFS는 현재 전 세계에서 가장 인기 있고 메모리 안전한 언어인 Rust 언어로 작성되었습니다.
10+
이는 전 세계 우수한 엔지니어들이 참여하고 기여한 상업적 친화적인 분산 객체 스토리지 제품으로, RustFS는 비우호적인 오픈소스 라이선스를 가진 많은 객체 스토리지 제품을 대체할 수 있습니다.
11+
12+
RustFS는 곧 상용 애플리케이션에서 정식으로 오픈소스화되어 전 세계적으로 출시되며, 전 세계의 스토리지 비용 절감과 데이터 보안 향상에 기여할 것입니다.
13+
14+
## 운영체제 및 CPU 지원
15+
16+
Linux, Unix, Windows, MacOS, FreeBSD, Docker, 심지어 에지 게이트웨이에서도 거의 모든 CPU와 운영체제에서 RustFS를 실행할 수 있습니다.
17+
CPU 아키텍처 지원: X86, ARM 등 다양한 CPU 아키텍처.
18+
19+
## RustFS의 특징
20+
21+
- **S3 호환**: S3 프로토콜과 100% 호환되며, 빅데이터, 데이터 레이크, 백업 소프트웨어, 이미지 처리 소프트웨어, 산업 생산 소프트웨어와의 우수한 호환성;
22+
- **분산**: RustFS는 분산 객체 스토리지이므로 다양한 요구사항을 충족;
23+
- **상업적 친화적**: RustFS는 100% 오픈소스 소프트웨어이며 Apache v2.0 라이선스로 배포되므로 상업적 사용에 적합;
24+
- **고속**: Rust 개발 언어의 성능은 C 언어의 속도에 무한히 가까움. 따라서 RustFS의 성능은 매우 강력;
25+
- **안전**: RustFS는 메모리 안전한 언어 Rust로 작성되었으므로 RustFS는 100% 안전;
26+
- **크로스 플랫폼**: RustFS는 Windows, macOS, Linux에서 작동;
27+
- **확장 가능**: RustFS는 커스텀 플러그인을 지원하므로 다양한 요구사항을 충족;
28+
- **커스터마이징 가능**: 오픈소스 특성으로 인해 다양한 플러그인을 커스터마이징할 수 있으므로 다양한 요구사항을 충족;
29+
- **클라우드 네이티브**: RustFS는 Docker 등의 방식으로 배포를 지원하여 클라우드 네이티브 환경에서 빠른 배포 가능.
30+
31+
## RustFS 가치관
32+
33+
전 인류의 데이터 보안 향상과 스토리지 비용 절감을 지원합니다.
34+
35+
## RustFS의 비전
36+
37+
전 세계 모든 개인 AI 에이전트가 RustFS를 사용하여 데이터를 저장할 수 있도록 합니다.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
title: "삭제 부호화 원리"
3+
description: "RustFS는 차세대 분산 객체 스토리지 시스템으로, 혁신적인 아키텍처 설계와 메모리 안전 특성을 통해 클라우드 스토리지 분야에서 독특한 장점을 보여줍니다. 그 핵심 혁신 중 하나는 Reed-Solomon 삭제 부호화(Reed-Solomon Erasure Coding)의 깊이 있는 적용입니다."
4+
---
5+
6+
# 삭제 부호화 원리
7+
8+
## 1. 핵심 알고리즘과 핵심 알고리즘 적용 범위
9+
10+
Reed-Solomon 코드(Reed-Solomon Code, RS 코드)는 유한체 대수 구조를 기반으로 한 삭제 부호화(Erasure Code)로, **효율적인 데이터 복구 능력****유연한 중복 구성** 덕분에 여러 분야에 광범위하게 적용됩니다. 다음은 기술 분야와 실제 적용 두 차원에서 그 핵심 적용 시나리오를 자세히 설명합니다:
11+
12+
### 1.1. 분산 스토리지 시스템 (RustFS 등)
13+
- **데이터 샤딩과 중복**
14+
원본 데이터를 `k`개 샤드로 분할하여 `m`개의 검사 샤드를 생성합니다(총 `n=k+m`). ≤`m`개의 샤드가 손실되어도 데이터를 복구할 수 있습니다.
15+
**예시**: RS(10,4) 전략은 4개의 노드가 동시에 손실되어도 허용합니다(스토리지 이용률 71%). 3복제본(33%)에 비해 50% 스토리지 공간을 절약합니다.
16+
17+
- **장애 복구 메커니즘**
18+
**가우스 소거법** 또는 **고속 푸리에 변환(FFT)** 알고리즘을 통해 살아남은 샤드를 이용해 손실된 데이터를 재구축하며, 복구 시간은 네트워크 대역폭에 반비례합니다.
19+
20+
- **동적 조정 능력**
21+
실행 시 `(k,m)` 매개변수 조정을 지원하여 다양한 스토리지 계층(핫/웜/콜드 데이터)의 신뢰성 요구사항에 적응합니다.
22+
23+
### 1.2. 통신 전송
24+
- **위성 통신**
25+
심우주 채널에서 장시간 지연, 높은 오류율 문제를 처리합니다(예: NASA 화성 탐사선은 RS(255,223) 코드를 사용하여 16바이트/코드워드의 오류 정정 능력 달성).
26+
27+
- **5G NR 표준**
28+
제어 채널에서 RS 코드와 CRC 검사를 결합하여 중요한 시그널링의 안정적인 전송을 보장합니다.
29+
30+
- **무선 센서 네트워크**
31+
멀티홉 전송에서 누적 패킷 손실 문제를 해결하며, 일반적인 구성인 RS(6,2)는 33%의 데이터 손실을 허용합니다.
32+
33+
### 1.3. 디지털 미디어 스토리지
34+
- **QR 코드**
35+
RS 코드를 사용하여 내결함성 레벨을 조정합니다(L7%, M15%, Q25%, H30%). 일부 영역이 손상되어도 정확한 디코딩이 가능합니다.
36+
37+
- **블루레이 디스크**
38+
RS(248,216) 코드 결합 교차 인터리빙을 채택하여 긁힘으로 인한 연속 버스트 오류를 수정합니다.
39+
40+
- **DNA 데이터 스토리지**
41+
합성 생물 분자 체인에 RS 검사를 추가하여 염기 합성/시퀀싱 오류에 저항합니다(예: Microsoft 실험 프로젝트에서 RS(4,2) 사용).
42+
43+
## 2. 삭제 부호화 기초 개념
44+
45+
### 2.1 스토리지 중복의 진화
46+
```rust
47+
// 전통적인 3복제본 스토리지
48+
let data = "object_content";
49+
let replicas = vec![data.clone(), data.clone(), data.clone()];
50+
```
51+
전통적인 다중 복제본 방안은 스토리지 효율성이 낮다는 문제가 있습니다(스토리지 이용률 33%). 삭제 부호화 기술은 데이터를 블록으로 분할한 후 검사 정보를 계산하여 스토리지 효율성과 신뢰성의 균형을 달성합니다.
52+
53+
### 2.2 핵심 매개변수 정의
54+
- **k**: 원본 데이터 샤드 수
55+
- **m**: 검사 샤드 수
56+
- **n**: 총 샤드 수 (n = k + m)
57+
- **복구 임계값**: 임의의 k개 샤드로 원본 데이터 복구 가능
58+
59+
| 방안 유형 | 중복도 | 장애 허용도 |
60+
|------------|----------|------------|
61+
| 3복제본 | 200% | 2노드 |
62+
| RS(10,4) | 40% | 4노드 |
63+
64+
## 3. Reed-Solomon 코드 수학적 원리
65+
66+
### 3.1 유한체(Galois Field) 구축
67+
GF(2^8) 필드(256개 원소)를 채택하여 다음을 만족합니다:
68+
```math
69+
α^8 + α^4 + α^3 + α^2 + 1 = 0
70+
```
71+
생성원 다항식은 `0x11D`이고, 이진수로는 `100011101`에 해당합니다.
72+
73+
### 3.2 인코딩 행렬 구축
74+
반데르몬드 행렬 예시 (k=2, m=2):
75+
```math
76+
G = \begin{bmatrix}
77+
1 & 0 \\
78+
0 & 1 \\
79+
1 & 1 \\
80+
1 & 2
81+
\end{bmatrix}
82+
```
83+
84+
### 3.3 인코딩 과정
85+
데이터 벡터 D = [d₁, d₂,..., dk]
86+
인코딩 결과 C = D × G
87+
88+
**생성 다항식 보간법**:
89+
k개 데이터 포인트를 통과하는 다항식 구축:
90+
```math
91+
p(x) = d_1 + d_2x + ... + d_kx^{k-1}
92+
```
93+
검사값 계산:
94+
```math
95+
c_i = p(i), \quad i = k+1,...,n
96+
```
97+
98+
## 4. RustFS에서의 엔지니어링 구현
99+
100+
### 4.1 데이터 샤딩 전략
101+
```rust
102+
struct Shard {
103+
index: u8,
104+
data: Vec<u8>,
105+
hash: [u8; 32],
106+
}
107+
108+
fn split_data(data: &[u8], k: usize) -> Vec<Shard> {
109+
// 샤딩 로직 구현
110+
}
111+
```
112+
- 동적 샤드 크기 조정 (64 KB-4 MB)
113+
- 해시 검사값은 Blake3 알고리즘 사용
114+
115+
### 4.2 병렬 인코딩 최적화
116+
```rust
117+
use rayon::prelude::*;
118+
119+
fn rs_encode(data: &[Shard], m: usize) -> Vec<Shard> {
120+
data.par_chunks(k).map(|chunk| {
121+
// SIMD 가속 행렬 연산
122+
unsafe { gf256_simd::rs_matrix_mul(chunk, &gen_matrix) }
123+
}).collect()
124+
}
125+
```
126+
- Rayon 기반 병렬 컴퓨팅 프레임워크
127+
- AVX2 명령어 집합을 사용한 유한체 연산 최적화
128+
129+
### 4.3 디코딩 복구 플로우
130+
```mermaid
131+
sequenceDiagram
132+
Client->>Coordinator: 데이터 읽기 요청
133+
Coordinator->>Nodes: 샤드 상태 조회
134+
alt 충분한 가용 샤드 있음
135+
Nodes->>Coordinator: k개 샤드 반환
136+
Coordinator->>Decoder: 디코딩 시작
137+
Decoder->>Client: 원본 데이터 반환
138+
else 샤드 부족
139+
Coordinator->>Repairer: 복구 플로우 트리거
140+
Repairer->>Nodes: 살아남은 샤드 수집
141+
Repairer->>Decoder: 데이터 재구축
142+
Decoder->>Nodes: 새 샤드 쓰기
143+
end
144+
```

0 commit comments

Comments
 (0)