diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index fd8c44d086..391c46b4fe 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -32,19 +32,3 @@ jobs:
- name: Build and check with Gradle
run: ./gradlew check
-
- - name: Perform IO redirection test (*NIX)
- if: runner.os == 'Linux'
- working-directory: ${{ github.workspace }}/text-ui-test
- run: ./runtest.sh
-
- - name: Perform IO redirection test (MacOS)
- if: always() && runner.os == 'macOS'
- working-directory: ${{ github.workspace }}/text-ui-test
- run: ./runtest.sh
-
- - name: Perform IO redirection test (Windows)
- if: always() && runner.os == 'Windows'
- working-directory: ${{ github.workspace }}/text-ui-test
- shell: cmd
- run: runtest.bat
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f69985ef1f..d603fa10e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,9 @@ bin/
/text-ui-test/ACTUAL.txt
text-ui-test/EXPECTED-UNIX.TXT
+
+/data/logs/
+/text-ui-test/data/logs
+
+/data/main/user.json
+/text-ui-test/data/main/user.json
\ No newline at end of file
diff --git a/README.md b/README.md
index 698b938529..0f88bed369 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Duke project template
+# E-Duke-8
This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it.
diff --git a/build.gradle b/build.gradle
index b0c5528fb5..1052b4a885 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,6 +12,8 @@ repositories {
dependencies {
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0'
+ // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
+ compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
}
test {
@@ -29,12 +31,14 @@ test {
}
application {
- mainClassName = "seedu.duke.Duke"
+ mainClassName = "seedu.eduke8.Eduke8"
}
shadowJar {
- archiveBaseName = "duke"
+ archiveBaseName = "eduke8"
archiveClassifier = null
+ sourceSets.main.resources.srcDirs = [ "src/" ]
+ sourceSets.main.resources.includes = [ "**/*.json" ]
}
checkstyle {
@@ -43,4 +47,7 @@ checkstyle {
run{
standardInput = System.in
-}
+ enableAssertions = true
+ sourceSets.main.resources.srcDirs = [ "src/" ]
+ sourceSets.main.resources.includes = [ "**/*.json" ]
+}
\ No newline at end of file
diff --git a/data/test/blank_question_description.json b/data/test/blank_question_description.json
new file mode 100644
index 0000000000..1a92e1b8ea
--- /dev/null
+++ b/data/test/blank_question_description.json
@@ -0,0 +1,30 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/blank_topic_title.json b/data/test/blank_topic_title.json
new file mode 100644
index 0000000000..a24fbc01fc
--- /dev/null
+++ b/data/test/blank_topic_title.json
@@ -0,0 +1,30 @@
+[
+ {
+ "topic": "",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/duplicate_topics.json b/data/test/duplicate_topics.json
new file mode 100644
index 0000000000..6be07a1263
--- /dev/null
+++ b/data/test/duplicate_topics.json
@@ -0,0 +1,104 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is abstraction?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "topic": "first topic",
+ "questions": [
+ {
+ "description": "How do you name classes?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is the appropriate indentation?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/empty.json b/data/test/empty.json
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/data/test/five_options.json b/data/test/five_options.json
new file mode 100644
index 0000000000..02c49f2f3f
--- /dev/null
+++ b/data/test/five_options.json
@@ -0,0 +1,108 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ },
+ {
+ "description": "E",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is abstraction?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "topic": "Style",
+ "questions": [
+ {
+ "description": "How do you name classes?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is the appropriate indentation?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/missing_key.json b/data/test/missing_key.json
new file mode 100644
index 0000000000..38f3705a18
--- /dev/null
+++ b/data/test/missing_key.json
@@ -0,0 +1,5 @@
+[
+ {
+ "missing": "keys"
+ }
+]
\ No newline at end of file
diff --git a/data/test/no_correct_answer.json b/data/test/no_correct_answer.json
new file mode 100644
index 0000000000..b5308d32a1
--- /dev/null
+++ b/data/test/no_correct_answer.json
@@ -0,0 +1,104 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is abstraction?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "topic": "Style",
+ "questions": [
+ {
+ "description": "How do you name classes?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is the appropriate indentation?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/save.json b/data/test/save.json
new file mode 100644
index 0000000000..57a624ee8b
--- /dev/null
+++ b/data/test/save.json
@@ -0,0 +1 @@
+[{"notes":[{"description":"First Note","text":"Test"},{"description":"Second Note","text":"Test"}],"questions":[{"correct":true,"bookmarked":true,"hint":true,"description":"First question description."}],"topic":"First_Topic"},{"notes":[{"description":"First Note","text":"Test"},{"description":"Second Note","text":"Test"}],"questions":[],"topic":"Second_Topic"}]
\ No newline at end of file
diff --git a/data/test/three_options.json b/data/test/three_options.json
new file mode 100644
index 0000000000..ab96ef4eba
--- /dev/null
+++ b/data/test/three_options.json
@@ -0,0 +1,100 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is abstraction?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "topic": "Style",
+ "questions": [
+ {
+ "description": "How do you name classes?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is the appropriate indentation?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/topics.json b/data/test/topics.json
new file mode 100644
index 0000000000..926cd731f0
--- /dev/null
+++ b/data/test/topics.json
@@ -0,0 +1,104 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is abstraction?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "topic": "Style",
+ "questions": [
+ {
+ "description": "How do you name classes?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is the appropriate indentation?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/two_correct_answer.json b/data/test/two_correct_answer.json
new file mode 100644
index 0000000000..ac127baabc
--- /dev/null
+++ b/data/test/two_correct_answer.json
@@ -0,0 +1,104 @@
+[
+ {
+ "topic": "First Topic",
+ "questions": [
+ {
+ "description": "What is encapsulation?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is abstraction?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "topic": "Style",
+ "questions": [
+ {
+ "description": "How do you name classes?",
+ "hint": "check the textbook",
+ "explanation": "because option A is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": true
+ },
+ {
+ "description": "B",
+ "correct": false
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ },
+ {
+ "description": "What is the appropriate indentation?",
+ "hint": "check the textbook",
+ "explanation": "because option B is the best answer",
+ "options": [
+ {
+ "description": "A",
+ "correct": false
+ },
+ {
+ "description": "B",
+ "correct": true
+ },
+ {
+ "description": "C",
+ "correct": false
+ },
+ {
+ "description": "D",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/data/test/user.json b/data/test/user.json
new file mode 100644
index 0000000000..673b5e5a68
--- /dev/null
+++ b/data/test/user.json
@@ -0,0 +1,34 @@
+[
+ {
+ "notes":[
+ {
+ "description":"First Note",
+ "text":"Test"
+ },
+ {
+ "description":"Second Note",
+ "text":"Test"
+ }
+ ],
+ "questions": [
+ {
+ "correct":true,
+ "bookmarked":true,
+ "hint":true,
+ "description":"First question description."
+ },
+ {
+ "correct":false,
+ "bookmarked":false,
+ "hint":false,
+ "description":"Second question description."
+ }
+ ],
+ "topic":"First_Topic"
+ },
+ {
+ "notes":[],
+ "questions":[],
+ "topic":"Second_Topic"
+ }
+]
\ No newline at end of file
diff --git a/data/test/wrong_format.json b/data/test/wrong_format.json
new file mode 100644
index 0000000000..4435010b3e
--- /dev/null
+++ b/data/test/wrong_format.json
@@ -0,0 +1,3 @@
+{
+ "wrong": "format"
+}
\ No newline at end of file
diff --git a/docs/AboutUs.md b/docs/AboutUs.md
index 0f072953ea..d6630d0884 100644
--- a/docs/AboutUs.md
+++ b/docs/AboutUs.md
@@ -2,8 +2,8 @@
Display | Name | Github Profile | Portfolio
--------|:----:|:--------------:|:---------:
- | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md)
- | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md)
- | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md)
- | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md)
- | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md)
+ | Tang Zhi You | [Github](https://github.com/Zhi-You) | [Portfolio](team/zhi-you.md)
+ | Joseph Abraham | [Github](https://github.com/josephhhhhhhhh) | [Portfolio](team/josephhhhhhhhh.md)
+ | Lim An Qi | [Github](https://github.com/anqi20) | [Portfolio](team/anqi20.md)
+ | Joel Ng Yi Xian| [Github](https://github.com/joelngyx) | [Portfolio](team/joelngyx.md)
+ | Kingston Kuan Jun Xiang | [Github](https://github.com/kstonekuan) | [Portfolio](team/kstonekuan.md)
diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 0ec3db103d..05a2af00f5 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -1,34 +1,612 @@
-# Developer Guide
+# Developer Guide for E-Duke-8
+* Table of Contents
+{:toc}
-## Design & implementation
+
-{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.}
+## 1. Introduction
+### 1.1. Software Overview
-## Product scope
-### Target user profile
+E-Duke-8 (pronounced "Educate") helps CS2113/T students **learn and understand software engineering and [Object-oriented Programming (OOP)](#34-glossary) principles** through a gamified
+platform and enhances their learning experience.
-{Describe the target user profile}
+On this desktop application, CS2113/T students can attempt bite-sized quizzes, through the [Command Line Interface (CLI)](#34-glossary), to test their understanding of the concepts taught, and serves to consolidate key concepts for easy revision.
-### Value proposition
+E-Duke-8, comprises of a Logic component, UI component, Storage component, and Model component. Each component comprises of multiple classes that work in tandem, to fulfil the purpose of our program.
-{Describe the value proposition: what problem does it solve?}
+The purpose of this developer guide is to allow any interested contributors, who wish to develop this learning companion further, understand the inner workings of the program.
+This understanding will enable such contributors to add value to the current code, by improving its performance, level of interaction or capabilities.
-## User Stories
+### 1.2. Setting up
+
+First, fork this repo, and clone the fork into your computer.
+
+You are recommended to use Intellij IDEA to edit the program.
+
+1. **Configure the JDK**: Ensure Intellij is configured to use JDK 11.
+2. **Import the project as a Gradle project**: Choose the option to import the project as a Gradle project when prompted.
+3. **Verify the setup**: Enter some commands to ensure E-Duke-8 functions as expected. Refer to our [User Guide](https://ay2021s1-cs2113t-f12-3.github.io/tp/UserGuide.html) for more information.
+
+
+
+## 2. Design & implementation
+
+### 2.1. Architecture
+
+The high-level design of our program is based on a 3-tier architecture which consists of the Presentation, Application and Database layers. The Logic component, UI component, Storage component, and Model component can be found in each layer as shown in the architecture diagram below.
+
+
+
+
+
+### 2.2. Model Component
+
+The data model is centered around `DisplayableList` objects which hold `Displayable` objects. This implementation
+allows us to create various topics with questions, options, hints and explanations. This was also extended to creating bookmarks and notes.
+
+#### 2.2.1. Design of TopicList
+
+`TopicList` is an ArrayList of type `Displayable`, which is 1 of the 6 interfaces implemented
+in the code for E-Duke-8. As such, many of the commands that manipulate the `TopicList` make
+use of the package `java.util.ArrayList`.
+
+The `TopicList` is used to store `Topic` objects. `Topic` objects themselves implement the interface `Displayable`.
+
+
+
+There is just 1 command that manipulates the `TopicList`, which is `topics`. The `topics` command shows all the
+`Topic` objects in the current `TopicList`.
+
+
+
+#### 2.2.2. Implementation of TopicList
+
+**Listing topics in TopicList:**
+
+This task is performed by the `TopicList.showTopics()` method.
+
+
+
+Step 1: The `parseCommand()` method instantiates a `TopicsCommand` object which then calls the
+ `TopicList.showTopics()` method.
+
+Step 2. The `TopicList.showTopics()` method then calls the method `Ui.printTopicList()`. The
+ current `TopicList` is passed into the called method.
+
+Step 3: The `Ui.printTopicList()` method then prints out the number of questions in each topic,
+ along with the description of each topic in the `TopicList`.
+
+
+
+#### 2.2.3. Design of NoteList
+
+`NoteList` is also an `ArrayList` of type `Displayable`. As such, just like with `TopicList`, many of the commands
+that manipulate the `NoteList` also make use of the package `java.util.ArrayList`.
+
+Each topic has an attribute of type `NoteList`, which contains `Note` objects.
+
+
+
+
+
+#### 2.2.4. Implementation of Notes
+
+There are 3 commands that involve the manipulation of `NoteList` objects. They are: `note add`, which adds a new `Note`
+object, `note delete`, which deletes a `Note` object, and `note list`, which lists out all `Note` objects in a `NoteList` from a
+specified `Topic`. These commands are carried out by the instantiation of a `NoteCommand` object. The `NoteCommand`
+object then performs a task based on the type of command from the user's input. This is reflected in the following
+sequence diagram:
+
+
+
+**Adding a new note:**
+
+This task is performed by the `NoteList.add()` method.
+
+Step 1: The `parseCommand()` method instantiates a `NoteCommand` object which then calls the `Ui.addNoteInteractions()`
+method.
+
+Step 2: The `Ui.printAddNote()` method uses the user's input to create a `Note` object.
+
+Step 3: The `Ui.printAddNote()` method then calls the method `NoteList.add()`, passing the created `Note` object
+into this method. `NoteList.add()` makes use of the package `java.util.ArrayList`, specifically the `ArrayList.add()`
+method, to add the `Note` object into the specified `NoteList` object.
+
+**Listing out all notes in a topic:**
+
+This task is performed by the `Ui.showNotes()` method.
+
+Step 1: The `parseCommand()` method instantiates a `NoteCommand` object which then instantiates an Ui object
+and calls the `Ui.printListNote` method. The topic's `NoteList` object is passed into this method.
+
+Step 2: The `Ui.printListNote` method calls the `Ui.showNotes()` method. The topic's `NoteList` object is passed into
+this method. `Ui.showNotes()` prints out the descriptions and texts of all the `Note` objects in the topic's `NoteList`
+object.
+
+**Deleting a note:**
+
+This task is performed by the `NoteList.delete()` method.
+
+Step 1: The `parseCommand()` method instantiates a `NoteCommand` object which then calls the `Ui.printDeleteNote`
+method. An integer provided by the user's input is passed into this method. This integer is interpreted as the index of
+the `Note` object to be deleted in the specified `NoteList` object.
+
+Step 2: The `NoteList.delete()` method makes use of the `java.util.ArrayList` package, specifically the
+`ArrayList.remove()` method, to delete the specified `Note` object in the specified `NoteList` object.
+
+
+
+#### 2.2.5. Design of Option and OptionList
+
+The `Option` and `OptionList` classes implements the `Displayable` and `DisplayableList` interfaces respectively.
+The `Option` object stores one option of a question while the `OptionList` object stores all 4 options of the same
+question. The class diagram below illustrates the structure of both classes.
+
+The `Option` class implements the `Displayable` interface while the `OptionList` class implements the `DisplayableList` interface. The illustration below shows the class diagram of `Option` and `OptionList`.
+
+
+
+The `Option` object stores the description of one option from a question. It also indicates if the option is the correct answer for the question by using the `isCorrectAnswer` boolean.
+The `OptionList` object stores all 4 options of the same question.
+
+
+
+#### 2.2.6. Implementation of Option and OptionList
+
+An example of when the `Option` and `OptionList` classes are used is when the quiz mode is activated. The quiz requires all the options of a particular question to be printed out.
+
+The diagram below is only an illustration to show the implementation of `Option` and `OptionList` classes, it does not show the full sequence diagram of the `SingleTopicQuiz()` method.
+
+
+
+Step 1. When a quiz is started, the `SingleTopicQuiz()` method will instantiate a `SingleTopicQuiz` object.
+
+Step 2. The `SingleTopicQuiz` object then calls the `Question` class using the `getOptionList()` method. The `Question` class then returns `optionList`.
+
+Step 3. The `SingleTopicQuiz` object then calls the `OptionList` class using the `getInnerList()` method. The `OptionList` class then returns `options` which contains the list of 4 options of a particular question that is shown to the user.
+
+Step 4. The `SingleTopicQuiz` object then calls the `Ui` to print out all 4 options using the `printOption(options.get(i), i+1)` method.
+The `options.get(i)` parameter will get the description of the specific option and the `i+1` parameter will handle the numbering of the options.
+
+
+
+### 2.3. Logic Component
+
+The main application logic, such as provisioning quizzes, is handled by the Logic component. This component also acts as the middleman between the backend and frontend by processing data before passing it to the user interface and parsing user input from the user interface.
+
+#### 2.3.1. Design of Parser
+
+
+
+1. After constructing a new `MenuParser` in the `Eduke8` class, the `parseCommand()` method is used to parse the
+ user command.
+2. This results in a `Command` object, which is executed by `Command` class itself, using the `execute()` method.
+3. The `Ui` object in the `Command` object is used to display the requested information, or to display the required task
+to be completed as per the user input.
+
+It should be made clear that `parseCommand()` returns a new object from the child class of `Command`. The object's exact
+class depends on the input typed into the command line, and so since `parseCommand()` returns all these objects from the
+various specific `Command` classes, the `MenuParser` which has the `parseCommand()` method is dependent on all these
+specific `Command` classes.
+
+
+
+#### 2.3.2. Implementation of MenuParser
+
+Below is the sequence diagram for how the Parser component of `Eduke8` works with commands to show output to the user.
+
+
+
+The command parsing feature is our program’s way of reading the user’s input into the command line. It makes use of a
+single method `parseCommand()` that identifies what command the user is calling for and then calls the command. There are
+two parsers in our program that implements a single `Parser` interface. One parser is for choosing menu options and is
+named `MenuParser`. The other parser is used during quizzes, in order to answer questions or request for hints, and is
+called `QuizParser`. Given below is an example usage scenario of how the command parsing feature works at each step,
+when the user types in input to get help in order to see what commands are available to the user.
+
+Step 1. The user launches the program for the first time. The `MenuParser` will be initialised and awaiting the user’s
+ input to proceed.
+
+Step 2. The user types in "help" into the command line interface and presses enter. This user input “help” is stored as
+ a string and is put into the `parseCommand()` method as a parameter, together with the list of topics. This
+ topic list is not relevant to the help command for now.
+
+Step 3. The user input string is subjected to the `lang.string.trim()` and `lang.string.split()` functions of a string
+ in the Java libraries in order to remove redundant spaces around the input, and to discern the number of words
+ in the input. The `lang.string.split()` function uses a blank space string, “ “, as the delimiter to split the
+ string into its individual components.
+
+Step 4. Each subsequent string separated by a space is stored in a string array `commandArr[]`. The 0th index of the
+ `commandArr[]` array is the first word, the 1st index is the second word, and so on. In this case there is only
+ one word stored in the array, at the 0th index, which is “help”.
+
+Step 5. The string at the 0th index is then used in a switch statement, where each case represents the different menu
+ options available. As such, the contents of the case with reference “help” is run, which is a return statement
+ containing a new `HelpCommand()`. This leads to the execution of the `help` command.
+
+
+
+#### 2.3.3. Design of QuizQuestionsManager
+
+To start a quiz in E-Duke-8, the user will have to give some inputs, and these include the number of questions that he wants to attempt, as well as the topic to get the questions from. Thereafter, questions will be shown to the user one by one until all of them are attempted.
+
+The class diagram given below explains the high-level design of the quiz system in E-Duke-8. Given below it is a quick overview of each component.
+
+
+
+An object of `SingleTopicQuiz` class represents an instance of the quiz in E-Duke-8. Its `numberOfQuestions` attribute and `Topic` object correspond to the user's specified number of questions and topic for the quiz respectively.
+
+The `startQuiz(:Ui)` method call from the `SingleTopicQuiz` object initializes an object of `QuizQuestionsManager`, by passing into its constructor `QuizQuestionsManager(:int, :ArrayList)` the arguments `numberOfQuestions` for its first parameter and an ArrayList of questions from the `Topic` object for its second parameter. The `QuizQuestionsManager` object will then randomly select `numberOfQuestions` questions from the topic the user has chosen, using its `setQuizQuestions(:int, :ArrayList)` method, where the first parameter will take in `numberOfQuestions` and its second parameter will take in the ArrayList of questions from the `Topic` object passed into the `QuizQuestionsManager` object. The questions' selection process will be further explained in the subsequent section on the [Implementation of QuizQuestionsManager](#234-implementation-of-quizquestionsmanager).
+
+After a quiz has started, by making use of `QuizQuestionsManager`'s `getNextQuestion()` and `areAllQuestionsAnswered()` method calls, the `goThroughQuizQuestions(:Ui, :QuizQuestionsManager)` will loop through the questions until the user has answered all of them on the command line interface.
+
+
+
+#### 2.3.4. Implementation of QuizQuestionsManager
+
+As mentioned earlier in the section on the design of the quiz system, a `QuizQuestionsManager` object will randomly select the indicated number of questions from the list of questions in the `Topic` object, and these will form the quiz questions for the user.
+
+The sequence diagram below shows how `QuizQuestionsManager` is implemented to achieve this for the scenario where the user indicates that he wants to attempt 5 questions from the topic on [OOP](#34-glossary), which translates to the `setQuizQuestions(5, questionsInTopic)` call:
+
+
+
+
+`nextInt(5)` is a method call to an object of the `Random` class. It returns a random integer `randomQuestionIndex` where its value is between 0 (inclusive) and the number passed in as argument, 5 in this scenario, exclusive.
+
+Using the `Arraylist`'s method of `get(randomQuestionIndex)`, a random question will be selected from the list of questions in the `Topic` object. This process is done repeatedly in a loop until the correct number of questions are selected.
+
+To ensure that no two of the same question is selected, the selected `randomQuestionIndex` is checked to see if it is repeated. To determine if `randomQuestionIndex` is not selected before, an integer `ArrayList` is initialized to record all the selected integers. By checking against this collection of integers, it can be determined if a currently selected integer is repeated or not, and if it is, no question will be added for that iteration of the loop.
+
+An ArrayList of `Question` objects stores all the selected questions meant for the quiz.
+
+
+
+#### 2.3.5. Design of Stats Feature
+
+E-Duke-8 allows for user’s stats to be shown to the user when requested. These statistics correspond to the results of the user’s past attempts of the quiz. An aggregate result, followed by topical results of the quiz will be displayed.
+
+A `Stats` class facilitates what is to be shown to the user. It also calls the methods of the objects of the two subclasses of `StatsCalculator`, `UserStatsCalculator` and `TopicalStatsCalculator` to retrieve the necessary information to be displayed.
+
+The class diagram given below showcases the high-level design of the stats feature in E-Duke-8. Given below it is a quick overview of each component.
+
+
+
+Results of the quiz attempts can be calculated using the information stored in a `Question` object, because of its methods, namely `wasShown()`, `wasHintShown()` and `wasAnsweredCorrectly()`, that indicate if it has been attempted before, whether hint was used when user attempted the question and if the question was answered correctly respectively.
+
+The current design of the stats feature is such that a correct answer without hint being used would award the user with 2 points, while a correct answer with hint used would award the user with 1 point. No point is awarded to the user if they chose the wrong answer. `calculatePointsEarnedForQuestion(:Question)` in `StatsCalculator` class and its subclasses, is the method that contains the logic for this calculation.
+
+An object of `UserStatsCalculator` class is responsible for calculating the aggregate results from the user’s previous quiz results. For instance, its `calculateTotalPointsEarned()` method will iterate through the multiple topics stored in E-Duke-8 and calculate the total sum of the user’s past results of the quizzes done for those topics.
+
+On the other hand, an object of `TopicalStatsCalculator` is used by the object of `Stats` class to calculate the topical results. In its constructor, the `TopicalStatsCalculator` object uses the single `Topic` object passed into it to retrieve its specific `QuestionList` object. Thereafter, by iterating through the questions for the particular `QuestionList` object, the results for individual topics can be calculated with its methods.
+
+
+
+#### 2.3.6. Implementation of Stats Feature
+
+The current implementation of the stats feature is such that the object of `Stats` class controls what is shown to the user when the `stats` command is received. It calls on methods of a `UserStatsCalculator` object and a `TopicalStatsCalculator` object to calculate and retrieve the statistics of the user’s previous attempts of quizzes in E-Duke-8, before displaying them.
+
+The sequence diagram below shows the interactions between the different objects when `showPointsEarned(ui)` is invoked, by the object of `Stats` class, to display to the user the total points he has earned in E-Duke-8 so far, out of all the points that he can potentially earn.
+
+
+
+Through the logic in the object of `UserStatsCalculator`, necessary information regarding the user’s statistics, such as the `totalPointsGained` integer value and `totalPointsAvailable` integer value, are calculated, and then passed to the `Ui` object to print them to the user. This same concept and procedure are applied to the display the other aggregate results.
+
+A similar procedure is being employed by the `TopicalStatsCalculator` object to calculate the topic-level statistics for the user. The only difference between the objects of these two classes is that instead of iterating through all the topics available, the `TopicalStatsCalculator` object only deals with a particular topic at any point of time. By iterating through the questions of the single topic, it calculates statistics for the topic and returns it back to the `Stats` object, which will then pass them to the `Ui` object to display them to the user. As such, in order to display the user’s statistics for each and every topic, a loop is done in the `Stats` object to repeatedly calculate the topic-level information for all of the topics and displaying them concurrently.
+
+
+
+#### 2.3.7. Implementation of Timer Feature
+
+E-Duke-8 has a timer feature for the quiz. The users are able to choose how much time (in seconds) they require to complete each question.
+The timer would start as soon as the options are being printed out.
+If the user has typed in a valid answer, the timer would stop and move on to the next question.
+If the time is up, it will be regarded as an `IncompleteCommand` and it will be deemed as a wrong answer as well.
+
+The diagram and explanation below only illustrates the implementation of the timer feature,
+it does not show the full sequence diagram and explanation of the `SingleTopicQuiz()` method.
+
+
+
+When a quiz is started, the `startQuiz(ui)` method will be called.
+After the options of a particular question has been printed out, the timer would begin.
+The `getCommand(ui, optionList, userTimer)` method is first called. The `userTimer` parameter used here is the time that the user has set at the start of the quiz.
+The `getQuizInputFromUser(userTimer)` method will then call the `Ui` class to read in the users' input. The timer continues to count down as it waits for the users' input.
+After the user has written an input, the `Ui` will return the `userInput` string back to the `SingleTopicQuiz` object.
+If the user did not write in any input and the time is up, the `Ui` will return `null` string back to the `SingleTopicQuiz` object instead.
+The `Command` object will be returned.
+
+For example, if the user entered a string (that is not "hint" or "bookmark" and not a number from 1 to 4), then the `Command` returned will be one of `IncorrectCommand`.
+If the user entered any number from 1 to 4, it will be an `AnswerCommand`.
+If the user did not input anything and the time is up, the `Command` returned will be `IncompleteCommand`.
+
+It will then enter into a loop and remain in this loop unless the user has input a valid answer or the time is up for that question.
+In the loop, the `SingleTopicQuiz` object will then call the respective `Command` object, using the `execute(optionList, ui)` method.
+
+For example, if it is a `HintCommand`, then the execution would mean that the hint will be printed out by the `Ui` class to show the user the hint for the particular question.
+However, some details were omitted here so that the sequence diagram is easier to understand.
+
+The `SingleTopicQuiz` object will then call the `Ui` class using the `printQuizInputMessage()` method to print the prompt for the users to enter in their input.
+The `getCommand(ui, optionList, userTimer - timePassed)` method will be called again. However, this `getCommand()` method is different from the one that was used initially.
+This `getCommand()` method takes in the time left on the timer (`userTimer - timePassed`) instead of the timer set by the user.
+This is because, we want to avoid the situation where the user is able to extend the timer by entering in any random value (except number 1 to 4) as this would cause the timer to reset everytime.
+Hence, in order to prevent this bug, for this `getCommand()` method, we have to use the time left on the timer instead.
+The subsequent steps are similar to the one stated above.
+
+The loop will end if the user has written an input or the time is up for that question.
+The `SingleTopicQuiz` object will then proceed to execute the `Command` for the last time, using the `execute(optionList, ui)` method.
+
+It will then enter another loop that checks if the user has pressed on the "Enter" button on the computer.
+This feature was implemented so that they have sufficient time to read through and understand the explanation before moving on to the next question.
+The `Ui` class will be called by the `getEnterFromUser()` method. This method will prompt the user to press the "Enter" button.
+The `Ui` class will then return the boolean `enterIsUsed`.
+If the user has pressed on any keys other than "Enter", the boolean `enterIsUsed` is set to false and it will remain in the loop.
+If the user has pressed on the "Enter" button, the boolean `enterIsUsed` is set to true and it will exit out of the loop and proceed to the next question.
+
+
+
+### 2.4. Storage Component
+
+The storage component is implemented locally and mainly saves and loads files in JavaScript Object Notation (JSON) format, except for log files which are stored as normal text files.
+The JSON format was chosen as it is a well-known standard which is easy to parse.
+
+#### 2.4.1. Design of TopicsStorage
+
+Given data for the topics and questions is loaded automatically from JSON files in the data folder. This is mainly facilitated through the `TopicsStorage`
+class which handles accessing the file as well as converting from JSON into `Topic`, `Question` and `Option` objects.
+The class diagram below shows this relationship.
+
+
+
+
+
+The format of the JSON file is important as it is loaded in a particular way. This format has been designed as an array
+of topics that hold the different properties for questions, options, hints and explanations.
+An example is as such:
+
+
+```json
+[
+ {
+ "topic": "Topic Title",
+ "questions": [
+ {
+ "description": "What is your question?",
+ "hint": "Put the hint here",
+ "explanation": "Put the explanation here",
+ "options": [
+ {
+ "description": "This is the first option and correct answer",
+ "correct": true
+ },
+ {
+ "description": "This is the second option",
+ "correct": false
+ },
+ {
+ "description": "This is the third option",
+ "correct": false
+ },
+ {
+ "description": "This is the fourth option",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
+```
+
+Users may choose to edit this data as well and are provided with the following requirements from the User Guide:
+> Note that the title will be loaded with spaces replaced with underscores, there must be 4 options for each question,
+and there must be one and only one option chosen as the correct answer by specifying `true` as the value of the
+`correct` key.
+
+Note that a default data file is packaged together with the jar file such that the application can still run without downloading the data file.
+If users want to edit the data they are instructed to on how to download and set up the external custom file which will be loaded with a higher priority than the one packaged.
+
+
+
+#### 2.4.2. Implementation of TopicsStorage
+
+When the user launches the app, the main program will initialize a `TopicsStorage` object and call the `load()` method which will return an `ArrayList` of `Topic` objects.
+The following sequence diagram shows how the load operation works, focusing on how options are marked as correct:
+
+
+
+As there is a high level of nesting in the JSON file, many methods are called in loops to parse each section and return them as objects which are then used to build the next object at a higher level.
+In the diagram above, the `Option` objects within each `Topic` has to be constructed with a description from the file.
+They are then marked as the correct answer with `markAsCorrectAnswer()` if the value of the key `correct` was `true` in the given data.
+More properties can easily be added to the classes and the storage component in a similar way, by parsing in loops.
+
+
+
+#### 2.4.3. Design of UserStorage
+
+In order to save and load attributes specific to each user, such as the questions attempted, answered correctly or bookmarked, a `UserStorage` class is used to selectively store these attributes into a JSON file, `user.json`.
+This class requires access to the main `TopicList` and `BookmarkList` from the Model component in order to extract these attributes. The class diagram below shows this relationship.
+
+
+
+
+
+The attributes will be saved in the JSON file tied to each question in a topic and is identified by its description.
+A question's presence in the file represents that it has been attempted before while other attributes are stored as boolean values.
+An example is given below.
+
+```json
+[
+ {
+ "notes":[],
+ "questions": [
+ {
+ "correct":true,
+ "bookmarked":true,
+ "hint":false,
+ "description":"First Question"
+ },
+ {
+ "correct":false,
+ "bookmarked":false,
+ "hint":true,
+ "description":"Second Question"
+ }
+ ],
+ "topic":"First Topic"
+ },
+ {
+ "notes":[
+ {
+ "description":"Note Title",
+ "text":"Note Text"
+ }
+ ],
+ "questions":[],
+ "topic":"Second Topic"
+ }
+]
+```
+
+Unlike `topics.json`, users should not be editing the `user.json` file as it is system generated.
+If the user edits this file and does not follow the correct format then the affected parts of the data will be lost but the
+program will continue to run.
+
+
+
+#### 2.4.4. Implementation of UserStorage
+
+Unlike `TopicsStorage` which constructs objects, `UserStorage` accesses existing objects in order to extract their attributes.
+The following sequence diagram shows an example of getting the topic description from a `Topic` object within the `TopicList` in order to save attributes for that particular `Topic` object.
+
+
+
+It can be noted here that the `Topic` object is the same one constructed by `TopicsStorage` and continues to persist until the program shuts down.
+
+A similar method is used to extract the attributes from each `Question` object inside the `Topic` object.
+For example, the `wasAnsweredCorrectly()` method is called on the `Question` object to check if it was answered
+correctly by the user or not.
+This value is then stored as an attribute of the question in the JSON file.
+
+Loading back the user data is done in reverse. If the boolean value of the key `correct` is `true` for a
+particular question, then the `markAsAnsweredCorrectly()` method is called on the corresponding `Question` object. This is depicted below in the sequence diagram.
+
+
+
+
+
+### 2.5. UI Component
+
+The command line interface was chosen for users that prefer to type using a keyboard over using the mouse.
+
+#### 2.5.1. Implementation of Ui
+
+The `Ui` class handles all the interactions with the users. It reads the input from the users and prints out replies to
+the users. It is the point of communication between E-Duke-8 and the users.
+
+An example is provided below to illustrate how the `Ui` class prints out the starting page of the quiz for
+the user to comprehend.
+
+
+
+As the user starts the quiz, the `Ui` class will print out the quiz page to show that the quiz has started.
+The user inputs the number of questions that he wants to answer and also the topics that he wants to be tested on.
+The `Ui` will go through printStartQuizQuestions() to print out the number of questions that the user has chosen.
+Afterwards, the `Ui` will go through printStartQuizTopics() to print out the topics that the user has chosen.
+
+
+
+## 3. Appendix
+
+### 3.1. Product scope
+
+#### 3.1.1. Target user profile
+
+CS2113/T Students
+
+#### 3.1.2. Value proposition
+
+To help CS2113/T students learn and understand software engineering and Object-oriented Programming [(OOP)](#34-glossary) principles through a gamified
+platform and enhances their learning experience.
+
+It is a desktop application where CS2113/T students can attempt bite-sized quizzes, through the Command Line Interface (CLI), to test their understanding of the concepts taught, and serves to consolidate key concepts for easy revision.
+
+Students can earn points for themselves as they answer questions in the quizzes, and they can view their quizzes' statistics to gauge their level of mastery of the topics in CS2113/T.
+
+
+
+### 3.2. User Stories
|Version| As a ... | I want to ... | So that I can ...|
|--------|----------|---------------|------------------|
-|v1.0|new user|see usage instructions|refer to them when I forget how to use the application|
-|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list|
+|v1.0|new user|quickly see what the software has to offer|understand how to use the app|
+|v1.0|new user|answer given questions|start testing myself immediately|
+|v1.0|long-time user|get different questions each time|repeatedly test my understanding for the particular topic|
+|v1.0|busy user|test myself on concepts using short, targeted quizzes|confirm my understanding of concepts|
+|v1.0|user|get a hint for the question in the quiz|think about the question from a different angle|
+|v1.0|user|see what the available topics are|navigate around the app effectively|
+|v1.0|user|select the number of questions to do in the quiz|manage the workload and time spent on the quiz|
+|v2.0|slow but hardworking user|see the explanations provided in the quiz|learn from my mistakes and revise|
+|v2.0|busy, lazy user|take note of key concepts|refer to it easily at a later time|
+|v2.0|frequent disorganized user|view the percentage of error in each topic|tell how well I understand the content|
+
+
+
+### 3.3. Non-Functional Requirements
+
+- Should work on any mainstream [Operating System (OS)](#34-glossary) as long as it has Java 11 or above installed.
+- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
+
+### 3.4. Glossary
+
+- **Command Line Interface (CLI):** CLI is a text-based interface that allows users to respond to visual prompts by typing single commands into the interface and receiving a reply in the same way. (From [techopedia](https://www.techopedia.com/definition/3337/command-line-interface-cli))
+
+- **Object-oriented Programming (OOP):** OOP is a programming paradigm. A programming paradigm guides programmers to analyze programming problems, and structure programming solutions, in a specific way. (From [CS2113/T textbook](https://nus-cs2113-ay2021s1.github.io/website/se-book-adapted/chapters/oop.html))
+
+- **Mainstream Operating Systems (OS)**: Windows, Linux, Unix, OS-X
+
+
+
+### 3.5. Instructions for manual testing
-## Non-Functional Requirements
+To test the product please refer to the E-Duke-8 [User Guide](https://ay2021s1-cs2113t-f12-3.github.io/tp/UserGuide.html).
+The following are a few testcases to try out.
-{Give non-functional requirements}
+#### 3.5.1. Loading data
-## Glossary
+1. Dealing with missing/corrupted data files
+ 1. Find `topics.json` inside `data/main`.
+ 2. Test case: Delete the file
+ Expected: Application will not launch properly and error message will be displayed.
+ 3. Test case: Change a topic title
+ Expected: Application will launch successfully but related user data will be erased.
+ 4. Test case: Remove the `questions` key from a topic
+ Expected: Application will not launch properly and error message will be displayed.
+ 5. Other ways to corrupt the data files: Remove other keys or mess up the JSON format (remove the outer array)
+ Expected: Similar to previous.
+
+#### 3.5.2. Starting a quiz
-* *glossary item* - Definition
+1. Giving quiz commands with different input formats
+ 1. Test case: `quiz n/2 t/oop s/10`
+ Expected: Starts a quiz successfully ith 2 questions from the topic of [OOP](#34-glossary) and a time limit for 10 seconds for each question.
+ 2. Test case: `quiz n/2 t/oop`
+ Expected: Quiz will not start. Error message will show and the ideal format structure will be displayed to user.
+ 3. Test case: `quiz n/2 hi t/oop s/5`
+ Expected: Quiz will not start. Error message will show and the ideal format structure will be displayed to user.
+ 4. Other ways to start quiz in wrong format: Use the quiz command but give insufficient inputs or invalid inputs
+ Expected: Quiz will not start. Error message will show and the ideal format structure will be displayed to user.
+
+2. Trying to start a quiz with invalid inputs
+ 1. Test case: `quiz n/2 t/oop a/10`
+ Expected: Quiz will not start. Error message will show and the ideal format structure will be displayed to user.
+ 2. Test case: `quiz n/2 t/oop s/0`
+ Expected: Quiz will not start. Error message will show to prompt user to give a valid time limit.
+ 3. Test case: `quiz n/2 t/none s/5`
+ Expected: Quiz will not start. Error message will tell user that the topic does not exist in E-Duke-8 and where they can find the available topics.
+ 4. Test case: `quiz n/0 t/oop s/5`
+ Expected: Quiz will not start. Error message will tell user to specify more than 0 quiz questions.
+ 5. Other ways to start quiz in wrong format: Use the quiz command but give insufficient inputs or invalid inputs
+ Expected: Similar to previous.
-## Instructions for manual testing
-{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing}
diff --git a/docs/README.md b/docs/README.md
index bbcc99c1e7..78d75ac07a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,6 +1,15 @@
-# Duke
+# E-Duke-8
-{Give product intro here}
+E-Duke-8 (pronounced "Educate") helps CS2113/T students **learn and understand software engineering and Object-oriented Programming (OOP) principles** through a gamified
+platform and enhances their learning experience.
+
+It is a desktop application where CS2113/T students can attempt bite-sized quizzes, through the **Command Line Interface (CLI)**, to test their understanding of the concepts taught, and serves to consolidate key concepts for easy revision.
+
+If you are a CS2113/T student yourself, do give E-Duke-8 a try!
+
+On E-Duke-8, you can earn points for yourself as you attempt the quizzes! You can also view the statistics of your past quiz attempts to understand your current level of mastery of the various topics!
+
+Challenge your friends to see who can earn the most points on E-Duke-8!
Useful links:
* [User Guide](UserGuide.md)
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index abd9fbe891..48085226aa 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -1,42 +1,535 @@
-# User Guide
+# User Guide for E-Duke-8
+* Table of Contents
+{:toc}
-## Introduction
+
-{Give a product intro}
+## 1. Introduction
-## Quick Start
+E-Duke-8 (pronounced "Educate") helps CS2113/T students **learn and understand software engineering and [Object-oriented Programming (OOP)](#7-glossary) principles** through a gamified
+platform and enhances their learning experience.
-{Give steps to get started quickly}
+It is a desktop application where CS2113/T students can attempt bite-sized quizzes, through the [Command Line Interface (CLI)](#7-glossary), to test their understanding of the concepts taught, and serves to consolidate key concepts for easy revision.
+
+On E-Duke-8, you can earn points for yourself as you attempt the quizzes! You can also view the statistics of your past quiz attempts to understand your current level of mastery of the various topics!
+
+Challenge your friends to see who can earn the most points on E-Duke-8!
+
+Understand more about E-Duke-8, and how you can use it to aid your learning, through this User Guide.
+
+
+
+## 2. Quick Start
1. Ensure that you have Java 11 or above installed.
-1. Down the latest version of `Duke` from [here](http://link.to/duke).
+2. Download the latest version of the jar file for **E-Duke-8** from [here](https://github.com/AY2021S1-CS2113T-F12-3/tp/releases).
+3. Copy the files to the folder you want to use for the application.
+4. Double click on the jar file to start up the program. If the program does not start up, continue to step 6, otherwise skip to step 8.
+5. If double clicking on the jar file does not work, open up the command prompt in the same folder used in step 3.
+6. Enter the following command `java -jar eduke8.jar` (assuming the downloaded jar file is named `eduke8.jar` but this can be changed).
+7. Type a command in the terminal and press Enter to execute it. e.g. typing `help` and pressing Enter will list all the commands that you can use in this application. For a start, here is a list of basic commands you can try:
+ - `about` : Provides information about E-Duke-8.
+ - `help` : Displays available commands.
+ - `topics` : Lists CS2113/T topics that E-Duke-8 knows.
+ - `textbook` : Provides you with a link to the CS2113/T website.
+ - `quiz` : Starts a quiz. Eg. `quiz t/OOP n/5 s/10` will start a quiz with five questions based on OOP concepts. You will have 10 seconds to complete each question.
+ - `exit` : Exits the app.
+
+8. Refer to the section on [Features](#3-features) below for the full list of commands you can use and the details of each.
+
+
+
+## 3. Features
+
+ℹ️ Notes about the command format:
+- Words in UPPER_CASE are the parameters that you can specify for your usage.
+- e.g. in `quiz t/TOPIC n/NUM_QUESTIONS s/TIMER`, 'TOPIC' is a parameter that allows you to choose the topic you want the quiz to be based on, 'NUM_QUESTIONS' specifies the number of questions you want to have in your quiz, and 'TIMER' specifies the number of seconds given to complete each question.
+
+
+### 3.1. Loading Data
+
+Data will be automatically loaded from the files in the `data` folder for use in quizzes and notes.
+You will see this message while the data loads:
+
+
+
+If the data has been loaded successfully you should see this message:
+
+
+
+If you wish to edit the data available, such as adding your own questions to the question bank, then do follow the instructions found in [**FAQ**](#4-faq).
+However, it is recommended that you do this only after fully exploring E-Duke-8.
+
+If have trouble opening E-Duke-8 and received the following warning message, then please refer to the section [**6. Troubleshooting**](#6-troubleshooting) for help in resolving the issue.
+
+
+
+
+
+### 3.2. Welcome Page
+
+Upon successful startup, you should be greeted with a screen like this:
+
+
+
+
+### 3.3. Viewing E-Duke-8 information: `about`
+
+Shows a message explaining what E-Duke-8 is about and your benefits of using it.
+
+Example of usage:
+```
+about
+```
+
+What you should see:
+
+
+
+
+
+
+### 3.4. Viewing available commands: `help`
+
+Shows a list of commands that you can use.
+
+Example of usage:
+```
+help
+```
+
+What you should see:
+
+
+
+
+### 3.5. Listing all topics: `topics`
+
+Shows the entire list of CS2113/T's topics that you can choose for your quiz to be based upon.
+
+You can see the number of questions available for each topic beside the topic itself.
+
+Example of usage:
+```
+topics
+```
+
+What you should see:
+
+
+
+
+
+### 3.6. Accessing the CS2113T textbook content: `textbook`
+
+You can find a link to the module's textbook using this command.
+
+Example of usage:
+```
+textbook
+```
+
+What you should see:
+
+
+
+
+
+### 3.7. Starting a quiz: `quiz`
+
+By following a specific input format for your command (shown below), you can start a quiz where the number of questions, topic and time limit to complete each question are specified by you.
+
+While on a question, you can choose to answer it, ask for a hint (if you are unsure of the answer) or bookmark it for future reference!
+
+You will have to complete the question within the specified time as well. If you are unable to complete it in time, it will be regarded as an incorrect answer and the correct answer, along with the explanation, will be shown to you. You will then be directed to start the next question where the timer will restart.
+
+A correct answer without requesting for a hint will earn you **2 points**! Whereas a correct answer with hint requested will earn you **1 point**. You will not be awarded any points for incorrect answers. You can view the points you have accumulated with the `stats` command, which will be further explained in a [later section](#312-displaying-stats-stats) of this guide.
+
+Regardless of right or wrong answer, an explanation about the question will be displayed after you give an answer. You will then be directed to start the next question.
+
+Note:
+- The maximum time limit for each question that you can choose is 1000 seconds.
+- Each of the questions in the quiz will be related to the topic you have chosen.
+- You can choose any topic (not case-sensitive) from the [topic](#35-listing-all-topics-topics) list.
+- The [topic](#35-listing-all-topics-topics) list also shows you the number of questions you can choose from for each topic.
+- The first question will be immediately displayed to you once the quiz starts.
+- The quiz will only end when you have attempted all of the questions in it.
+- Refer to [**FAQ**](#4-faq) to know more about the quiz system and the point system.
+
+Input format: `quiz t/TOPIC n/NUM_QUESTIONS s/TIMER`
+
+Example of usage:
+```
+quiz t/OOP n/5 s/10
+```
+- This will start a quiz that contains 5 randomly-chosen questions from the topic on OOP. Each question will have to be completed within 10 seconds.
+
+
+
+What you should see:
+
+
+
+From here on you can either:
+
+1) Enter in your answer by typing '1', '2', '3' or '4' and pressing enter.
+
+2) If you do not know the answer, you can request for a hint by typing `hint` and pressing enter. Refer to the [section on hints](#38-showing-a-hint-hint) for more information.
+
+3) If you would like to refer to the question in future, you can also `bookmark` it. Refer to the [section on bookmark](#39-bookmarking-a-question-bookmark) for more information.
+
+If you have entered the correct answer, this is what you will see:
+
+
+If you have entered the wrong answer, this is what you will see:
+
+
+If you did not answer the question within the specified time, this is what you will see:
+
+
+After every question, this is what you will see:
+
+Please press "Enter" to proceed to the next question. Once the new question appears, the timer will then restart!
+
+After attempting all of the questions, the quiz will automatically end:
+
+
+After the quiz ends, you will be prompted to enter in a new command. At this point, you are free to choose any feature of E-Duke-8 you want to access, or you can also start a new quiz!
+
+
+
+### 3.8. Showing a hint: `hint`
+
+Shows a hint to the current question.
+
+Example of usage:
+```
+hint
+```
+
+What you should see:
+
+
+
+Note:
+- Once a hint is used for a question, it will be recorded into your [stats](#312-displaying-stats-stats).
+- When a hint is used, getting the question correct will earn you 1 point instead of 2.
+- Refer to [**FAQ**](#4-faq) Q4 to understand why you should use hint despite the penalties.
+
+
+
+### 3.9. Bookmarking a question: `bookmark`
+
+Stores any question encountered in a quiz in a list.
+
+Note:
+- Bookmarking a question can only be done during a quiz
+
+Example of usage:
+```
+bookmark
+```
+
+What you should see:
+
+
+
+
+
+### 3.10. Listing out all bookmarked questions: `bookmark list`
+
+Lists out all the bookmarked questions and each of their four options. The correct answer will be shown too.
+
+Note:
+- Listing out all bookmarked questions can only be done in the main menu
+
+
+Example of usage:
+```
+bookmark list
+```
+
+What you should see:
+
+
+
+
+
+### 3.11. Deleting a bookmark: `bookmark delete`
+
+You can delete a bookmark by specifying its index. The index can be found in the bookmark list when you use the `bookmark list` command.
+
+Input format: `bookmark delete INDEX`
+
+Example of usage:
+```
+bookmark delete 2
+```
+
+What you should see:
+
+
+
+
+
+### 3.12. Displaying stats: `stats`
+
+Displays the accumulated statistics of your quiz attempts on E-Duke-8 which includes the points you have earned, questions done, questions answered correctly and hints used. Both overall statistics and topic-level statistics will be displayed.
+
+Example of usage:
+```
+stats
+```
+
+If you are a new user, this is what you should see:
+
+
+
+
+
+
+If you have attempted the quizzes on E-Duke-8, you would be able to see your own stats.
+
+This is an example of what you should see:
+
+
+
+- Refer to [**FAQ**](#4-faq) for more information about the point system in E-Duke-8.
+
+
+
+### 3.13. Adding a note: `note add`
+
+Adds a note to a specified topic.
+
+Note:
+- There can be many notes under each topic
+- E-Duke-8 will guide you through the note-adding process
+
+Example of usage:
+```
+note add
+```
+
+What you should see:
+
+
+
+
+
+
+### 3.14. Deleting a note: `note delete`
+
+Deletes a note from a specific topic.
+
+Example of usage:
+```
+note delete
+```
+
+What you should see:
+
+
+
+
+### 3.15. Listing out notes: `note list`
+
+Lists out all notes belonging to a specific topic.
+
+Example of usage:
+```
+note list
+```
+
+What you should see:
+
+
+
+
+
+### 3.16. Exiting the program: `exit`
+
+Exits E-Duke-8.
+- You can only exit the application when you are not in a quiz.
+- If you are in the middle of a quiz and really want to exit, you can give random answers for the questions.
+
+Example of usage:
+```
+exit
+```
+
+
+
+
+
+### 3.17. Saving user data
+
+User data will be saved after every command that changes the data completes such as at the end of using
+`quiz`, `note`, and `bookmark`. There will be a final save confirmation message upon successful exit of the application
+through the `exit` command.
+You will see this message while the data saves:
+
+
+
+When the data has been saved successfully you should see this message:
+
+
+
+This is stored in the `user.json` file in the `data` folder and can be transferred between machines to keep your own
+history. Please do not attempt to edit this file as it will disrupt the running of application (Refer to [**FAQ**](#4-faq) Q7).
+If you want a better score you can always reattempt a quiz!
+
+
+
+## 4. FAQ
+
+**Q1**: Am I be able to re-attempt the same question after my quiz ends?
+
+**A1**: Yes, you may. Questions for the quizzes are chosen randomly from all of the questions in a certain topic. Hence, there is a chance that the question you have attempted before gets chosen again if you choose to attempt another quiz from the same topic.
+
+**Q2**: Why does my stats only improve as I do more quizzes? Shouldn't the penalities from my previous quizzes remain?
+
+**A2**: E-Duke-8 tries to motivate you to understand CS2113/T concepts better. E-Duke-8 also encourages learning from failure. Therefore, you do not have to be disheartened by incorrect answers when attempting quizzes. Learn from the explanations given and get the question correct in your future quiz attempts to improve your stats!
+A correct answer in a future quiz attempt would also mean that you have come to understand the concept being tested in the question, and hence, you should deserve the points for it.
+
+**Q3**: Why does my hint usage indicator for a question not disappear after I re-attempt the question without using hint?
+
+**A3**: This is because the hint usage serves as an indicator that you might still have some doubts in the topic, and hence you might want to read more about it. Resetting the count for hint usage might take away this benefit.
+
+**Q4**: Using hints will limit the total points that I can earn to build up my stats, so why should I still use hint?
+
+**A4**: While points you earn will indeed be lesser, you are still encouraged to use hints when you have any doubts while answering questions, as they help to spur your thinking, or to confirm your thoughts.
+Furthermore, hints might give you an alternative perspective to think about the question at hand, which may be helpful to how you answer similar questions in the future.
+
+**Q5**: How are the points awarded for correct answers?
+
+**A5**: A correct answer without requesting for a hint will earn you **2 points**, whereas a correct answer with hint requested will earn you **1 point**. You will not be awarded any points for incorrect answers.
+
+**Q6**: How do I change the questions in the quizzes?
+
+**A6**: You may download the sample `topics.json` from the [releases page](https://github.com/AY2021S1-CS2113T-F12-3/tp/releases).
+Make sure to include this file in the `main` folder located in the `data` folder.
+If these folders do not exist yet please run the application once to create it.
+
+The directory structure should look something like this (assuming the main jar file is named `eduke8.jar` but this can be changed):
+
+```
+yourFolder
+| eduke8.jar
+|
+----data
+ |
+ ----main
+ | | topics.json
+ | | ...
+ |
+ ----logs
+ | ...
+```
+
+Your changes will not be reflected if the directory structure does not match that above.
+
+Open `topics.json` in any text editor to edit the questions, make sure to follow the format of the questions
+already provided. An example is shown below.
+
+```json
+[
+ {
+ "topic": "Topic Title",
+ "questions": [
+ {
+ "description": "What is your question?",
+ "hint": "Put the hint here",
+ "explanation": "Put the explanation here",
+ "options": [
+ {
+ "description": "This is the first option and correct answer",
+ "correct": true
+ },
+ {
+ "description": "This is the second option",
+ "correct": false
+ },
+ {
+ "description": "This is the third option",
+ "correct": false
+ },
+ {
+ "description": "This is the fourth option",
+ "correct": false
+ }
+ ]
+ }
+ ]
+ }
+]
+```
+
+Note:
+- The title will be loaded with spaces replaced with underscores.
+- There must be 4 options for each question.
+- There must be one and only one option chosen as the correct answer by specifying `true` as the value of the
+`correct` field.
+- If you edit the title of existing topics or description of existing questions then their associated user
+data might be erased.
+- The title of a topic cannot be blank or repeated (not case-sensitive).
+- If the title includes a backslash, you may not be able to use the title in anywhere of the program.
+- The description of a question cannot be blank or repeated (not case-sensitive).
+- If you want to re-attempt the same question, you can simply start a new quiz with the topic that the question is from.
+- If you do not want to give a hint or explanation please provide an empty quotation marks, `""`, do not remove the key from the question.
+- Make sure you follow the types of values used which is either a word/sentence enclosed with quotation marks, `""`, or a `true`/`false` value.
+
+
+
+
+**Q7**: What happens if I modify the user data in `user.json`?
-## Features
+**A7**: If you wish to modify the user data, the application may not be able to load it successfully. You will
+receive the following message, and the affected user data will be erased.
-{Give detailed description of each feature}
+
-### Adding a todo: `todo`
-Adds a new item to the list of todo items.
+Therefore, it is recommended that you do not modify the user data. Do build up your stats by attempting more quizzes!
-Format: `todo n/TODO_NAME d/DEADLINE`
+
-* The `DEADLINE` can be in a natural language format.
-* The `TODO_NAME` cannot contain punctuation.
+## 5. Command summary
-Example of usage:
+| Action | Format, Examples |
+| ------ | ---------------- |
+| Viewing E-Duke-8 information | `about` |
+| Viewing available commands | `help` |
+| Listing all topics | `topics` |
+| Accessing the CS2113T textbook content | `textbook` |
+| Starting a quiz | `quiz t/TOPIC n/QUESTIONS s/TIMER` e.g. `quiz t/OOP n/5 s/10` |
+| Showing a hint | `hint` |
+| Bookmarking a question | `bookmark` |
+| Listing out all bookmarked questions | `bookmark list` |
+| Deleting a bookmark | `bookmark delete` |
+| Displaying statistics | `stats` |
+| Adding a note | `note add` |
+| Deleting a note | `note delete` |
+| Listing out notes | `note list` |
+| Exit | `exit` |
-`todo n/Write the rest of the User Guide d/next week`
+
-`todo n/Refactor the User Guide to remove passive voice d/13/04/2020`
+## 6. Troubleshooting
-## FAQ
+If you have trouble starting the application there could be two sources of error for loading data.
+It is possible that the data for `topics.json` or `user.json` has been tampered with wrongly and thus cannot be parsed
+correctly. Please ensure that if you wish to edit the data in `topics.json`, such as to add questions, then you should follow the instructions found in [**FAQ**](#4-faq) Q6 carefully.
-**Q**: How do I transfer my data to another computer?
+On the other hand, `user.json` should not be manually edited.
+If you have accidentally changed this file, you may delete
+the file to reset the data.
+A new file will be created on start up.
-**A**: {your answer here}
+If the above fixes do not work you may delete the `data` folder and use the default questions or
+download `topics.json` from the [releases page](https://github.com/AY2021S1-CS2113T-F12-3/tp/releases) again.
-## Command Summary
+## 7. Glossary
-{Give a 'cheat sheet' of commands here}
+- **Command Line Interface (CLI):** CLI is a text-based interface that allows users to respond to visual prompts by typing single commands into the interface and receiving a reply in the same way. (From [techopedia](https://www.techopedia.com/definition/3337/command-line-interface-cli))
-* Add todo `todo n/TODO_NAME d/DEADLINE`
+- **Object-oriented Programming (OOP):** OOP is a programming paradigm. A programming paradigm guides programmers to analyze programming problems, and structure programming solutions, in a specific way. (From [CS2113/T textbook](https://nus-cs2113-ay2021s1.github.io/website/se-book-adapted/chapters/oop.html))
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000000..c4192631f2
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/docs/diagrams/Architecture.drawio b/docs/diagrams/Architecture.drawio
new file mode 100644
index 0000000000..e3cfd229d9
--- /dev/null
+++ b/docs/diagrams/Architecture.drawio
@@ -0,0 +1 @@
+7Vlbk9ogFP41edxMAiEhj6tuL9N2ujNOp91HTNAwjcFBXLW/vsQQcyHWy0TdaZsHBz7IAb7z5cBBCw7nm/eCLJIvPKapBZx4Y8GRBUCAgfrNgW0BeDAogJlgcQG5FTBmv6gGHY2uWEyXjY6S81SyRROMeJbRSDYwIgRfN7tNedocdUFm1ADGEUlN9DuLZVKgGAQV/oGyWVKO7Pph0TInZWe9kmVCYr6uQfDJgkPBuSxK882Qpjl3JS/Fe+8OtO4nJmgmT3lhMBiHG8gfxCe5zZLh1xVevT5oK68kXekF68nKbcmA4KssprkRx4KDdcIkHS9IlLeulcsVlsh5qmquKmpzVEi6OThPd796pRrK51SKreqiXwCOJkwrBurquqIfhhpLatTDQINEu3y2N12xogqamDNICo6TRLP4MVebqmU8U+AgJstkx5rbZIhumPyhyczLL3nZhhjp+mhTaxxta5VnKphaEBUllqnF5aZc23FRCTTs5UBlcFfb1mttk8W6aGx8E0edV/MO6nBOiQmaEslem+a7HKZHeOZMDXxQGy7ybQ851YOaFpd8JSKqjdS/jZZdFCIbe2H1nDWKJGJGpTHKTmt7ii6XH/4vvzciPzcMbAc3tAGwWn798S9VILBDeJbpK8suNGT3LOhSOUIxyDNDgirgy6bUllLwn3TIUy4qXU5ZmrYgkrJZpqqRsp1LYZBvH0xtwY+6Yc7iOB+mc/Npbk997D/g6P7jdUgMXGv3KU9CNUc8LhapIugv90M71vumI4KbOgIYjhgRSSZkSf8dLwBsesG/qReg4YVvHw3+zzq01r1gARgjimPPcJlqwWACfb8fYiFEDWIDk1cXdBDrX41YzyBWZ3N9cksonkZd3PoRppNpT6JFrdAR3p1cZJD7mc9Y1Cu5UxzRqJPcCUbqANsPuR58c+T6BrljyUWe2fdK73QKuumN/YmPrhQXYCmd+9F7Uf5bzznKTMGxm3nCsRyhzFXsMjt5saospjtTsU5MIdTsdyfzEwJicc4+qr97JSUQt3Zo1BLCqSlI+8Peb/03SjjcixLdE3TmXqQz52Y6Q6fqDN5VZ628yAg4J+vMaUU4cNv7FNfMbC/VWfPW4+idh9aZW1eZ/eebl7vEM3RPnaF2xtEOQ5fqzPX6imeqWt3bF92rPz/g028=
\ No newline at end of file
diff --git a/docs/diagrams/Parser Diagram_.drawio b/docs/diagrams/Parser Diagram_.drawio
new file mode 100644
index 0000000000..af6a36b09a
--- /dev/null
+++ b/docs/diagrams/Parser Diagram_.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/Parser_Sample_Sequence_.drawio b/docs/diagrams/Parser_Sample_Sequence_.drawio
new file mode 100644
index 0000000000..ee01ddf0ae
--- /dev/null
+++ b/docs/diagrams/Parser_Sample_Sequence_.drawio
@@ -0,0 +1 @@
+5Vpdk6I4FP01Vu0+2AWEoDz61d01Y9f2dM9O7zxGiZJtJGwIo+6v3yBBIKCCyowz2y9tDuEK557cnJuyA0arzQNDgftEHex1DM3ZdMC4Yxi61TfFvxjZJohpgQRYMuLISRnwSv7FCQglGBEHh4V5nFKPk6AIzqnv4zkvYIgxui5OW1Cv+KUBWuIS8DpHXhl9Iw53E7QPtQx/xGTppt+sa/LKCqWTJRC6yKHrHAQmHTBilPLk02ozwl7MXUpLct/9gav7B2PY53VuAH40vN8we76daoH/x9tnAz10ZZRvyIvkC3fA4An70TNiIWbyyfk2pUO8RBB/jFbelCywR3wxGgaYkRXmYj4YexJ+zrChSA5HAouv67ux56EgJLNdWE0gDM8jFpJv+AWHiQR2KI18BztytCdwN+CMvu9TEgct85G+HGYcb3KQ5OcBU/GAbCumpFfTXEmt9uVwnWV+n183l3UIJIik2pb70FlCxAeZkwb5Mcr5UVMSUOLz3ffCYQeOlXRQxl26pD7y8gm5kNijUqrNtgkLZPeqyC5zrdttcQ2r1sIj9oIRXa2Q7/zPFgPQiotBN2uuBrPXVoasn2c1wKZ0K6uhkuwKrq9AtY2nlvnyQYOPr+sNHbyHEz7t6jW4zul/jGOmxLMP1y7h+DVA8/jKWngCgbl85Un6ioSCFgkFCqHQKDEKKhhtrZT3S4Tmastvv5fYjd+UCCMy8MjSF9CMck5XgjDsO4PY2cSYR+fvO0g84V+xZu80zUyBrwlg6qdVvZs/3sjryWibH+XWyw48WGBCGrE5Pr2lccSWuEbCsVMwaOV0M+whLopl0fpVZE/e+hxXiEwmRq+oE91SBJC8kLxL0cD+MS5YaCVZzA9sN00E4aDQ3VW0JLmpr7ZqKGFDeKykrlAOkOOvuWuZSOLBNjdQJSK+9p546cK/WDAnhSATGj94X5fBLxSHUkOAWm4TEZe0UYqjW+bxQAdElgVKJ9LFIsStCLGG1fy+ChR5NPIK1O5s2/5hKrRqlq3majWAbhTU0TXMq6jXUBzc3tE1lS8w7Dt4PNQNCNg8LeAf4A6b+27FCQK7ZmOkblxX84Jl5yIao4kTveN+ieFfuyfqKgcElT1r1QFBaz7dvknRH5VRywcEpnEFrl1sT798HvdGH7VnQD9NBp9eogqrxiJfGvgppcGfPifeROxBF7r5c3XctlXu6rB0JCD6jexPiXhyT0j3KahGrbVNnbFvVKa1bHyC+PAz7cw6hvVPFB/SDl3Rr2WjVnOceiBdeCCj4IE0wzzDA8n2MPbGulXoD6/a/CkKrG+X8vbrcJ077vkhuIprAlZRjbCp09l7fu14oJPu66qWqVL6Zcskm887vBEbLsftVrKcynWzoHJow8Yqr6/Kc9V2obJMxY6rJ9l1lXXQIV6/YM5mU7f3YTb+8vGpT7ovf98v3sY31CmmdU0ICPSLx152zzqntNVsF/N17Zgvu4U2UClosHEdOiC7UqALekChCbTNzZCe9eA76XpxLUHTVpSeRLyq7msciX/vExKQL5tiFWjNy2ZNxd+Ckru6UkKh2vPW1jK4M/PO1T4ettXTDTHMfgWQTM9+SgEm/wE=
\ No newline at end of file
diff --git a/docs/diagrams/QuizQuestionsManager.drawio b/docs/diagrams/QuizQuestionsManager.drawio
new file mode 100644
index 0000000000..26f2e1c643
--- /dev/null
+++ b/docs/diagrams/QuizQuestionsManager.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/QuizQuestionsManager_setQuizQuestions.drawio b/docs/diagrams/QuizQuestionsManager_setQuizQuestions.drawio
new file mode 100644
index 0000000000..126db2347f
--- /dev/null
+++ b/docs/diagrams/QuizQuestionsManager_setQuizQuestions.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/Stats.drawio b/docs/diagrams/Stats.drawio
new file mode 100644
index 0000000000..727c075c82
--- /dev/null
+++ b/docs/diagrams/Stats.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/Stats_showPointsEarned.drawio b/docs/diagrams/Stats_showPointsEarned.drawio
new file mode 100644
index 0000000000..adbe1f3e47
--- /dev/null
+++ b/docs/diagrams/Stats_showPointsEarned.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/TopicListAndNotes.drawio b/docs/diagrams/TopicListAndNotes.drawio
new file mode 100644
index 0000000000..c2ee0156c4
--- /dev/null
+++ b/docs/diagrams/TopicListAndNotes.drawio
@@ -0,0 +1 @@
+7Vxbb9s2FP41BpoBMXShZPkxtttmW7YFTZu1TwVt0TZXWXQlJXH660dKpG6kbUUR4wBRECTmRRTJ850rjzmwp5vdxwhu138RHwUDy/B3A3s2sCzPAPQvq3jMKoBtZRWrCPtZlVlU3OBfiFcavPYO+yiudEwICRK8rVYuSBiiRVKpg1FEHqrdliSovnULV0iquFnAQK79F/vJmi/LMYr6S4RXa/Fm0+AtGyg684p4DX3yUKqy3w/saURIkn3a7KYoYHsn9iV77sOe1nxiEQqTJg/8AZaX1i0yvv+z+G4mF5Oblb0+t7NR7mFwxxc8sNyAjjfZsiknj3wf3J93bJ6TDYxWOBzYF7TV2O7oX1qZrpbVnydkm7WBUluCdsk5DPCKP7egE0ZRMSb9tGL/P5MtXlzhOBFTmEeiSdTQ1W3rdeuIzVQARwxqyuM/a2UBWialpdXHPk9xKeaf9ruIIvjIlwM3dF8m6dtnON4G8BHO6ftFQ2V6mlbt4/tSVfbecB5v0/IkxSd5SEkQZ/N/R/99wWelSVSHaDbqEoc+G+kmiXC4Oju4yMpgVoVK1j2KEkzZ8iLD0SxF2oSjapZRZ0Jor2WQMtkSU/DbkyUJEy5UTIuXP8ANDpg4ukTBPWKjsv1MNgHrlL+7zFic19gc0K5UxRntIyIblESPtAtvtWzO9ELqCXH2UMgQc8zr1mX5IcQH5HJrlY9dsDb9wLn7CZwuxFCF1WubjEL/gslMWvIx3JDQ/7xmPDGhDR/SDU03iJb4nlqgunV0x6LHr+XCN1owho4oztgGGXnpUZR2OPla+pw95XoWLxePsUL5qWsUYbpBVJ7wOp+Kb74iFMzJw/uiYj9lY3IXLdCB3fO46qHCACXH5SmbxUGclHHgcspEKIAJvq8qHhUO+HDXBNNl5JiznSrmHKsGpWyR/KmyoqgN5JhHBsp2QRoohWW+xvZIHUlATcWShNb4AW8CGCLB5rzFLMkFrmrsiVp8LNY48K/gI7ljNI0TuPghSpM1ifAvOiwU2KbNkZAlllvpccOe5ACMEJPK1wJjZq3qL7irdLyCTF+kFQsSBHAb43m+jEz3TEiSkA3v1IFwckCVvranEE6OSjiZribh5EkkZwqVGn6LCG8TTLhezpQI1REDy95dcLX7AOMbqrp4lzk1DhEMS30k3DB7JKVnRH6gKQkIkx0hyYBEpVytqqZj1EiKt3BBp3aV9pmBouYT3z5QVU9r7PuISdaIJDCBGckZfbeMq9LtdSb0l1JhysSnQyc+pWWzKNNf1j1KpiSka4E4BQSieHpAcaKEykF2O44fjhfLbQYXADShZXxckwU4pV1GY2G4m60IvKGkSrUHp+hnRvDZuSlR3ZapbisoHMA5Cq5JjDNcz6Ksb43ypyLuqKEs8DTR1lSZKcyQpBpnVsiDd2cpu5eYXJiwf5MExYXt2ksBXUDxmgHF1oUUS1YaEpFLpmmdYnOuVSclo5dsU2r4MF4jXzJ2vbKhmpm03FQ1D5upwig2hsAFZcP43BgauaW8zzRmpUNWLqX9mqxICINuTF27oalrNbV1n2nXSuao09KuBfaRgTTbtbZ5UsACwypDdmjY48OwPYoxpf9VgN3xvE7A3h7KAjmvBsvA7cxH8yoDueaoEZbToFSpG1c0eyfsGrUJu8aReY0P9acfshl0yliWHMX8giXW6t3Fdu6iXcOsq4hl5WZjxUTUFspyegegqV2X88Zz3Ds1eXVR193jAWyp85/khwTMxC+H2BXB9TSSfCZ5Cek4zE1oP0zvS3SLORs0wxzQFYASp5Il0FVA0OuSbnSJV9Ul+TmJKh7+IrpEIK/XJcf5OmeSZ4UKleTVRV2VpSBHk/ZEl7OuIr7MQ059hPkFcKPQB0rc6NMHKiOkRuWSHz4PCJPCkiPOD02NilueHkR3eWg6BA4oufbM0TaE79/u5LTrmBJ3To8fn/JdPsX5KbCquin3e57sm3tHBtIcZwKyO9zbMm/BlgG9LdNYJ4Eu/OIXtWVAb8u8Alvm6bg5vS0jJ9SU9EEW9+h1QjepNTWVoIqlWS/q3jY4JO1VQo1PnhUqVZJXF3VVmTBcJfwehihSZyPvi3FK6kJO3u3VhC4sqUKgKixpUxPgFC6vMRyPR1W313DcY46vMiVCmZmRe74tj7j36oTO0igED/cu7zOw6zRIrThdcvvxRAqWqE5bhRgswdksgzmHthrO7cEKRqcD4ahmNLnjliDMHxRfumiY3/PUnIj6hD3zcE5Evb+Yl9acCCAb/eLIs7f2O7L2QS2RfuTKESALKHS4vm/5AHUmfciSYp9iCPbW3cEgQCeeggoZlq6cedAnzWskr9OQ8XU5guL9kiMI/dSBY6JfToTxUUANaNZOd6r37rQCRM6WVwIEWLoQ8jTv7pkWsjEE40ryrzk0Ru0y3Vu4de3tYIdvylGvTTDcKQxmp5aQOTbbem21gbx6GLI7rw3fXruf/vx57UWz5bfb/y53fnR7Lh9oMDk1JZsNDP3eSi2gLMkZBbr3Wqk1H9+xbUkUKc8j7A5MESXZG0iiN2KJHKHrfqZ5DYeUytnJcZg0Ybfnaa08bY8akl0bT6vukel5uilPv+7EA2EU1fR0z8yawkhj0DSMVDf8uiO5zM/9hQwv5V3m/NZ5dEnbjQxOn3mmkbyKOxleNrrUJvOs5/GOQdAwgiRSqDtHgSujwBwOh7/tI3UpLpSq1tJ+w7uE8LvrGlkHOb/LDKnAjhJjEbkL/TRPoSutXT9tVHwtVhnh16WzXdmvNt8obdxaOsJIccOVKrdGH23kY7m3yjfOaE/08gVoo3S+5IPyL7Hs3MiXbtSymyp5UNJtkrU4cSNfX8cdgfV7Kdsm/EjST1/Cj5JoDU4zW1OsOMUYdJ3nI5J6hgYAg8pVlyN38NQvbDVFVvXc41DYrtn1lntZ2xgCc1S9l0ScZ2nAsunVIegOnXZotsHRofbguRhKdCTLZYy0YN5s4GS1B/2he1O7xW3OX+yLipZTYbJjLLb/fqAmfNDwWO+1AHw0Ho7LP6PKmx2Hfc+z5tE3Rbzl7rGQXgTvtFjce551Ly6Pt9//Dw==
\ No newline at end of file
diff --git a/docs/diagrams/TopicListSampleSequence.drawio b/docs/diagrams/TopicListSampleSequence.drawio
new file mode 100644
index 0000000000..5b25ea70de
--- /dev/null
+++ b/docs/diagrams/TopicListSampleSequence.drawio
@@ -0,0 +1 @@
+7Vpdc6IwFP01zuw+1BEQhcdqP/ahnXZ2u9vuYypRMgXChFBlf/0GSIAAAla66rY+dMghXuCcm3PJrQNt7m6uCfDtW2xBZ6COrM1Auxio6tRQ2d8YiFJgrHFgRZCVQkoO/EB/IAdHHA2RBQNpIsXYociXwQX2PLigEgYIwWt52hI78lV9sIIV4McCOFX0EVnUTlFDH+X4N4hWtriyMuJnXCAmcyCwgYXXBUi7HGhzgjFNj9zNHDoxd4KX9HtXW85mN0agR7t8QfPC2dWGmIvoZuR7d48PKrg+41FegRPyBx5o5w/YR4s5dl3gWfzeaSQIYY/hx4eh69ygJXSQx0YzHxLkQgoJO+Nw+D7HZkweChgWn1eSseMAP0DPSdgRQwhchCRAr/A7DNIsSFAceha0+CijMBlQgl8yUeKgVUbE40FC4aYAcYauIWY3SCI2RZwVavF0NfhwnWufKWwXdNcECHi+rbLQuSTsgKuyg0JqVaGyJD5GHk2uq88G+kVJDkyojVfYA05RkD2JbUymzmyPdYnsaR3ZVa4V87241tq5jh8OMXs4d9DKY9AzphS7CWuA0PPYcWLOWQiGQc8SyLODFy9iGrc5o2/mWewVbJrHnwdakult1UfEjcRQMVOAQAdQtlZlu62Rg4e+jzO0GLdeeBEhwCFZQP6loqWV45QS6MyU4+DlMoC0khbZg749U/StvnmDAvrBTDMzv6MxzcnpmKa+K9ulnK8lu8Y0Jz1w/XQZktC/8+bgYbaM8K8JuT2rMU2fMGqvYq6SFRF8+drdRmssk/FHoqeY5yF7dj7+nYw1bdouRDL/YsPPp6OoOCpInIC1JtlVyqpuwpzEq8We5qmbkv7KqBShq3kqxrgcaMiWaf5R5bhpcWmI+/6ua1RSbYk8q7f0knJrD+dMFWgvw63letKxXPecYepUtpiKd7SmWK+pUOs6tRuXn+j0Km/F+GtSanstGB+w8tbqcjzblRZit2dV18qbMdtWesuvt72RPa6QHaJhT9UX+5CdmlkgsBPe00pqFbYucINo5pvsOC3Jpt5VoMYC2+x0PRmdKa8eTS8J1VryRGKUA43NoVn4GEdnn9v3Lyfb99nLSBVFVnCsHtxJj2cP8xYn3fIufPjGT+3dTtu5Pkjjp9EimxZ28dVye3Z9Nn52zpTqFuS0Gz97uWa5gB6Ba5on7ZrGLq558M6PuFq59ZMth/+w8bOLbJ+Nn952+9VtZWDjdc/txTf1f9p3MXJDqOldr7Vqm/8k0dSJbDR62a2PYAOj1Pyv7iM2gLSjq8BKtStxSiU4TazT6QEp1a28aALtW4c/QgvIkNfPpLzF7NwCKgcyDtcCYsP8Z0Xp9Py3WdrlXw==
\ No newline at end of file
diff --git a/docs/diagrams/TopicsStorage.drawio b/docs/diagrams/TopicsStorage.drawio
new file mode 100644
index 0000000000..788cb9dda9
--- /dev/null
+++ b/docs/diagrams/TopicsStorage.drawio
@@ -0,0 +1 @@
+7VrZduI4EP0azul+YI5tGQOPLFmmm+kmSydz5mWOsAWoERZjKyz5+i7ZEl5wwJCQZDq8gFWWtdS9VXVlqKDOdHkR4Nn4L+4RVrEMb1lB3Ypl1RsWfErDKjbYqB4bRgH1YpOZGG7oI1FGQ1kfqEfCTEfBORN0ljW63PeJKzI2HAR8ke025Cw76wyPyIbhxsVs03pPPTGOrQ2rntgvCR2N9cym04zvTLHurHYSjrHHFykTOqugTsC5iK+myw5h0nfaL/d/ru5Zb+JcfLkK/8M/2l9vv91V48HO93lkvYWA+OLgoR8nw/PLO/vn37P++dXCuGgNvlSrpkJ3jtmDcpjarFhpDxLfa0kgoOVzH4xtsCigAeWoeU5hLtSVrbWbooYI+GTteBMsAX/wPeKp+8QDsNRUhA344iwxtCMD3JiTQFBAFEweDsfRw2Y0OA6EXtqAcXeijenlyHZ6tSWdqZwe8ofAJVs86ChO42BExDZPo7ij3HGKmQqrC8KnRAQr6LBIWGo6inoBYVjQeZbSWEXGaP3serg+p7A5y1BBbKthVAibTZQdId6keihNoe3jWHp5epzYCRvjwEVqh4kpIug+ZHX+X2R9F/zUvNtJUOPt+LkuFrrGWAcSFOUGQvm1PMFQAAmvUt1mskNYfsHIMrauy2rk+huZ/nARr+DQcPna/Pmvdxnak6GB3GF/0JpeL6u6UJcMFz4j/t4RsQ4m87nJ/IVpb2yyvthJtZK0V0gaf9SyVDVfJAKQbWdTdK2pJ9o7SaNctq+Xy9IbA1XtPMmz4/DhMCTPCiM7F0aWQuOlwmIbM1JRcctn1A1vBA+klsyHSLigU4ajUjLkvtAEl/THjI4gZroucJYEYNDkbqkbgs/A6o4p83p4xR8kEyHhuxPdao95QB9hWKyDKF0PLCfT40Y+qaYOSAh9+jpczLWph0Oh+ricMTwL6SBasOwyBeip3+ZC8KkeKBPQO6J/vyCV3iDLMlHVzAsU1U7VGqumbOOUWm/mqF0QaNdwqMD+CFyQZON8hNib061LW3o6y8lOhxnA7mNB2tKJ4TE0j707hzMakXMspgmH8sBppjIyFAU8nVLPi7J0OMMu9Ue3krfdqplYetGDXZRYrpVfUEQigQUerAOD4QFhfR5SQbkcP4j7tlVCgGXX2pVaN7IEosN9WDGmEacI8HdBJIcL2LY1oHezbZWFcRe7Gk+TKwPzvpjWCjBtS0zxnHz6XEEtuIayupmKYH9iN5hx0sniZm/iJk0cnh2yKODHQIFIAOSxzGLWBj91ZBEE9KwOtM2k/WaAIrscoPn4PQTRQhVhbhaVGFLGsachjWpZj4InLIdJd3RpOGN4FfnackaJh06Q74TcKVkhXgLyreeqNOT1Nh5IL7iiUgcDTI2iI12Pu7J6vzt9YRsfU1+gWkn2mOgggYHyyrlRIDDqry4wnO/fu3ffru5ve5Mr//LSGc3/QQVyuCJP38YQClA/egUqc9eNCCCPfNTstI710umpQFG+cnoqEo4a15PE2B9Rp6RoPB6iRbLxdBR4JqxN69XOArxVb5xBKq0NqvMfX7i5vLXdJ9NvWjJ8gniNE/Dn3y5es5LnWCibxlvn46KfLuJTgP6mUuMNsZs6C6y/tZA8aci305B2XtQViEizUSQijYNEpIlKiMh38paqeSpNu5KWU5pvT0vIQnod6y1VwTuN3/4F1SHVaH9gG+WAPZ6SNDeQPb2nOhLY9c1Xk0cDe+sPnM9UHhkOnNTH66uPWlYNWDqId6kBe0t9eFp81HLTvZOfyIoZXuJvQR9IfWzPAs+SH0WA7y8/oJn8aTImQfLPU3T2Cw==
\ No newline at end of file
diff --git a/docs/diagrams/TopicsStorage_load.drawio b/docs/diagrams/TopicsStorage_load.drawio
new file mode 100644
index 0000000000..8ff9b70141
--- /dev/null
+++ b/docs/diagrams/TopicsStorage_load.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/UserStorage.drawio b/docs/diagrams/UserStorage.drawio
new file mode 100644
index 0000000000..5f3dc0cf50
--- /dev/null
+++ b/docs/diagrams/UserStorage.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/diagrams/UserStorage_load.drawio b/docs/diagrams/UserStorage_load.drawio
new file mode 100644
index 0000000000..275c58084f
--- /dev/null
+++ b/docs/diagrams/UserStorage_load.drawio
@@ -0,0 +1 @@
+5Vrfc6M2EP5rPLk+2APIYHj0j0vuruk0d+5Nrn3pKCDbagSiQo7t/vWVQNiAsMExvkmveUjQSlqJb/fb1Yr0wDTc3jEYr36hASI9ywi2PTDrWZbpAEv8kZJdJgGukQmWDAdq0EEwx/8gJcyHrXGAktJATinhOC4LfRpFyOclGWSMbsrDFpSUV43hEmmCuQ+JLn3EAV9lUtc2DvIPCC9X+cqmoXpCmA9WgmQFA7opiMD7HpgySnn2FG6niEjwclyyebdHevcbYyjibSY4jhfdTieR++fPf7AXO3785AX9YablBZK1emG1Wb7LEWB0HQVIKjF6YLJZYY7mMfRl70bYXMhWPCSiZYpHfVNqny+IcbQtiNQm7xANEWc7MUT19h03m6I8xvQUgJsD/vZIjVkVsc+NApXNl3vdB1jEg0LmDJTsZpSEdWP56EMWNMPEKIcc00g0PYlqgJlw3kyQ0LV8zUmSccE0uoLVLsPqOoORrSFr2TqwwBjYV0LW0ZAllMY9y4GhhCx6SuL09Q1NZE8WlIkOBP2V+PP3GiUpgGJB+euvRDzbM81OAi1etkXCGX1GU0qEOjCLaCRGThaYkIoIEryU9vGFDZCQTyT2WESKseoIcRDIZWqNX2ZRF/YcGY00MV1Lt6Z1LZaYLWhSxeyJck5DgQiKgrEM11JGqP8sSQGTVYqYmfWr5ODI1hbzbxJL4ZhZ6/fcmnmUNfamzeO2qYbOtqo7bewKjQfEsMBCWjeTRcEtJo2xDQWlHKKbjCEi6P5STil1+KupDxSLJY6aGowqJuSQLRFXs4opoKLIbFIkYg/zkaYodYf9+7TykH6wncHk4wP4+GE+nD88fP0yXPbdN5hthmVILGs4sPSwaANDZ1Ihgl5CplqovB8h5YBRBVvzO+abWljzY2UBVxrzNvlGiOxJNk0eI2XqufEpkyDeiOdnJF8cJ1LM2Rrd/NjJR7NsLWtMr+6Y1g1ralNQDWvA+PP+aHCEQOuQ3OMFIjiFOi4kAaLEhcQwEZUGh0LGlAl9SgiME/yUqpUAC59Ys0TE+y9IMcrQjNCQpzqw0b7Sym0Eag4IRk1YM6tZobsTgs4+zSixTD7pwvZEcqhsEMr4ii5pBEnRJBdCe9KVWuM9LJ+vbasG7eucxkC0ntxumefv7o04+vXxNwve9U0dajD+miA255TJovf/xQbTKrPBbUkGcDUDWW+SCyd96bVcGNWBXcOFq2ENNKwJhcG7nzTEj9YniThj87xCUUm5pmZJh6lCxW3GPx2uSoz61HzKHtmxv9nFGusTZTVjYDiOSuyXliz7crTiAg2VxkFRPpAuFgm6tBqpRafF3dd/loB25XJg2I6B+xDYeerXSz/x0gm6ZTTMz2efEhq9y+9x7nEijD4t3OzIoXLIGaStI2jz/cC3wrO8VhC0AO4r7g4EbNkdhefmbaXOBLngoC9t7YqtqsajWbA9v61h9XI1d5QL+W6OKreLnjOwHePwA86k/16vNxh5hZ/yMtk7FbpH5WWOXIwIp4C7wjBF86NvZxnVuzZnAIYnN16dYhleZYp4yPZRr2Dkleb3zfxLSqeBsf6Yrh9NQsiex8k4SjaIoWCa1b1kd04GPZ+MRx0+857m0F5MkCcLkmvf4Ek3LnrxqFI+V79ctKUHsMt63dNqz6ZD557VIue+yWheuou+OBD3xSbsCsHNjgJxperX6pf2kdeuKBKR2P0u4bWw1NHdeU1TGsKrWZ6/jwSdRtf6K8iayvwSDpz4TNJEj1d93iiH3xNhtfsoWvVto5IS234HGVoNio6QpItAKZqHb/7Z8MN/ToD3/wI=
\ No newline at end of file
diff --git a/docs/diagrams/UserStorage_save.drawio b/docs/diagrams/UserStorage_save.drawio
new file mode 100644
index 0000000000..f8630a05c3
--- /dev/null
+++ b/docs/diagrams/UserStorage_save.drawio
@@ -0,0 +1 @@
+5Vpbc6M2FP41ntk+xCMQ18c43qTdprM7TTrZ9qWDQbbVxYgR8m1/fSUQBiFs8LVpm5egowvi+875zkF4AB8WmycapPNfSITigQmizQCOB6ZpONDk/4RlW1gs6BaGGcWRHFQZXvB3JI1AWpc4QpkykBESM5yqxpAkCQqZYgsoJWt12JTE6l3TYIY0w0sYxLr1DUdsXlg9G1T2HxGezcs7G0D2LIJysDRk8yAi65oJfhzAB0oIK64WmwcUC/BKXIp5j3t6dxujKGF9JjiOnzw+jBLvz5//oCs7ffvkR3dWscoqiJfygeVm2bZEgJJlEiGxCBjA0XqOGXpJg1D0rjnn3DZni5i3DH6pb0ruc4UoQ5uaSW7yCZEFYnTLh0gPMXwJ2LrC27akba5iLXmWHM92a1Uw8AuJxBGo2N2ocDZTcRkGNOqGhRIWMEwS3vQFihGm3FkLQ0aW4jFHWeH7BjgTRtkLiwklqJ4zdG0NV9PWYYVgaF8JV0fDNSYkHZhOsBCAJZMszR8eaCZ7NCWUd6AgnOcSkOJQ3C0pG9nAHmskcaiYSkTGKPmGHkjMV4PjhCR85GiK47hhCmI8E+SEnADE7SMBPOaycC87FjiKxG1amVdD5gJk3pkqmy0hYrgtIWJeIEJgshw9bqgfbp9Bmnx+ezWDpztDY3IA73/LEH1hhApJ3Rcvy0X8jKcoxjnMKaKYb0ggPI6l+UtlG3FVZwG3UUlfSOI4SDM8yZcV4PI4WtIMr9CvSAYQ0AjYKS/YeUCp5edqVtlbAi0J8lr4AS38QHAtgsxuCUsJTlh+X3skokelg1A2JzOSBHGdkDOBPehLvdG2bAVstw3slnThXwtrqGGdBSv04QcN8aaITAhjZJFjF1B2L8qVSoJQEpWWSUzCb+UwWSN53fjnwx+xeJg9QnSIDz55hg6Nkx6FIqWC2ssaGALHkcUfRTHPhyu1xmrjRa72RbhqTQ6b8eY2qOU5lYZIzqrXROVC5UAynWaIaR6w2/3pTtGjsvrXBqCtom9Y/SLQuVYAttRr8P5VlAXPOGP/s1wEjfeWi/Sy792Ggn0s2o1c1Ar2DesyT4Oaa/hP/NWYikg4JiW1pB8OHd1+lRDnjd/P9OpCp7tzTGcucnrmojMTj+mqdBtNSduTeC6VVHyNXvnycw6tHeRFQTbPo+wgk9dGHtoN5L1jU34Zzk0KmwsVvqYtxFELtrVhUrH2uwoArfepPKJY8VT/aH3B1sOfU5WhV5Inw08ZST7kDvN58hcK2Xlq0OE2aIPZ19p1LhVDAD3ZHm9KIRGNba1R0/hKaXLZGfqeojxDYMDSUK2Xt7b1VnPF0714V8ualuO1Kv+Zfq65p+8MbQdUf/BUt/eHrl/7U29TPFKt271NUPCng9bBjTenmMBvTFFDSVvAUs9O7prvChd5BWiNRl2ty7JUC7z/dklqGU0Oe9akmjhf7Ciy3NE7K0oP+tGpRal9u6K0HWv9MIqLyRhlIcWpOAU/sy491YHrVeVBJ7l2cSPEua7NrquGi31irQNtdV3v8LJ7RP5Scmj0OBJ5lwXIhSrg8vCKb8J2fTUPXqh48Bo6e6ki2fR49eDdpCSo3Wrv7vyuKR0lQSMd3TU/JF6vJDB6fFo8JgYU1+T98nDYqfm/+JxXRYDRL3COqc4jecT8z7wfSg6h1U/MWlxddQZtocu90rd7hP71oPy6GVUZ8ppC2U/e6kc1B5Nl51mNdZukapnW0DFq2U/VDBcModeLaV2y4OF07ajdvnUd4XTs5hPtl8Bub+XN6rcoxfDqFz3w498=
\ No newline at end of file
diff --git a/docs/images/Architecture.png b/docs/images/Architecture.png
new file mode 100644
index 0000000000..9743bd76a1
Binary files /dev/null and b/docs/images/Architecture.png differ
diff --git a/docs/images/NoteCommandSequence.png b/docs/images/NoteCommandSequence.png
new file mode 100644
index 0000000000..bf59587b75
Binary files /dev/null and b/docs/images/NoteCommandSequence.png differ
diff --git a/docs/images/NoteListClassDiagram.png b/docs/images/NoteListClassDiagram.png
new file mode 100644
index 0000000000..00cc5ef042
Binary files /dev/null and b/docs/images/NoteListClassDiagram.png differ
diff --git a/docs/images/Option.png b/docs/images/Option.png
new file mode 100644
index 0000000000..56652a7c3e
Binary files /dev/null and b/docs/images/Option.png differ
diff --git a/docs/images/OptionSequence.png b/docs/images/OptionSequence.png
new file mode 100644
index 0000000000..d42ff0e01d
Binary files /dev/null and b/docs/images/OptionSequence.png differ
diff --git a/docs/images/ParserDiagram.png b/docs/images/ParserDiagram.png
new file mode 100644
index 0000000000..cbfacc784d
Binary files /dev/null and b/docs/images/ParserDiagram.png differ
diff --git a/docs/images/ParserSampleSequence.png b/docs/images/ParserSampleSequence.png
new file mode 100644
index 0000000000..3230e620b9
Binary files /dev/null and b/docs/images/ParserSampleSequence.png differ
diff --git a/docs/images/QuizQuestionsManager.png b/docs/images/QuizQuestionsManager.png
new file mode 100644
index 0000000000..3e40973778
Binary files /dev/null and b/docs/images/QuizQuestionsManager.png differ
diff --git a/docs/images/QuizQuestionsManager_setQuizQuestions.png b/docs/images/QuizQuestionsManager_setQuizQuestions.png
new file mode 100644
index 0000000000..2f9def7661
Binary files /dev/null and b/docs/images/QuizQuestionsManager_setQuizQuestions.png differ
diff --git a/docs/images/Stats.png b/docs/images/Stats.png
new file mode 100644
index 0000000000..fc7b937f33
Binary files /dev/null and b/docs/images/Stats.png differ
diff --git a/docs/images/Stats_showPointsEarned.png b/docs/images/Stats_showPointsEarned.png
new file mode 100644
index 0000000000..cc8236df63
Binary files /dev/null and b/docs/images/Stats_showPointsEarned.png differ
diff --git a/docs/images/Timer.png b/docs/images/Timer.png
new file mode 100644
index 0000000000..7186982db0
Binary files /dev/null and b/docs/images/Timer.png differ
diff --git a/docs/images/TopicListClassDiagram.png b/docs/images/TopicListClassDiagram.png
new file mode 100644
index 0000000000..a9b8bf6371
Binary files /dev/null and b/docs/images/TopicListClassDiagram.png differ
diff --git a/docs/images/TopicsStorage.png b/docs/images/TopicsStorage.png
new file mode 100644
index 0000000000..f011f983af
Binary files /dev/null and b/docs/images/TopicsStorage.png differ
diff --git a/docs/images/TopicsStorage_load.png b/docs/images/TopicsStorage_load.png
new file mode 100644
index 0000000000..a1289bf0bc
Binary files /dev/null and b/docs/images/TopicsStorage_load.png differ
diff --git a/docs/images/Ui.png b/docs/images/Ui.png
new file mode 100644
index 0000000000..d0ff686343
Binary files /dev/null and b/docs/images/Ui.png differ
diff --git a/docs/images/UserStorage.png b/docs/images/UserStorage.png
new file mode 100644
index 0000000000..ff96be2f16
Binary files /dev/null and b/docs/images/UserStorage.png differ
diff --git a/docs/images/UserStorage_load.png b/docs/images/UserStorage_load.png
new file mode 100644
index 0000000000..2011b6a9b3
Binary files /dev/null and b/docs/images/UserStorage_load.png differ
diff --git a/docs/images/UserStorage_save.png b/docs/images/UserStorage_save.png
new file mode 100644
index 0000000000..e060c2bfc4
Binary files /dev/null and b/docs/images/UserStorage_save.png differ
diff --git a/docs/images/about.png b/docs/images/about.png
new file mode 100644
index 0000000000..5825a05645
Binary files /dev/null and b/docs/images/about.png differ
diff --git a/docs/images/bookmark_delete.png b/docs/images/bookmark_delete.png
new file mode 100644
index 0000000000..003ee12cc9
Binary files /dev/null and b/docs/images/bookmark_delete.png differ
diff --git a/docs/images/bookmark_list.png b/docs/images/bookmark_list.png
new file mode 100644
index 0000000000..d92735e91a
Binary files /dev/null and b/docs/images/bookmark_list.png differ
diff --git a/docs/images/bookmark_store.png b/docs/images/bookmark_store.png
new file mode 100644
index 0000000000..c6fe047f5e
Binary files /dev/null and b/docs/images/bookmark_store.png differ
diff --git a/docs/images/data_error.png b/docs/images/data_error.png
new file mode 100644
index 0000000000..eed2e79f94
Binary files /dev/null and b/docs/images/data_error.png differ
diff --git a/docs/images/data_loaded.png b/docs/images/data_loaded.png
new file mode 100644
index 0000000000..ba1c3a8386
Binary files /dev/null and b/docs/images/data_loaded.png differ
diff --git a/docs/images/data_loading.png b/docs/images/data_loading.png
new file mode 100644
index 0000000000..88a84596e2
Binary files /dev/null and b/docs/images/data_loading.png differ
diff --git a/docs/images/data_saved.png b/docs/images/data_saved.png
new file mode 100644
index 0000000000..54b7d3a495
Binary files /dev/null and b/docs/images/data_saved.png differ
diff --git a/docs/images/data_saving.png b/docs/images/data_saving.png
new file mode 100644
index 0000000000..430fd569d1
Binary files /dev/null and b/docs/images/data_saving.png differ
diff --git a/docs/images/exit.png b/docs/images/exit.png
new file mode 100644
index 0000000000..ec9150495b
Binary files /dev/null and b/docs/images/exit.png differ
diff --git a/docs/images/help.png b/docs/images/help.png
new file mode 100644
index 0000000000..e23a391414
Binary files /dev/null and b/docs/images/help.png differ
diff --git a/docs/images/hint.png b/docs/images/hint.png
new file mode 100644
index 0000000000..12f5ff7211
Binary files /dev/null and b/docs/images/hint.png differ
diff --git a/docs/images/noteadd.png b/docs/images/noteadd.png
new file mode 100644
index 0000000000..695f094252
Binary files /dev/null and b/docs/images/noteadd.png differ
diff --git a/docs/images/notedelete.png b/docs/images/notedelete.png
new file mode 100644
index 0000000000..79087c66b4
Binary files /dev/null and b/docs/images/notedelete.png differ
diff --git a/docs/images/notelist.png b/docs/images/notelist.png
new file mode 100644
index 0000000000..f81742e26f
Binary files /dev/null and b/docs/images/notelist.png differ
diff --git a/docs/images/question_end.png b/docs/images/question_end.png
new file mode 100644
index 0000000000..250e574f3b
Binary files /dev/null and b/docs/images/question_end.png differ
diff --git a/docs/images/quiz.png b/docs/images/quiz.png
new file mode 100644
index 0000000000..b0c9cc8a47
Binary files /dev/null and b/docs/images/quiz.png differ
diff --git a/docs/images/quiz_correct.png b/docs/images/quiz_correct.png
new file mode 100644
index 0000000000..374c4241ae
Binary files /dev/null and b/docs/images/quiz_correct.png differ
diff --git a/docs/images/quiz_end.png b/docs/images/quiz_end.png
new file mode 100644
index 0000000000..a404c84a19
Binary files /dev/null and b/docs/images/quiz_end.png differ
diff --git a/docs/images/quiz_times_up.png b/docs/images/quiz_times_up.png
new file mode 100644
index 0000000000..9141566705
Binary files /dev/null and b/docs/images/quiz_times_up.png differ
diff --git a/docs/images/quiz_wrong.png b/docs/images/quiz_wrong.png
new file mode 100644
index 0000000000..4407957da9
Binary files /dev/null and b/docs/images/quiz_wrong.png differ
diff --git a/docs/images/stats_No_Progress.png b/docs/images/stats_No_Progress.png
new file mode 100644
index 0000000000..e9c4c142cf
Binary files /dev/null and b/docs/images/stats_No_Progress.png differ
diff --git a/docs/images/stats_Some_Progress.png b/docs/images/stats_Some_Progress.png
new file mode 100644
index 0000000000..47f776e6a0
Binary files /dev/null and b/docs/images/stats_Some_Progress.png differ
diff --git a/docs/images/textbook.png b/docs/images/textbook.png
new file mode 100644
index 0000000000..2cfb9a69c8
Binary files /dev/null and b/docs/images/textbook.png differ
diff --git a/docs/images/topiclistsequence.png b/docs/images/topiclistsequence.png
new file mode 100644
index 0000000000..c6e4086d22
Binary files /dev/null and b/docs/images/topiclistsequence.png differ
diff --git a/docs/images/topics.png b/docs/images/topics.png
new file mode 100644
index 0000000000..129d4ff06c
Binary files /dev/null and b/docs/images/topics.png differ
diff --git a/docs/images/user_data_error.png b/docs/images/user_data_error.png
new file mode 100644
index 0000000000..e41231fe54
Binary files /dev/null and b/docs/images/user_data_error.png differ
diff --git a/docs/images/welcome.png b/docs/images/welcome.png
new file mode 100644
index 0000000000..846ebd48d6
Binary files /dev/null and b/docs/images/welcome.png differ
diff --git a/docs/team/anqi20.md b/docs/team/anqi20.md
new file mode 100644
index 0000000000..6a31200b63
--- /dev/null
+++ b/docs/team/anqi20.md
@@ -0,0 +1,47 @@
+# Lim An Qi - Project Portfolio Page
+
+## Overview
+
+E-Duke-8 (pronounced "Educate") helps CS2113/T students learn and understand software engineering and Object-Oriented Programming (OOP) principles through a gamified platform and enhances their learning experience.
+
+## Summary of Contributions
+
+- **New Feature:** Implemented the timer function for the quiz
+ - What it does: The user would be able to choose the timer set for each question. If the time is up, and the user have yet to complete the question, then it will be marked as an incorrect answer.
+ - Justification: E-Duke-8 is able to simulate a timed examination environment for the students. Moreover, since they get to choose the timing , E-Duke-8 is able to cater to all students at different learning stages.
+ - Highlights: This timer feature is challenging as we had to cater to users using different operating systems. In the User Interface, there is two ways to detect the time passed when the user has not inputted anything.
+ Kingston has helped in implementing this feature for the Windows Operating System (OS) while I worked on implementing this feature for the MacOS and Linux Operating System.
+ The implementation in Windows OS uses the Robot object which cannot be used in the implementation in the MacOS and Linux as they are a headless environment.
+- **New Feature:** Added delay between each question during the quiz
+ - What it does: The users need to press the "Enter" button on the computer before they can proceed to the next question.
+ - Justification: This allows the users to read and understand the explanation of the question first, before moving on to the next question. This makes the quiz function more effective in helping the students to revise.
+- **New Feature:** Implemented the User Interface (UI) class
+ - What it does: It would be the point of contact between E-Duke-8 and the users. It would take in input from the user while printing out prompts for the users to read.
+ - Justification: This also allows the users to know if the command they give is successfully handled by E-Duke-8. This is because, E-Duke-8 will echo back if it is a successful command, and tells the user the error if it is an unsuccessful command.
+- **New Feature:** Implemented the `Option` and `OptionList` classes
+ - What it does: The `Option` class holds the one of the option of a question while the `OptionList` class holds all 4 options of the same question.
+ - Justification: When we have classes for the `Option` and `OptionList`, our program will be more Object-oriented, which brings about many benefits.
+
+- **Code contributed:** [RepoSense link](https://nus-cs2113-ay2021s1.github.io/tp-dashboard/#breakdown=true&search=&sort=groupTitle&sortWithin=title&since=2020-09-27&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other&tabOpen=true&tabType=authorship&tabAuthor=anqi20&tabRepo=AY2021S1-CS2113T-F12-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other)
+
+- **Enhancements to existing features:**
+ - Implemented testing for IncompleteCommand. [#256](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/256)
+ - Added explanations class. [#118](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/118)
+ - Implemented the UI class to do error handling. [#79](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/79)
+ - Implemented some testing for Option and OptionList classes. [#65](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/65)
+
+- **Documentation:**
+ - User Guide:
+ - Did cosmetic tweaks to existing documentation of features: [#165](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/165), [#222](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/222)
+ - Added documentation for the timer feature in `quiz` system. [#165](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/165)
+ - Added documentation for the Command Summary. [#165](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/165)
+
+ - Developer Guide:
+ - Added the implementation of timer feature [#222](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/222)
+ - Added the design and implementation of Option and OptionList classes [#125](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/125), [#165](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/165)
+ - Added the user stories of V1.0 and V2.0 [#125](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/125)
+ - Added the implementation of User Interface [#125](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/125)
+
+- **Community:**
+ - PRs reviewed (with non-trivial review comments): [#34](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/34), [#46](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/46), [#51](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/51), [#67](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/67), [#124](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/124)
+ - Reported bugs and suggestions for other teams in the class. (examples: [1](https://github.com/anqi20/ped/issues/1), [2](https://github.com/anqi20/ped/issues/2), [3](https://github.com/anqi20/ped/issues/5), [4](https://github.com/anqi20/ped/issues/7), [5](https://github.com/anqi20/ped/issues/8), [6](https://github.com/anqi20/ped/issues/11), [7](https://github.com/anqi20/ped/issues/12))
diff --git a/docs/team/joelngyx.md b/docs/team/joelngyx.md
new file mode 100644
index 0000000000..186d3a7c8c
--- /dev/null
+++ b/docs/team/joelngyx.md
@@ -0,0 +1,57 @@
+# Joel Ng Yi Xian - Project Portfolio Page
+
+## Overview:
+
+E-Duke-8 (pronounced "Educate") helps CS2113/T students learn and understand software engineering and Object-Oriented Programming (OOP) principles through a gamified platform and enhances their learning experience.
+
+
+## Summary of Contributions:
+
+- **New Feature:** Topic and TopicList components.
+ - What it does: The TopicList component stores Topic objects, each of which stores the description, note list and question list of the topic.
+ - Justification: Necessary for the compartmentalization of data
+
+- **New Feature:** Implemented the NoteCommand component
+ - What it does: This command is a type Command object. Entering an input containing the following formats: `note add`,
+ `note delete`, `note list` will throw this command and process the instruction provided.
+ - Justification: Necessary to add/delete/list notes.
+ - Highlight: This feature required the use of logic, as well as interactions with various classes such as `TopicList`,
+ `Ui`, `NoteList` and `Note`. Methods were added to the `Ui` class to allow for a more user-friendly way of providing
+ inputs when it comes to creating/deleting/listing out `Note` objects in the specified `NoteList` object.
+
+- **New Feature:** Implemented the Note and NoteList components.
+ - What it does: The NoteList components store Note objects, and contains methods that can modify the NoteList object.
+ - Justification: Necessary to process and carry out the NoteCommand.
+
+- **Code contributed:** [RepoSense link](https://nus-cs2113-ay2021s1.github.io/tp-dashboard/#breakdown=true&search=joelngyx&sort=groupTitle&sortWithin=title&since=2020-09-27&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other&tabOpen=false)
+
+- **Enhancements to existing features:**
+ - Removed redundant code in the DisplayableList interface which allowed for the better implementation of features.
+ Made necessary additions and amendments to various classes and JUnits tests. [#122](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/122)
+ - Made necessary additions and amendments to the UserStorage class to accommodate improvements made to the `Note` and `NoteList` classes.
+ [#144](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/144/commits)
+
+- **Contributions to documentation**
+ - User Guide:
+ - Added documentation for the adding, deleting, and the listing of notes:
+ [#207](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/207/files)
+ - Developer Guide:
+ - Added design and implementation details of the Topic and TopicList components
+ [Design of TopicList](https://ay2021s1-cs2113t-f12-3.github.io/tp/DeveloperGuide.html#221-design-of-topiclist),
+ [Implementation of TopicList](https://ay2021s1-cs2113t-f12-3.github.io/tp/DeveloperGuide.html#222-implementation-of-topiclist)
+ - Added design and implementation details of the Note and NoteList components
+ [Design of NoteList](https://ay2021s1-cs2113t-f12-3.github.io/tp/DeveloperGuide.html#223-design-of-notelist),
+ [Implementation of Notes](https://ay2021s1-cs2113t-f12-3.github.io/tp/DeveloperGuide.html#224-implementation-of-notes)
+ - Added UML and sequence diagrams relevant to the Topic, TopicList, Note and NoteList components, as seen in the links above.
+
+- **Community:**
+ - PRs reviewed (with non-trivial review comments):
+ [#216](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/216),
+ [#51](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/51),
+ [#22](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/22)
+ - Reported bugs for other teams in the class:
+ [#1](https://github.com/joelngyx/ped/issues/1),
+ [#2](https://github.com/joelngyx/ped/issues/2)
+
+
+
diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md
deleted file mode 100644
index ab75b391b8..0000000000
--- a/docs/team/johndoe.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# John Doe - Project Portfolio Page
-
-## Overview
-
-
-### Summary of Contributions
diff --git a/docs/team/josephhhhhhhhh.md b/docs/team/josephhhhhhhhh.md
new file mode 100644
index 0000000000..e3b41527df
--- /dev/null
+++ b/docs/team/josephhhhhhhhh.md
@@ -0,0 +1,35 @@
+# Joseph Abraham - Project Portfolio Page
+
+## Overview
+E-Duke-8 (pronounced "Educate") helps CS2113/T students learn and understand software engineering and Object-Oriented Programming (OOP) principles through a gamified platform and enhances their learning experience.
+
+
+### Summary of Contributions
+
+- **New Feature:** Added the functionality to be able to bookmark questions during a quiz.
+ - What it does: Store's a question of the user's choice in an array list of type `Displayable`. Whenever the user is in a quiz and wishes to store a particular question of interest for the future, the user can
+ type in `bookmark` in the command-line, and the question will be stored. Once the user finishes the quiz, the user may type `bookmark list` in the main menu to view the list of bookmarked question,
+ at which point, each question's options will be printed under the question, with the words "[Correct Answer]" next to the option whose attribute `isCorrectAnswer` is true.
+ The user may also delete a bookmark by typing `bookmark delete `, at which point the question indicated will be deleted.
+ - Justification: This feature is important in terms of using the product, as from time to time questions that are hard to figure out may get tested, and the user
+ would want to have a way to store this question for perusal later. By consolidating all these bookmarks in one place, the user is capable of referring to all the questions that they have had doubts about
+ in one central location. This makes revising an easier process as well.
+ - Highlights: This command requires interaction with the `Ui`, `Question` and `Option` classes in order to be able to store and display the questions effectively. It requires altering the code of some pre-existing
+ commands, and required some fine-tuning to ensure the `Ui` object was responding with the correct statements whenever prompted.
+
+- **Code contributed:** [RepoSense Link](https://nus-cs2113-ay2021s1.github.io/tp-dashboard/#breakdown=true&search=&sort=groupTitle&sortWithin=title&since=2020-09-27&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other&tabOpen=true&tabType=authorship&tabAuthor=josephhhhhhhhh&tabRepo=AY2021S1-CS2113T-F12-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other)
+
+- **Enhancements to existing features:**
+ - Increased flexibility of parsing quiz commands by allowing the topic field and number of questions field to be interchangeable in position. (Pull request [#126](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/126))
+ - Added parser logic in order to be able to read in additional white spaces without losing the user input. (Pull request [#227](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/227))
+ - Implemented JUnit Testing for some Command classes, BookmarkList class and Parser classes . (Pull request [#226](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/226), [#132](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/132))
+
+- **Documentation:**
+ - User Guide:
+ - Added documentation for the `bookmark` feature. [#169](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/169)
+ - Developer Guide:
+ - Added documentation for the Logic Component of the Developer Guide. [#123](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/123), [#138](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/138)
+
+- **Community:**
+ - PRs reviewed (with non-trivial review comments): [#51](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/51), [#59](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/59), [#207](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/207), [#212](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/212)
+ - Reported bugs and suggestions for other teams in the class. [#1](https://github.com/josephhhhhhhhh/ped/issues/1), [#2](https://github.com/josephhhhhhhhh/ped/issues/2), [#3](https://github.com/josephhhhhhhhh/ped/issues/3), [#4](https://github.com/josephhhhhhhhh/ped/issues/4), [#5](https://github.com/josephhhhhhhhh/ped/issues/5), [#6](https://github.com/josephhhhhhhhh/ped/issues/6), [#7](https://github.com/josephhhhhhhhh/ped/issues/7), [#8](https://github.com/josephhhhhhhhh/ped/issues/8)
\ No newline at end of file
diff --git a/docs/team/kstonekuan.md b/docs/team/kstonekuan.md
new file mode 100644
index 0000000000..400be2a8c8
--- /dev/null
+++ b/docs/team/kstonekuan.md
@@ -0,0 +1,43 @@
+# Kingston Kuan Jun Xiang - Project Portfolio Page
+
+## Overview
+
+E-Duke-8 (pronounced "Educate") helps CS2113/T students learn and understand software engineering and Object-Oriented Programming (OOP) principles through a gamified platform and enhances their learning experience.
+
+## Summary of Contributions
+
+- **New Feature:** Implemented and maintained the Storage component.
+ - What it does: `LogStorage` saves logging data, `TopicsStorage` loads topic data and `UserStorage` saves and loads user data locally.
+ - Justification: This feature improves the product significantly because a user does not need to add questions manually for the quiz through the CLI, the user's statistics will be stored which enhances gamification, and user logs are available to identfy causes of bugs in the application.
+ - Highlights: The saving of user data does not actually require the implementation of a `User` class as the user attributes for each question are extracted directly from the question.
+ This design was chosen so as to not increase the overall complexity of the system.
+ The error handling was also challenging as the files save locally are easily editable by the user.
+ For `TopicsStorage`, if the format of the JSON file is not correct then the program will not startup and users will be directed to instructions to fix this instead.
+ For `UserStorage`, if the user chooses to tamper with the user data, badly formatted data will result in a safe loss of data and the program will continue to run.
+ Furthermore, as it is not guaranteed that users will download the default data file, this was included as a resource in the jar file to allow normal operation while still allowing edits though the external path.
+ - Credits: This feature relies heavily on the use of the `JSON.simple` library as data is stored in JSON format.
+- **New Feature:** Implemented the initial quiz logic to be a separate interface from the main menu.
+
+- **Code contributed:** [RepoSense link](https://nus-cs2113-ay2021s1.github.io/tp-dashboard/#breakdown=true&search=kstonekuan&sort=groupTitle&sortWithin=title&since=2020-09-27&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other)
+
+- **Project management:**
+ - Managed releases `v1.0` - `v2.1` (3 releases) on GitHub
+
+
+
+- **Enhancements to existing features:**
+ - Implemented a fix for problems with the timer feature on Windows for command prompt/powershell. The user input was no showing up due to the use of the `BufferedReader` instead of the usual `Scanner`. The workaround used `Future` and `ExecutorService` to get the user input asynchronously in a separate thread while allowing for a `TimeoutException` to be used for the timer. However, this required the use of a `Robot` to complete the `Future` which did not work in headless environments like WSL. I recommened for this to be fixed in a separate issue by doing an OS-dependent timer. (Pull requests [#158](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/158))
+
+- **Documentation:**
+ - User Guide:
+ - Added documentation for loading and saving data [#100](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/100), [#211](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/211)
+ - Developer Guide:
+ - Added implementation details of the Storage component [#116](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/116), [#142](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/142), [#152](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/152)
+
+- **Community:**
+ - PRs reviewed (with non-trivial review comments): [#23](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/23), [#46](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/46), [#59](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/59), [#91](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/91), [#125](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/125), [#132](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/132), [#145](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/145), [#150](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/150)
+ - Contributed to forum discussions (examples: [1](https://github.com/nus-cs2113-AY2021S1/forum/issues/64), [2](https://github.com/nus-cs2113-AY2021S1/forum/issues/79), [3](https://github.com/nus-cs2113-AY2021S1/forum/issues/47), [4](https://github.com/nus-cs2113-AY2021S1/forum/issues/56), [5](https://github.com/nus-cs2113-AY2021S1/forum/issues/91), [6](https://github.com/nus-cs2113-AY2021S1/forum/issues/117))
+ - Reported bugs and suggestions for other teams in the class (examples: [1](https://github.com/kstonekuan/ped/issues/4), [2](https://github.com/kstonekuan/ped/issues/2), [3](https://github.com/kstonekuan/ped/issues/6), [4](https://github.com/kstonekuan/ped/issues/5))
+
+- **Tools:**
+ - Integrated a third party library (JSON.simple) to the project ([#13](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/13))
\ No newline at end of file
diff --git a/docs/team/zhi-you.md b/docs/team/zhi-you.md
new file mode 100644
index 0000000000..9b7434258e
--- /dev/null
+++ b/docs/team/zhi-you.md
@@ -0,0 +1,40 @@
+# Tang Zhi You - Project Portfolio Page
+
+## Overview
+
+E-Duke-8 (pronounced "Educate") helps CS2113/T students learn and understand software engineering and Object-Oriented Programming (OOP) principles through a gamified platform and enhances their learning experience.
+
+
+## Summary of Contributions
+
+- **New Feature:** Added the ability for users to earn points from answering questions in quizzes and view their quiz attempts' statistics.
+ - What it does: Calculates user's aggregated quiz statistics using `UserStatsCalculator` and calculates their topic-level quiz statistics using `TopicalStatsCalculator`. Relevant statistics include how accurate they are and the points they have earned from answering questions in quizzes. When the user gives the command to show his or her statistics, the relevant data will be calculated and displayed clearly to him or her.
+ - Justification: This feature improves the product significantly because it allows users to understand how well they did for the quizzes on a topical level and hence allows them to keep track of their learning progress across CS2113/T topics. By having a point system for the quiz and recording their stats, users will feel rewarded as they get the right answers and become motivated to attempt more quizzes to improve their current stats. Therefore, the addition of this feature enables E-Duke-8 to better achieve its objectives of gamifying the learning process for CS2113/T students.
+ - Highlights: Due to its complete implementation, the calculation of the statistics is not limited to the current number of questions and topics in E-Duke-8, hence allowing the project to grow smoothly in terms of adding more topics and questions. While alternative designs were discussed, the current one was chosen as it provides users with a clear summary page of their statistics. Since the feature is one of the last few features to implement and there had to be a wait for the others to be finalized, the implementation was challenging due to the short timeframe to complete it before v2.0. In-depth planning had to be done in order to get it completed in time.
+
+
+
+- **New Feature:** Implemented the logic to start a quiz with randomly selected questions and facilitate the process of the quiz.
+ - What it does: Based on the user's specified number of questions and topic, `QuizQuestionsManager` randomly selects the indicated number of questions from the list of questions of the indicated topic at the start of the quiz. It also ensures that a quiz will not have duplicated questions. Furthermore, It provides the ability to navigate to the next question, and the ability to determine the end of the quiz.
+ - Justification: The random selection of questions will ensure that users get a variety of questions from the topic.
+
+- **Code contributed:** [RepoSense link](https://nus-cs2113-ay2021s1.github.io/tp-dashboard/#breakdown=true&search=zhi-you&sort=groupTitle&sortWithin=title&since=2020-09-27&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other)
+
+- **Enhancements to existing features:**
+ - Personalized the project by changing packages' names and settings. (Pull request [#33](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/33))
+ - Improved display messages to enhance user experience. (Pull request [#90](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/90))
+
+- **Documentation:**
+ - User Guide:
+ - Added documentation for `quiz` system and `stats` feature. [#130](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/130), [#146](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/146)
+ - Did cosmetic tweaks and maintained existing overall documentation. [#103](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/103), [#140](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/140)
+ - Developer Guide:
+ - Added design and implementation details of the `quiz` feature. [#124](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/124), [#167](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/167)
+ - Added design and implementation details of the `stats` feature. [#143](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/143), [#145](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/145), [#209](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/209)
+ - Did cosmetic tweaks to existing overall documentation. [#129](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/129)
+
+- **Community:**
+ - PRs reviewed (with non-trivial review comments): [#39](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/39), [#46](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/46), [#51](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/51), [#56](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/56), [#79](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/79), [#125](https://github.com/AY2021S1-CS2113T-F12-3/tp/pull/125)
+ - Contributed to forum discussions (example: [1](https://github.com/nus-cs2113-AY2021S1/forum/issues/77))
+ - Reported bugs and suggestions for other teams in the class (examples: [1](https://github.com/Zhi-You/ped/issues/3), [2](https://github.com/Zhi-You/ped/issues/4), [3](https://github.com/Zhi-You/ped/issues/7), [4](https://github.com/Zhi-You/ped/issues/8), [5](https://github.com/Zhi-You/ped/issues/9))
+
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..83cdad37b1
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: seedu.eduke8.Eduke8
+
diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java
deleted file mode 100644
index 5c74e68d59..0000000000
--- a/src/main/java/seedu/duke/Duke.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package seedu.duke;
-
-import java.util.Scanner;
-
-public class Duke {
- /**
- * Main entry-point for the java.duke.Duke application.
- */
- public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
- System.out.println("What is your name?");
-
- Scanner in = new Scanner(System.in);
- System.out.println("Hello " + in.nextLine());
- }
-}
diff --git a/src/main/java/seedu/eduke8/Eduke8.java b/src/main/java/seedu/eduke8/Eduke8.java
new file mode 100644
index 0000000000..c99b708f96
--- /dev/null
+++ b/src/main/java/seedu/eduke8/Eduke8.java
@@ -0,0 +1,122 @@
+package seedu.eduke8;
+
+import org.json.simple.parser.ParseException;
+import seedu.eduke8.bookmark.BookmarkList;
+import seedu.eduke8.command.Command;
+import seedu.eduke8.exception.Eduke8Exception;
+import seedu.eduke8.parser.MenuParser;
+import seedu.eduke8.storage.LogStorage;
+import seedu.eduke8.storage.TopicsStorage;
+import seedu.eduke8.storage.UserStorage;
+import seedu.eduke8.topic.TopicList;
+import seedu.eduke8.ui.Ui;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static seedu.eduke8.exception.ExceptionMessages.ERROR_STORAGE_LOAD_FAIL;
+import static seedu.eduke8.exception.ExceptionMessages.ERROR_STORAGE_SAVE_FAIL;
+import static seedu.eduke8.exception.ExceptionMessages.ERROR_USER_JSON_LOAD;
+
+public class Eduke8 {
+ private static final String DATA_PATH = "data/main/topics.json";
+ private static final LocalDateTime DATE_TIME_NOW = LocalDateTime.now();
+ private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
+ private static final String LOG_PATH = "data/logs/" + DATE_TIME_NOW.format(DATE_TIME_FORMATTER) + ".log";
+ private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+ private static final String USER_PATH = "data/main/user.json";
+
+ private MenuParser menuParser;
+ private TopicsStorage topicsStorage;
+ private UserStorage userStorage;
+ private LogStorage logStorage;
+ private TopicList topicList;
+ private BookmarkList bookmarkList;
+ private Ui ui;
+
+ private Eduke8(String dataPath, String logPath, String userPath) {
+ ui = new Ui();
+ bookmarkList = new BookmarkList();
+
+ ui.printDataLoading();
+ try {
+ topicsStorage = new TopicsStorage(dataPath);
+ logStorage = new LogStorage(logPath);
+
+ logStorage.save();
+ topicList = new TopicList(topicsStorage.load());
+ } catch (ParseException | IOException | ClassCastException | NullPointerException e) {
+ ui.printError(ERROR_STORAGE_LOAD_FAIL);
+ LOGGER.log(Level.WARNING, ERROR_STORAGE_LOAD_FAIL);
+ System.exit(1);
+ } catch (Eduke8Exception e) {
+ ui.printError(e.getMessage());
+ LOGGER.log(Level.INFO, e.getMessage());
+ System.exit(1);
+ }
+
+ userStorage = new UserStorage(userPath, topicList, bookmarkList);
+ try {
+ userStorage.load();
+ } catch (IOException | ParseException | ClassCastException | NullPointerException e) {
+ ui.printError(ERROR_USER_JSON_LOAD);
+ LOGGER.log(Level.WARNING, ERROR_USER_JSON_LOAD);
+ } catch (Eduke8Exception e) {
+ ui.printError(e.getMessage());
+ LOGGER.log(Level.INFO, e.getMessage());
+ }
+
+ ui.printDataLoaded();
+
+ menuParser = new MenuParser(bookmarkList);
+ }
+
+ private void run() {
+ start();
+ runCommandLoopUntilExit();
+ exit();
+ }
+
+ private void start() {
+ ui.printGreetMessage();
+ }
+
+ private void runCommandLoopUntilExit() {
+ boolean isExit = false;
+
+ while (!isExit) {
+ String userInput = ui.getInputFromUser();
+
+ Command command = menuParser.parseCommand(topicList, userInput);
+ command.execute(topicList, ui);
+ isExit = command.isExit();
+ saveUserData();
+ }
+ }
+
+ private void exit() {
+ ui.printDataSaving();
+ saveUserData();
+ ui.printDataSaved();
+
+ ui.printExitMessage();
+ System.exit(0);
+ }
+
+ private void saveUserData() {
+ try {
+ userStorage.save();
+ } catch (IOException e) {
+ ui.printError(ERROR_STORAGE_SAVE_FAIL);
+ LOGGER.log(Level.WARNING, ERROR_STORAGE_SAVE_FAIL);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String[] args) {
+ new Eduke8(DATA_PATH, LOG_PATH, USER_PATH).run();
+ }
+}
diff --git a/src/main/java/seedu/eduke8/bookmark/BookmarkList.java b/src/main/java/seedu/eduke8/bookmark/BookmarkList.java
new file mode 100644
index 0000000000..60e4db1f88
--- /dev/null
+++ b/src/main/java/seedu/eduke8/bookmark/BookmarkList.java
@@ -0,0 +1,53 @@
+package seedu.eduke8.bookmark;
+
+import seedu.eduke8.common.Displayable;
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.common.EditableList;
+import seedu.eduke8.question.Question;
+
+import java.util.ArrayList;
+
+/**
+ * Represents the structure that stores the bookmarked questions.
+ */
+public class BookmarkList implements DisplayableList, EditableList {
+
+ private ArrayList bookmarks;
+
+ public BookmarkList() {
+ bookmarks = new ArrayList<>();
+ }
+
+ @Override
+ public ArrayList getInnerList() {
+ return bookmarks;
+ }
+
+ @Override
+ public void add(Displayable question) {
+ assert question != null; // Exception in future if user can add question
+ bookmarks.add(question);
+ ((Question) question).markAsBookmarked();
+ }
+
+ @Override
+ public Displayable delete(int index) {
+ assert (index >= 0 && index < bookmarks.size()); // Exception in future if user can delete question
+ return bookmarks.remove(index);
+ }
+
+ @Override
+ public Displayable find(String description) {
+ for (Displayable question : bookmarks) {
+ if (description.equalsIgnoreCase(question.getDescription())) {
+ return question;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public int getCount() {
+ return bookmarks.size();
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/AboutCommand.java b/src/main/java/seedu/eduke8/command/AboutCommand.java
new file mode 100644
index 0000000000..6de8c96537
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/AboutCommand.java
@@ -0,0 +1,20 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.stats.Stats;
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * Represents the specific command that prints a message to the user with a description of what the program does.
+ */
+public class AboutCommand extends Command {
+
+ public AboutCommand() {
+ super();
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ ui.printAbout();
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/AnswerCommand.java b/src/main/java/seedu/eduke8/command/AnswerCommand.java
new file mode 100644
index 0000000000..74340c838d
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/AnswerCommand.java
@@ -0,0 +1,39 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.exception.Eduke8Exception;
+import seedu.eduke8.option.Option;
+import seedu.eduke8.option.OptionList;
+import seedu.eduke8.question.Question;
+import seedu.eduke8.ui.Ui;
+
+public class AnswerCommand extends Command {
+ private Option option;
+ private Question question;
+
+ public AnswerCommand(Option option, Question question) {
+ super();
+ assert option != null && question != null;
+
+ this.option = option;
+ this.question = question;
+ }
+
+ @Override
+ public void execute(DisplayableList optionList, Ui ui) {
+ String explanation = question.getExplanation().getDescription();
+
+ if (option.isCorrectAnswer()) {
+ ui.printAnswerIsCorrect(explanation);
+ question.markAsAnsweredCorrectly();
+ assert question.wasAnsweredCorrectly();
+ } else {
+ try {
+ int correctOptionNumber = ((OptionList) optionList).findCorrectOptionIndex() + 1;
+ ui.printAnswerIsWrong(correctOptionNumber, explanation);
+ } catch (Eduke8Exception e) {
+ ui.printError(e.getMessage());
+ }
+ }
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/BookmarkCommand.java b/src/main/java/seedu/eduke8/command/BookmarkCommand.java
new file mode 100644
index 0000000000..56ad32d6af
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/BookmarkCommand.java
@@ -0,0 +1,82 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.bookmark.BookmarkList;
+import seedu.eduke8.common.Displayable;
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.exception.Eduke8Exception;
+import seedu.eduke8.question.Question;
+import seedu.eduke8.ui.Ui;
+
+import static seedu.eduke8.exception.ExceptionMessages.ERROR_BOOKMARK_NONE;
+
+/**
+ * The specific command to manage bookmarked questions in E-Duke-8.
+ */
+public class BookmarkCommand extends Command {
+ private static final String BOOKMARK_LIST = "listing";
+ private static final String BOOKMARK_STORE = "storing";
+ private static final String BOOKMARK_DELETE = "delete";
+
+ private BookmarkList bookmarkList;
+ private Question question;
+ private boolean alreadyBookmarked = false;
+ private int deleteIndex = 0;
+ String typeOfBookmarkCommand = "";
+
+ public BookmarkCommand(Question question, String typeOfBookmarkCommand, BookmarkList bookmarkList) {
+ super();
+ assert bookmarkList != null;
+ this.question = question;
+ if (question.isBookmarked()) {
+ alreadyBookmarked = true;
+ } else {
+ bookmarkList.add(question);
+ }
+ this.bookmarkList = bookmarkList;
+ this.typeOfBookmarkCommand = typeOfBookmarkCommand;
+ }
+
+ public BookmarkCommand(String typeOfBookmarkCommand, BookmarkList bookmarkList) throws Eduke8Exception {
+ this.typeOfBookmarkCommand = typeOfBookmarkCommand;
+ this.bookmarkList = bookmarkList;
+ if (bookmarkList.getCount() == 0) {
+ throw new Eduke8Exception(ERROR_BOOKMARK_NONE);
+ }
+ }
+
+ public BookmarkCommand(int deleteIndex, String typeOfBookmarkCommand, BookmarkList bookmarkList)
+ throws Eduke8Exception {
+ if (bookmarkList.getCount() == 0) {
+ throw new Eduke8Exception(ERROR_BOOKMARK_NONE);
+ }
+ this.typeOfBookmarkCommand = typeOfBookmarkCommand;
+ this.bookmarkList = bookmarkList;
+ this.deleteIndex = deleteIndex;
+
+ int currentIndex = 0;
+ for (Displayable question : bookmarkList.getInnerList()) {
+ currentIndex++;
+ if (currentIndex == deleteIndex) {
+ Question castedQuestion = (Question) question;
+ castedQuestion.markAsNotBookmarked();
+ }
+ }
+ bookmarkList.delete(deleteIndex - 1);
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ if (typeOfBookmarkCommand.equals(BOOKMARK_LIST)) {
+ ui.printListOfBookmarkedQuestions(bookmarkList);
+ } else if (typeOfBookmarkCommand.equals(BOOKMARK_STORE)) {
+ if (alreadyBookmarked) {
+ ui.printAlreadyBookmarkedIndicator();
+ } else {
+ ui.printBookmarkedIndicator();
+ }
+ } else if (typeOfBookmarkCommand.equals(BOOKMARK_DELETE)) {
+ ui.printDeletedBookmarkIndicator(deleteIndex);
+ }
+ }
+}
+
diff --git a/src/main/java/seedu/eduke8/command/Command.java b/src/main/java/seedu/eduke8/command/Command.java
new file mode 100644
index 0000000000..6dc8f5f4f5
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/Command.java
@@ -0,0 +1,31 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * Represents an executable command.
+ */
+public abstract class Command {
+ protected boolean isExit;
+
+ public Command() {
+ isExit = false;
+ }
+
+ /**
+ * Carries out the command and returns the outcome of the execution.
+ * @param displayableList an object from a class that extends the DisplayableList interface
+ * @param ui a Ui object to manage user interactions
+ */
+ public abstract void execute(DisplayableList displayableList, Ui ui);
+
+ /**
+ * Represents the exit status of the program.
+ * @return isExit the boolean controlling if the program exits or not
+ */
+ public boolean isExit() {
+ return isExit;
+ }
+
+}
diff --git a/src/main/java/seedu/eduke8/command/ExitCommand.java b/src/main/java/seedu/eduke8/command/ExitCommand.java
new file mode 100644
index 0000000000..bb0337eb7f
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/ExitCommand.java
@@ -0,0 +1,18 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * A specific command that allows user to terminate the program.
+ */
+public class ExitCommand extends Command {
+ public ExitCommand() {
+ super();
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ isExit = true;
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/HelpCommand.java b/src/main/java/seedu/eduke8/command/HelpCommand.java
new file mode 100644
index 0000000000..7dc6811e18
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/HelpCommand.java
@@ -0,0 +1,18 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * A specific command that prints out the commands available to the user.
+ */
+public class HelpCommand extends Command {
+ public HelpCommand() {
+ super();
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ ui.printHelp();
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/HintCommand.java b/src/main/java/seedu/eduke8/command/HintCommand.java
new file mode 100644
index 0000000000..f516327a70
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/HintCommand.java
@@ -0,0 +1,26 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.hint.Hint;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * A specific command that displays a question's hint during a quiz.
+ */
+public class HintCommand extends Command {
+ private Hint hint;
+
+ public HintCommand(Hint hint) {
+ super();
+ assert hint != null;
+
+ this.hint = hint;
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ ui.printHint(hint);
+
+ assert hint.wasShown();
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/IncompleteCommand.java b/src/main/java/seedu/eduke8/command/IncompleteCommand.java
new file mode 100644
index 0000000000..93bbb95b86
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/IncompleteCommand.java
@@ -0,0 +1,33 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.exception.Eduke8Exception;
+import seedu.eduke8.option.OptionList;
+import seedu.eduke8.question.Question;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * A specific command that prints out messages if a user is unable to finish a question in a quiz by the time limit.
+ */
+public class IncompleteCommand extends Command {
+ private Question question;
+ private int userTimer;
+
+ public IncompleteCommand(Question question, int userTimer) {
+ super();
+
+ this.question = question;
+ this.userTimer = userTimer;
+ }
+
+ @Override
+ public void execute(DisplayableList optionList, Ui ui) {
+ String explanation = question.getExplanation().getDescription();
+ try {
+ int correctOptionNumber = ((OptionList) optionList).findCorrectOptionIndex() + 1;
+ ui.printIncompleteAnswer(correctOptionNumber, explanation, userTimer);
+ } catch (Eduke8Exception e) {
+ ui.printError(e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/IncorrectCommand.java b/src/main/java/seedu/eduke8/command/IncorrectCommand.java
new file mode 100644
index 0000000000..9cc0db88e0
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/IncorrectCommand.java
@@ -0,0 +1,21 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * A specific command that indicates by a printed message that an error was encountered while parsing the user's input.
+ */
+public class IncorrectCommand extends Command {
+ String errorMessage;
+
+ public IncorrectCommand(String errorMessage) {
+ super();
+ this.errorMessage = errorMessage;
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ ui.printError(errorMessage);
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/NoteCommand.java b/src/main/java/seedu/eduke8/command/NoteCommand.java
new file mode 100644
index 0000000000..2c17da88a1
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/NoteCommand.java
@@ -0,0 +1,43 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.Displayable;
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.exception.Eduke8Exception;
+import seedu.eduke8.note.Note;
+import seedu.eduke8.topic.TopicList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * A specific command that manages a user's Notes in E-Duke-8.
+ */
+public class NoteCommand extends Command {
+
+ private static final String NOTE_ADD = "add";
+ private static final String NOTE_DELETE = "delete";
+ private static final String NOTE_LIST = "list";
+
+ private String typeOfNoteCommand;
+ private TopicList topics;
+
+ public NoteCommand(String typeOfNoteCommand, TopicList topics) {
+ this.typeOfNoteCommand = typeOfNoteCommand;
+ this.topics = topics;
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ switch (typeOfNoteCommand) {
+ case (NOTE_ADD):
+ ui.printAddNote(topics);
+ break;
+ case (NOTE_DELETE):
+ ui.printDeleteNote(topics);
+ break;
+ case (NOTE_LIST):
+ ui.printListNote(topics);
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/QuizCommand.java b/src/main/java/seedu/eduke8/command/QuizCommand.java
new file mode 100644
index 0000000000..a4b0d6aeef
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/QuizCommand.java
@@ -0,0 +1,50 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.bookmark.BookmarkList;
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.exception.Eduke8Exception;
+import seedu.eduke8.quiz.SingleTopicQuiz;
+import seedu.eduke8.topic.Topic;
+import seedu.eduke8.topic.TopicList;
+import seedu.eduke8.ui.Ui;
+
+import java.util.logging.Logger;
+
+/**
+ * A specific command that manages the construction of quizzes for the user.
+ */
+public class QuizCommand extends Command {
+ private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+
+ private TopicList topicList;
+ private int numOfQuestions;
+ private String topicName;
+ private Ui ui;
+ private BookmarkList bookmarks;
+ private int userTimer;
+
+ public QuizCommand(TopicList topicList, int numOfQuestions, String topicName, Ui ui, BookmarkList bookmarks,
+ int userTimer) {
+ super();
+ assert topicList != null;
+
+ this.topicList = topicList;
+ this.numOfQuestions = numOfQuestions;
+ this.topicName = topicName;
+ this.ui = ui;
+ this.bookmarks = bookmarks;
+ this.userTimer = userTimer;
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ try {
+ Topic topic = (Topic) topicList.find(topicName);
+ SingleTopicQuiz singleTopicQuiz = new SingleTopicQuiz(topic, numOfQuestions, bookmarks, userTimer);
+ singleTopicQuiz.startQuiz(ui);
+ } catch (Eduke8Exception e) {
+ ui.printError(e.getMessage());
+ }
+ }
+}
+
diff --git a/src/main/java/seedu/eduke8/command/StatsCommand.java b/src/main/java/seedu/eduke8/command/StatsCommand.java
new file mode 100644
index 0000000000..e951b40326
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/StatsCommand.java
@@ -0,0 +1,23 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.bookmark.BookmarkList;
+import seedu.eduke8.stats.Stats;
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.topic.TopicList;
+import seedu.eduke8.ui.Ui;
+
+public class StatsCommand extends Command {
+ private TopicList topicList;
+
+ public StatsCommand(TopicList topicList) {
+ super();
+ assert topicList != null;
+
+ this.topicList = topicList;
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ new Stats(topicList).showStatsToUser(ui);
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/TextbookCommand.java b/src/main/java/seedu/eduke8/command/TextbookCommand.java
new file mode 100644
index 0000000000..6be6ebbcba
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/TextbookCommand.java
@@ -0,0 +1,16 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.ui.Ui;
+
+public class TextbookCommand extends Command {
+
+ public TextbookCommand() {
+ super();
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ ui.printTextbook();
+ }
+}
diff --git a/src/main/java/seedu/eduke8/command/TopicsCommand.java b/src/main/java/seedu/eduke8/command/TopicsCommand.java
new file mode 100644
index 0000000000..cdc67219d2
--- /dev/null
+++ b/src/main/java/seedu/eduke8/command/TopicsCommand.java
@@ -0,0 +1,20 @@
+package seedu.eduke8.command;
+
+import seedu.eduke8.common.DisplayableList;
+import seedu.eduke8.topic.TopicList;
+import seedu.eduke8.ui.Ui;
+
+/**
+ * Represents the specific command that lists the topics available in E-Duke-8.
+ */
+public class TopicsCommand extends Command {
+ public TopicsCommand() {
+ super();
+ }
+
+ @Override
+ public void execute(DisplayableList displayableList, Ui ui) {
+ assert displayableList != null;
+ ((TopicList) displayableList).showTopics(ui);
+ }
+}
diff --git a/src/main/java/seedu/eduke8/common/Displayable.java b/src/main/java/seedu/eduke8/common/Displayable.java
new file mode 100644
index 0000000000..f45d3583b3
--- /dev/null
+++ b/src/main/java/seedu/eduke8/common/Displayable.java
@@ -0,0 +1,10 @@
+package seedu.eduke8.common;
+
+public interface Displayable {
+ String getDescription();
+
+ void markAsShown();
+
+ boolean wasShown();
+
+}
diff --git a/src/main/java/seedu/eduke8/common/DisplayableList.java b/src/main/java/seedu/eduke8/common/DisplayableList.java
new file mode 100644
index 0000000000..c44a6ae831
--- /dev/null
+++ b/src/main/java/seedu/eduke8/common/DisplayableList.java
@@ -0,0 +1,13 @@
+package seedu.eduke8.common;
+
+import seedu.eduke8.exception.Eduke8Exception;
+
+import java.util.ArrayList;
+
+public interface DisplayableList {
+ ArrayList getInnerList();
+
+ Displayable find(String description) throws Eduke8Exception;
+
+ int getCount();
+}
diff --git a/src/main/java/seedu/eduke8/common/EditableList.java b/src/main/java/seedu/eduke8/common/EditableList.java
new file mode 100644
index 0000000000..a2ce527b9a
--- /dev/null
+++ b/src/main/java/seedu/eduke8/common/EditableList.java
@@ -0,0 +1,8 @@
+package seedu.eduke8.common;
+
+public interface EditableList {
+
+ void add(Displayable displayable);
+
+ Displayable delete(int index);
+}
diff --git a/src/main/java/seedu/eduke8/exception/Eduke8Exception.java b/src/main/java/seedu/eduke8/exception/Eduke8Exception.java
new file mode 100644
index 0000000000..32efd58208
--- /dev/null
+++ b/src/main/java/seedu/eduke8/exception/Eduke8Exception.java
@@ -0,0 +1,7 @@
+package seedu.eduke8.exception;
+
+public class Eduke8Exception extends Exception {
+ public Eduke8Exception(String exceptionMessage) {
+ super(exceptionMessage);
+ }
+}
diff --git a/src/main/java/seedu/eduke8/exception/ExceptionMessages.java b/src/main/java/seedu/eduke8/exception/ExceptionMessages.java
new file mode 100644
index 0000000000..e87f30d09e
--- /dev/null
+++ b/src/main/java/seedu/eduke8/exception/ExceptionMessages.java
@@ -0,0 +1,49 @@
+package seedu.eduke8.exception;
+
+public class ExceptionMessages {
+ public static final String ERROR_STORAGE_LOAD_FAIL = "Oh no! An error has occurred when accessing the file."
+ + System.lineSeparator() + "Please check that you have the required files for operation."
+ + System.lineSeparator() + "If issues persist please follow the instructions in the"
+ + " user guide for troubleshooting.";
+ public static final String ERROR_STORAGE_SAVE_FAIL = "Error writing to user data file, user data was not saved.";
+ public static final String ERROR_UNRECOGNIZED_COMMAND = "Oops! The command cannot be understood."
+ + System.lineSeparator() + "Please enter in \"help\" to get the list of available commands.";
+ public static final String ERROR_QUIZ_WRONG_FORMAT = "Invalid command! The command for quiz is as follows:"
+ + System.lineSeparator() + "quiz t/ n/ s/