diff --git a/backend/__pycache__/extract_keywords.cpython-310.pyc b/backend/__pycache__/extract_keywords.cpython-310.pyc
new file mode 100644
index 0000000..1bfa4b3
Binary files /dev/null and b/backend/__pycache__/extract_keywords.cpython-310.pyc differ
diff --git a/backend/__pycache__/find_sentances.cpython-310.pyc b/backend/__pycache__/find_sentances.cpython-310.pyc
new file mode 100644
index 0000000..f317f52
Binary files /dev/null and b/backend/__pycache__/find_sentances.cpython-310.pyc differ
diff --git a/backend/server.py b/backend/server.py
index 0d4abe0..7ea6564 100644
--- a/backend/server.py
+++ b/backend/server.py
@@ -1,114 +1,191 @@
import http.server
+import json
+import random
import socketserver
-import urllib.parse
+import requests
import torch
+from models.modelC.distractor_generator import DistractorGenerator
from transformers import T5ForConditionalGeneration, T5Tokenizer, pipeline
-from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
-import json
-IP='127.0.0.1'
-PORT=8000
+IP = "127.0.0.1"
+PORT = 8000
-def summarize(text):
- summarizer=pipeline('summarization')
- return summarizer(text,max_length=110)[0]['summary_text']
-
-def generate_question(context,answer,model_path, tokenizer_path):
+def summarize(text):
+ summarizer = pipeline("summarization")
+ return summarizer(text, max_length=110)[0]["summary_text"]
+
+def get_distractors_conceptnet(word, context):
+ word = word.lower()
+ original_word = word
+ if len(word.split()) > 0:
+ word = word.replace(" ", "_")
+ distractor_list = []
+ # context_sentences = context.split(".")
+ try:
+ relationships = ["/r/PartOf", "/r/IsA", "/r/HasA"]
+
+ for rel in relationships:
+ url = f"http://api.conceptnet.io/query?node=/c/en/{word}/n&rel={rel}&start=/c/en/{word}&limit=5"
+ if context:
+ url += f"&context={context}"
+
+ obj = requests.get(url).json()
+
+ for edge in obj["edges"]:
+ word2 = edge["end"]["label"]
+ if (
+ word2 not in distractor_list
+ and original_word.lower() not in word2.lower()
+ ):
+ distractor_list.append(word2)
+ return distractor_list
+
+ except json.decoder.JSONDecodeError as e:
+ print(f"Error decoding JSON from ConceptNet API: {e}")
+ return distractor_list
+ except requests.RequestException as e:
+ print(f"Error making request to ConceptNet API: {e}")
+ return distractor_list
+
+
+def generate_question(context, answer, model_path, tokenizer_path):
model = T5ForConditionalGeneration.from_pretrained(model_path)
tokenizer = T5Tokenizer.from_pretrained(tokenizer_path)
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
- input_text=f'answer: {answer} context: {context}'
+ input_text = f"answer: {answer} context: {context}"
- inputs=tokenizer.encode_plus(
+ inputs = tokenizer.encode_plus(
input_text,
- padding='max_length',
+ padding="max_length",
truncation=True,
max_length=512,
- return_tensors='pt'
+ return_tensors="pt",
)
- input_ids=inputs['input_ids'].to(device)
- attention_mask=inputs['attention_mask'].to(device)
+ input_ids = inputs["input_ids"].to(device)
+ attention_mask = inputs["attention_mask"].to(device)
with torch.no_grad():
- output=model.generate(
- input_ids=input_ids,
- attention_mask=attention_mask,
- max_length=32
+ output = model.generate(
+ input_ids=input_ids, attention_mask=attention_mask, max_length=32
)
generated_question = tokenizer.decode(output[0], skip_special_tokens=True)
return generated_question
-def generate_keyphrases(abstract, model_path,tokenizer_path):
- device= torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+def generate_keyphrases(abstract, model_path, tokenizer_path):
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = T5ForConditionalGeneration.from_pretrained(model_path)
tokenizer = T5Tokenizer.from_pretrained(tokenizer_path)
model.to(device)
# tokenizer.to(device)
- input_text=f'detect keyword: abstract: {abstract}'
- input_ids=tokenizer.encode(input_text, truncation=True,padding='max_length',max_length=512,return_tensors='pt').to(device)
- output=model.generate(input_ids)
- keyphrases= tokenizer.decode(output[0],skip_special_tokens=True).split(',')
- return [x.strip() for x in keyphrases if x != '']
+ input_text = f"detect keyword: abstract: {abstract}"
+ input_ids = tokenizer.encode(
+ input_text,
+ truncation=True,
+ padding="max_length",
+ max_length=512,
+ return_tensors="pt",
+ ).to(device)
+ output = model.generate(input_ids)
+ keyphrases = tokenizer.decode(output[0], skip_special_tokens=True).split(",")
+ return [x.strip() for x in keyphrases if x != ""]
+
-def generate_qa(text):
+def generate_qa(self, text, question_type):
+ modelA, modelB = "./models/modelA", "./models/modelB"
+ tokenizerA, tokenizerB = "t5-base", "t5-base"
+ if question_type == "text":
+ text_summary = text
+ answers = generate_keyphrases(text_summary, modelA, tokenizerA)
+ qa = {}
+ for answer in answers:
+ question = generate_question(text_summary, answer, modelB, tokenizerB)
+ qa[question] = answer
- # text_summary=summarize(text)
- text_summary=text
-
+ return qa
- modelA, modelB='./models/modelA','./models/modelB'
- # tokenizerA, tokenizerB= './tokenizers/tokenizerA', './tokenizers/tokenizerB'
- tokenizerA, tokenizerB= 't5-base', 't5-base'
+ elif question_type == "mcq":
+ text_summary = text
- answers=generate_keyphrases(text_summary, modelA, tokenizerA)
+ answers = generate_keyphrases(text_summary, modelA, tokenizerA)
- qa={}
- for answer in answers:
- question= generate_question(text_summary, answer, modelB, tokenizerB)
- qa[question]=answer
-
- return qa
-
+ qa = {}
+ for answer in answers:
+ question = generate_question(text_summary, answer, modelB, tokenizerB)
+ conceptnet_distractors = get_distractors_conceptnet(answer, text_summary)
+ t5_distractors = self.distractor_generator.generate(
+ 5, answer, question, text_summary
+ )
+ dist_temp = list(set(conceptnet_distractors + t5_distractors))
+ dist = [x for x in dist_temp if x.lower() != answer.lower()]
+ print(conceptnet_distractors)
+ if len(dist) < 1:
+ distractors = []
+ qa[question] = answer
+ else:
+ distractors = random.sample(dist, min(3, len(dist)))
+ options = distractors + [answer]
+ random.shuffle(options)
+ formatted_question = f"{question} Options: {', '.join(options)}"
+
+ qa[formatted_question] = answer
+
+ return qa
class QARequestHandler(http.server.BaseHTTPRequestHandler):
- def do_POST(self):
+ def do_OPTIONS(self):
+ self.send_response(200)
+ self.send_header("Access-Control-Allow-Origin", "*")
+ self.send_header("Access-Control-Allow-Methods", "POST, OPTIONS")
+ self.send_header("Access-Control-Allow-Headers", "Content-Type")
+ self.send_header("Content-Length", "0")
+ self.end_headers()
+ def do_POST(self):
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
- content_length=int(self.headers["Content-Length"])
- post_data=self.rfile.read(content_length).decode('utf-8')
-
- # parsed_data=urllib.parse.parse_qs(post_data)
+ content_length = int(self.headers["Content-Length"])
+ post_data = self.rfile.read(content_length).decode("utf-8")
parsed_data = json.loads(post_data)
+ if self.path == "/":
+ input_text = parsed_data.get("input_text")
+ question_type = self.headers.get("Question-Type", "text")
+ qa = generate_qa(self, input_text, question_type)
- input_text=parsed_data.get('input_text')
-
- qa=generate_qa(input_text)
+ self.wfile.write(json.dumps(qa).encode("utf-8"))
+ self.wfile.flush()
+class CustomRequestHandler(QARequestHandler):
+ def __init__(self, *args, **kwargs):
+ self.distractor_generator = kwargs.pop("distractor_generator")
+ super().__init__(*args, **kwargs)
- self.wfile.write(json.dumps(qa).encode("utf-8"))
- self.wfile.flush()
def main():
- with socketserver.TCPServer((IP, PORT), QARequestHandler) as server:
- print(f'Server started at http://{IP}:{PORT}')
+ distractor_generator = DistractorGenerator()
+ with socketserver.TCPServer(
+ (IP, PORT),
+ lambda x, y, z: CustomRequestHandler(
+ x, y, z, distractor_generator=distractor_generator
+ ),
+ ) as server:
+ print(f"Server started at http://{IP}:{PORT}")
server.serve_forever()
-if __name__=="__main__":
- main()
-
\ No newline at end of file
+if __name__ == "__main__":
+ main()
diff --git a/extension/html/text_input.html b/extension/html/text_input.html
index f62c2da..9a1270e 100644
--- a/extension/html/text_input.html
+++ b/extension/html/text_input.html
@@ -2,8 +2,6 @@
EduAid: Text Input
-
@@ -24,11 +22,10 @@ Generate QnA
-
+
-
diff --git a/extension/js/question_generation.js b/extension/js/question_generation.js
index 58bdd94..4f80563 100644
--- a/extension/js/question_generation.js
+++ b/extension/js/question_generation.js
@@ -1,56 +1,61 @@
-document.addEventListener("DOMContentLoaded", function(){
- const saveButton= document.getElementById("save-button");
- const backButton= document.getElementById("back-button");
- const viewQuestionsButton = document.getElementById("view-questions-button");
- const qaPairs=JSON.parse(localStorage.getItem("qaPairs"));
- const modalClose= document.querySelector("[data-close-modal]");
- const modal=document.querySelector("[data-modal]");
-
-
- viewQuestionsButton.addEventListener("click", function(){
- const modalQuestionList = document.getElementById("modal-question-list");
- modalQuestionList.innerHTML = ""; // Clear previous content
-
- for (const [question, answer] of Object.entries(qaPairs)) {
- const questionElement = document.createElement("li");
- questionElement.textContent = `Question: ${question}, Answer: ${answer}`;
- modalQuestionList.appendChild(questionElement)
+document.addEventListener("DOMContentLoaded", function () {
+ const saveButton = document.getElementById("save-button");
+ const backButton = document.getElementById("back-button");
+ const viewQuestionsButton = document.getElementById("view-questions-button");
+ const qaPairs = JSON.parse(localStorage.getItem("qaPairs"));
+ const modalClose = document.querySelector("[data-close-modal]");
+ const modal = document.querySelector("[data-modal]");
+
+ viewQuestionsButton.addEventListener("click", function () {
+ const modalQuestionList = document.getElementById("modal-question-list");
+ modalQuestionList.innerHTML = "";
+
+ for (const [question, answer] of Object.entries(qaPairs)) {
+ const questionElement = document.createElement("li");
+ if (question.includes("Options:")) {
+ const options = question.split("Options: ")[1].split(", ");
+ const formattedOptions = options.map(
+ (opt, index) => `${String.fromCharCode(97 + index)}) ${opt}`
+ );
+ questionElement.textContent = `Question: ${
+ question.split(" Options:")[0]
+ }\n${formattedOptions.join("\n")}`;
+ } else {
+ questionElement.textContent = `Question: ${question}\n\nAnswer: ${answer}\n`;
}
- modal.showModal();
- });
- modalClose.addEventListener("click", function(){
- modal.close();
- });
- saveButton.addEventListener("click", async function(){
- let textContent= "EduAid Generated QnA:\n\n";
+ modalQuestionList.appendChild(questionElement);
+ }
+ modal.showModal();
+ });
- for (const [question,answer] of Object.entries(qaPairs)){
- textContent+= `Question: ${question}\nAnswer: ${answer}\n\n`;
- }
- const blob = new Blob([textContent], { type: "text/plain" });
-
- // Create a URL for the Blob
- const blobUrl = URL.createObjectURL(blob);
-
- // Create a temporary element to trigger the download
- const downloadLink = document.createElement("a");
- downloadLink.href = blobUrl;
- downloadLink.download = "questions_and_answers.txt";
- downloadLink.style.display = "none";
-
- // Append the element to the document
- document.body.appendChild(downloadLink);
-
- // Simulate a click on the link to trigger the download
- downloadLink.click();
-
- // Clean up: remove the temporary element and revoke the Blob URL
- document.body.removeChild(downloadLink);
- URL.revokeObjectURL(blobUrl);
- });
-
- backButton.addEventListener("click", function(){
- window.location.href="../html/text_input.html"
- });
-});
\ No newline at end of file
+ modalClose.addEventListener("click", function () {
+ modal.close();
+ });
+ saveButton.addEventListener("click", async function () {
+ let textContent = "EduAid Generated QnA:\n\n";
+
+ for (const [question, answer] of Object.entries(qaPairs)) {
+ textContent += `Question: ${question}\nAnswer: ${answer}\n\n`;
+ }
+ const blob = new Blob([textContent], { type: "text/plain" });
+
+ const blobUrl = URL.createObjectURL(blob);
+
+ const downloadLink = document.createElement("a");
+ downloadLink.href = blobUrl;
+ downloadLink.download = "questions_and_answers.txt";
+ downloadLink.style.display = "none";
+
+ document.body.appendChild(downloadLink);
+
+ downloadLink.click();
+
+ document.body.removeChild(downloadLink);
+ URL.revokeObjectURL(blobUrl);
+ });
+
+ backButton.addEventListener("click", function () {
+ window.location.href = "../html/text_input.html";
+ });
+});
diff --git a/extension/js/text_input.js b/extension/js/text_input.js
index bf65bb9..7588098 100644
--- a/extension/js/text_input.js
+++ b/extension/js/text_input.js
@@ -1,79 +1,92 @@
document.addEventListener("DOMContentLoaded", function () {
- const nextButton = document.getElementById("next-button");
- const backButton = document.getElementById("back-button");
- const textInput = document.getElementById("text-input");
- const fileInput = document.getElementById("file-upload");
- const loadingScreen = document.getElementById("loading-screen");
-
-
- fileInput.addEventListener("change", async function () {
- const file = fileInput.files[0];
- if (file) {
- const fileReader = new FileReader();
- fileReader.onload = async function (event) {
- const pdfData = new Uint8Array(event.target.result);
- const pdf = await pdfjsLib.getDocument({ data: pdfData }).promise;
- let pdfText = "";
-
- for (let i = 1; i <= pdf.numPages; i++) {
- const page = await pdf.getPage(i);
- const pageText = await page.getTextContent();
- const pageStrings = pageText.items.map(item => item.str);
- pdfText += pageStrings.join(" ");
- }
-
- textInput.value = pdfText;
- };
- fileReader.readAsArrayBuffer(file);
- }
- });
+ const nextButton = document.getElementById("next-button");
+ const mcqButton = document.getElementById("mcq-button");
+ const backButton = document.getElementById("back-button");
+ const textInput = document.getElementById("text-input");
+ const fileInput = document.getElementById("file-upload");
+ const loadingScreen = document.getElementById("loading-screen");
- nextButton.addEventListener("click", async function () {
- loadingScreen.style.display = "flex"
- const inputText = textInput.value;
-
- if (inputText.trim() === "" && fileInput.files.length > 0) {
- const file = fileInput.files[0];
- const fileReader = new FileReader();
- fileReader.onload = async function (event) {
- const uploadedPdfData = new Uint8Array(event.target.result);
- await sendToBackend(uploadedPdfData,"pdf");
- };
- fileReader.readAsArrayBuffer(file);
- } else if (inputText.trim() !== "") {
- await sendToBackend(inputText,"text");
- } else {
- alert("Please enter text or upload a PDF file.");
- loadingScreen.style.display = "none";
- }
- });
-
- backButton.addEventListener("click", function () {
- window.location.href = "../html/index.html";
+ fileInput.addEventListener("change", async function () {
+ const file = fileInput.files[0];
+ if (file) {
+ const fileReader = new FileReader();
+ fileReader.onload = async function (event) {
+ const pdfData = new Uint8Array(event.target.result);
+ const pdf = await pdfjsLib.getDocument({ data: pdfData }).promise;
+ let pdfText = "";
+
+ for (let i = 1; i <= pdf.numPages; i++) {
+ const page = await pdf.getPage(i);
+ const pageText = await page.getTextContent();
+ const pageStrings = pageText.items.map((item) => item.str);
+ pdfText += pageStrings.join(" ");
+ }
+
+ textInput.value = pdfText;
+ };
+ fileReader.readAsArrayBuffer(file);
+ }
+ });
+
+ nextButton.addEventListener("click", async function () {
+ await generateQuestion("text");
+ });
+
+ mcqButton.addEventListener("click", async function () {
+ await generateQuestion("mcq");
+ });
+
+ backButton.addEventListener("click", function () {
+ window.location.href = "../html/index.html";
+ });
+ document
+ .getElementById("generate-quiz-button")
+ .addEventListener("click", function () {
+ window.location.href = "../html/openai.html";
});
-
- async function sendToBackend(data, dataType) {
- let formData;
- let contentType;
- formData = JSON.stringify({ 'input_text': data });
- contentType = "application/json; charset=UTF-8";
-
- const response = await fetch("http://127.0.0.1:8000", {
- method: "POST",
- body: formData,
- headers: {
- "Content-Type": contentType,
- },
- });
-
- if (response.ok) {
- const responseData = await response.json();
- // console.log("Response data:\n"+responseData);
- localStorage.setItem("qaPairs", JSON.stringify(responseData));
- window.location.href = "../html/question_generation.html";
- } else {
- console.error("Backend request failed.");
- }
+
+ async function generateQuestion(questionType) {
+ loadingScreen.style.display = "flex";
+ const inputText = textInput.value;
+
+ if (inputText.trim() === "" && fileInput.files.length > 0) {
+ const file = fileInput.files[0];
+ const fileReader = new FileReader();
+ fileReader.onload = async function (event) {
+ const uploadedPdfData = new Uint8Array(event.target.result);
+ await sendToBackend(uploadedPdfData, "pdf", questionType);
+ };
+ fileReader.readAsArrayBuffer(file);
+ } else if (inputText.trim() !== "") {
+ await sendToBackend(inputText, "text", questionType);
+ } else {
+ alert("Please enter text or upload a PDF file.");
loadingScreen.style.display = "none";
}
- });
\ No newline at end of file
+ }
+
+ async function sendToBackend(data, dataType, questionType) {
+ let formData;
+ let contentType;
+ formData = JSON.stringify({ input_text: data });
+ contentType = "application/json";
+
+ const response = await fetch("http://127.0.0.1:8000/", {
+ method: "POST",
+ body: formData,
+ headers: {
+ "Content-Type": contentType,
+ "Question-Type": questionType,
+ },
+ });
+
+ if (response.ok) {
+ const responseData = await response.json();
+ localStorage.setItem("qaPairs", JSON.stringify(responseData));
+ window.location.href = "../html/question_generation.html";
+ } else {
+ console.error("Backend request failed.");
+ }
+ loadingScreen.style.display = "none";
+ }
+});
diff --git a/extension/manifest.json b/extension/manifest.json
index dabae1a..a8ea075 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -4,7 +4,7 @@
"version": "1.0",
"description": "Generate quizzes with AI-powered questions.",
"permissions": ["activeTab", "storage"],
- "host_permissions":["http://127.0.0.1:8000/*"],
+ "host_permissions":["http://localhost:8000/*","http://127.0.0.1:8000/*","http://localhost:8000/"],
"icons": {
"16": "./assets/aossie_logo.png"
},
@@ -33,4 +33,4 @@
"matches": [""]
}
]
-}
+}
\ No newline at end of file
diff --git a/extension/styles/index.css b/extension/styles/index.css
index 8c0bae4..ded76ae 100644
--- a/extension/styles/index.css
+++ b/extension/styles/index.css
@@ -1,12 +1,8 @@
-
-
-
body{
- /* background-color: rgb(18, 89, 231); */
background-color: #FBAB7E;
background-image: linear-gradient(62deg, #FBAB7E 0%, #F7CE68 100%);
font-family: 'Inter';
- font-weight: 400; /* Regular */
+ font-weight: 400;
}
header{
@@ -29,7 +25,6 @@ h1 {
flex-direction: column;
align-items: center;
justify-content: center;
- /* height: calc(101vh - 102px); Adjust this height value as needed */
}
h2 {
@@ -49,8 +44,6 @@ p{
--black: #000;
}
-
-/* Style the button */
button {
background: linear-gradient(to right, var(--yellow) 0%, var(--green) 50%, var(--yellow) 100%);
background-size: 500%;
@@ -59,9 +52,6 @@ button {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
color: var(--black);
cursor: pointer;
- /* font: 1.5em Raleway, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale; */
height: 1.5rem;
letter-spacing: 0.05em;
outline: none;
@@ -75,12 +65,10 @@ button {
margin-bottom: 1px;
}
-/* Style the button on hover */
button:hover {
- background-position: 100%; /* Move the background gradient on hover */
+ background-position: 100%;
}
-/* Add animation for button hover effect */
@keyframes gradient {
0% {
background-position: 0% 50%;
diff --git a/extension/styles/question_generation.css b/extension/styles/question_generation.css
index 605639c..d41460e 100644
--- a/extension/styles/question_generation.css
+++ b/extension/styles/question_generation.css
@@ -1,5 +1,4 @@
body{
- /* background-color: rgb(18, 89, 231); */
background-color: #FBAB7E;
background-image: linear-gradient(62deg, #FBAB7E 0%, #F7CE68 100%);
font-family: 'Inter';
@@ -26,7 +25,6 @@ h1 {
flex-direction: column;
align-items: center;
justify-content: center;
- /* height: calc(101vh - 102px); Adjust this height value as needed */
}
h2 {
@@ -51,9 +49,6 @@ p{
--black: #000;
}
-
-/* Style the button */
-
button {
display: inline-block;
background: linear-gradient(to right, var(--yellow) 0%, var(--green) 50%, var(--yellow) 100%);
@@ -63,9 +58,6 @@ button {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
color: var(--black);
cursor: pointer;
- /* font: 1.5em Raleway, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale; */
height: 1.5rem;
letter-spacing: 0.05em;
outline: none;
@@ -75,15 +67,14 @@ button {
-ms-user-select: none;
user-select: none;
width: 3rem;
- transition: background-position 0.7s ease; /* Add transition for background position */
+ transition: background-position 0.7s ease;
margin-bottom: 1px;
}
button:hover {
- background-position: 100%; /* Move the background gradient on hover */
+ background-position: 100%;
}
-
- /* Add animation for button hover effect */
+
@keyframes gradient {
0% {
background-position: 0% 50%;
diff --git a/extension/styles/text_input.css b/extension/styles/text_input.css
index 19e1412..bc65cd9 100644
--- a/extension/styles/text_input.css
+++ b/extension/styles/text_input.css
@@ -1,49 +1,77 @@
-body{
- /* background-color: rgb(18, 89, 231); */
- background-color: #FBAB7E;
- background-image: linear-gradient(62deg, #FBAB7E 0%, #F7CE68 100%);
- font-family: 'Inter';
- font-weight: 400; /* Regular */
+body {
+ background-color: #fbab7e;
+ background-image: linear-gradient(62deg, #fbab7e 0%, #f7ce68 100%);
+ font-family: "Inter";
+ font-weight: 400; /* Regular */
}
-header{
- display: flex;
- align-items: center;
- padding: 10px 20px;
-
-}
-img{
- width: 32px;
- height: 32px;
- margin-right: 10px;
-
+header {
+ display: flex;
+ align-items: center;
+ padding: 10px 20px;
+}
+img {
+ width: 32px;
+ height: 32px;
+ margin-right: 10px;
}
h1 {
- font-size: 24px;
- }
- main {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- /* height: calc(101vh - 102px); Adjust this height value as needed */
- }
+ font-size: 24px;
+}
+main {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
- h2 {
- font-size: 28px;
- margin-bottom: 10px;
- }
-p{
- margin-left: 2px;
- margin-right: 2px;
- padding-left: 1px;
- padding-right: 1px;
- text-align: left;
-}
-#text-input{
- height: 30px;
+h2 {
+ font-size: 28px;
+ margin-bottom: 10px;
+}
+p {
+ margin-left: 2px;
+ margin-right: 2px;
+ padding-left: 1px;
+ padding-right: 1px;
+ text-align: left;
+}
+#text-input {
+ height: 150px;
width: 150px;
margin-bottom: 10px;
+ resize: vertical;
+ overflow: auto;
+}
+
+#mcq-button {
+ display: inline-block;
+ background: linear-gradient(
+ to right,
+ var(--yellow) 0%,
+ var(--green) 50%,
+ var(--yellow) 100%
+ );
+ background-size: 500%;
+ border: none;
+ border-radius: 2rem;
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+ color: var(--black);
+ cursor: pointer;
+ font: 1em Inter, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ height: 2rem;
+ letter-spacing: 0.05em;
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ width: 8rem;
+ transition: background-position 0.7s ease;
+ margin-top: 10px;
}
:root {
--yellow: #e8f222;
@@ -51,21 +79,20 @@ p{
--black: #000;
}
-
-/* Style the button */
-
button {
display: inline-block;
- background: linear-gradient(to right, var(--yellow) 0%, var(--green) 50%, var(--yellow) 100%);
+ background: linear-gradient(
+ to right,
+ var(--yellow) 0%,
+ var(--green) 50%,
+ var(--yellow) 100%
+ );
background-size: 500%;
border: none;
border-radius: 2rem;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
color: var(--black);
cursor: pointer;
- /* font: 1.5em Raleway, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale; */
height: 1.5rem;
letter-spacing: 0.05em;
outline: none;
@@ -75,22 +102,26 @@ button {
-ms-user-select: none;
user-select: none;
width: 3rem;
- transition: background-position 0.7s ease; /* Add transition for background position */
+ transition: background-position 0.7s ease;
margin-bottom: 1px;
-
}
label {
display: inline-block;
- background: linear-gradient(to right, var(--yellow) 0%, var(--green) 50%, var(--yellow) 100%);
+ background: linear-gradient(
+ to right,
+ var(--yellow) 0%,
+ var(--green) 50%,
+ var(--yellow) 100%
+ );
background-size: 500%;
border: none;
border-radius: 1rem;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
color: var(--black);
cursor: pointer;
- font: 1em Inter, sans-serif;
+ font: 1em Inter, sans-serif;
-webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ -moz-osx-font-smoothing: grayscale;
height: 1rem;
letter-spacing: 0.05em;
outline: none;
@@ -100,21 +131,20 @@ label {
-ms-user-select: none;
user-select: none;
width: 7rem;
- transition: background-position 0.7s ease;
+ transition: background-position 0.7s ease;
margin-bottom: 10px;
-
}
-#upload-label{
+#upload-label {
text-align: center;
align-items: center;
margin-top: 2px;
}
-/* Style the button on hover */
-label:hover, button:hover {
- background-position: 100%; /* Move the background gradient on hover */
+
+label:hover,
+button:hover {
+ background-position: 100%;
}
-/* Add animation for button hover effect */
@keyframes gradient {
0% {
background-position: 0% 50%;
@@ -134,7 +164,6 @@ label:hover, button:hover {
z-index: 9999;
justify-content: center;
align-items: center;
-
}
.loading-spinner {
@@ -149,6 +178,10 @@ label:hover, button:hover {
}
@keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
}