CONFLICTMERAGE : AADHAVAN
This commit is contained in:
commit
1bb68bc64f
8
.gitignore
vendored
8
.gitignore
vendored
@ -15,4 +15,12 @@ dist/
|
|||||||
.env
|
.env
|
||||||
xml/*
|
xml/*
|
||||||
!xml/Sample.xml
|
!xml/Sample.xml
|
||||||
|
!xml/.gitkeep
|
||||||
|
credentials/in/*
|
||||||
|
credentials/out/*
|
||||||
|
!credentials/in/.gitkeep
|
||||||
|
!credentials/out/.gitkeep
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
378
addform.html
378
addform.html
@ -70,6 +70,12 @@
|
|||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
|
||||||
<script src="QuestionPaperPreview.js"></script>
|
<script src="QuestionPaperPreview.js"></script>
|
||||||
|
|
||||||
|
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"></script>
|
||||||
|
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||||
|
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -274,6 +280,7 @@
|
|||||||
transition: height 0.5s ease;
|
transition: height 0.5s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
math-field{
|
math-field{
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
font-size:18px;
|
font-size:18px;
|
||||||
@ -346,7 +353,7 @@
|
|||||||
|
|
||||||
#sidebar-wrapper {
|
#sidebar-wrapper {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
flex-basis:20%;
|
flex-basis:21%;
|
||||||
width:300px;
|
width:300px;
|
||||||
margin-left: -15rem;
|
margin-left: -15rem;
|
||||||
transition: margin 0.25s ease-out;
|
transition: margin 0.25s ease-out;
|
||||||
@ -463,6 +470,37 @@
|
|||||||
color: #bf303b;
|
color: #bf303b;
|
||||||
/* background: #bf303b; */
|
/* background: #bf303b; */
|
||||||
}
|
}
|
||||||
|
.work-area{
|
||||||
|
background-color: transparent;
|
||||||
|
position: fixed;
|
||||||
|
top:81px;
|
||||||
|
right: 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 15%; /* Make the button round */
|
||||||
|
width: 40px; /* Set the width and height of the button */
|
||||||
|
height: 40px;
|
||||||
|
transition: box-shadow 0.3s, background-color 0.3s;
|
||||||
|
color: #bf303b;
|
||||||
|
|
||||||
|
}
|
||||||
|
.work-area1{
|
||||||
|
background-color: transparent;
|
||||||
|
position: absolute;
|
||||||
|
top:-8px;
|
||||||
|
left:-18px;
|
||||||
|
border-width:0;
|
||||||
|
transform:rotate(58deg);
|
||||||
|
transition: box-shadow 0.3s, background-color 0.3s;
|
||||||
|
color: #bf303b;
|
||||||
|
|
||||||
|
}
|
||||||
|
.work-area1::before{
|
||||||
|
content: '\2BC7';
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.work-area::before{
|
||||||
|
content:'\2630';
|
||||||
|
}
|
||||||
.menu-symbol {
|
.menu-symbol {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
right:0;
|
right:0;
|
||||||
@ -497,8 +535,6 @@
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
||||||
<style>
|
<style>
|
||||||
/* Styles for the overlay background */
|
/* Styles for the overlay background */
|
||||||
.overlay {
|
.overlay {
|
||||||
@ -559,6 +595,8 @@
|
|||||||
border-color:#eee;
|
border-color:#eee;
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
background: #1D3557;
|
||||||
|
|
||||||
}
|
}
|
||||||
.popupbox q{
|
.popupbox q{
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -643,14 +681,132 @@ h1.title{
|
|||||||
color: #1d3557;
|
color: #1d3557;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
height: 100%;
|
||||||
|
width: 0;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #ffffff;
|
||||||
|
overflow-x: hidden;
|
||||||
|
transition: 0.5s;
|
||||||
|
padding-top: 60px;
|
||||||
|
z-index: 2;
|
||||||
|
border-left: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-box {
|
||||||
|
padding: 20px;
|
||||||
|
color: white;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messages {
|
||||||
|
max-height: calc(100% - 60px);
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messageForm {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message{
|
||||||
|
position: relative;
|
||||||
|
right: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebarToggle2 {
|
||||||
|
position: fixed;
|
||||||
|
top: 60px;
|
||||||
|
right: -7px;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-right: 0;
|
||||||
|
transition: margin-right 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-open .content {
|
||||||
|
margin-right: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar::before {
|
||||||
|
content: '\2BC7'; /* Unicode character for the close arrow (adjust as needed) */
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
font-size: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.work-area::before {
|
||||||
|
content: '\2BC7'; /* Unicode character for the open arrow (adjust as needed) */
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.worksection.ql-snow {
|
||||||
|
height: 100px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
border-top: 1px solid #ccc !important;
|
||||||
|
}
|
||||||
|
mjx-container[jax="CHTML"][display="true"] {
|
||||||
|
text-align: left !important;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.sendMessageButton{
|
||||||
|
display: inline-block;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 2px 0px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
transition: 0.5s;
|
||||||
|
font-size: 15px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
/* margin-top: 5px; */
|
||||||
|
/* background: linear-gradient(to right,#533dfd,#730fd5); */
|
||||||
|
background: linear-gradient(to right,darkred, #BF303B);
|
||||||
|
border: none;
|
||||||
|
/* margin-right: 15px; */
|
||||||
|
width: 85px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
<!-- loder -->
|
<!-- loder -->
|
||||||
<div class="loader-wrapper">
|
<div class="loader-wrapper">
|
||||||
<div class="loader"></div>
|
<div class="loader"></div>
|
||||||
@ -674,7 +830,6 @@ h1.title{
|
|||||||
<li><a href="dashboard.html"><img class="addPageMenu" src="assets/images/home.svg" alt="">Home</a></li>
|
<li><a href="dashboard.html"><img class="addPageMenu" src="assets/images/home.svg" alt="">Home</a></li>
|
||||||
<li><a href="#" class="myBtn" onclick="saveFile()" id="SaveButton"><img class="addPageMenu" src="assets/images/save.svg" alt="">Save</a></li>
|
<li><a href="#" class="myBtn" onclick="saveFile()" id="SaveButton"><img class="addPageMenu" src="assets/images/save.svg" alt="">Save</a></li>
|
||||||
<li><a href="#" id="editPreview" ><img class="addPageMenu" src="assets/images/preview.svg" alt="">Preview</a></li>
|
<li><a href="#" id="editPreview" ><img class="addPageMenu" src="assets/images/preview.svg" alt="">Preview</a></li>
|
||||||
<li id="sidebarToggle2"> Sidebar</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -684,6 +839,7 @@ h1.title{
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="menu-symbol1" id="sidebarToggle1"></button>
|
<button class="menu-symbol1" id="sidebarToggle1"></button>
|
||||||
|
<button class="work-area"id="sidebarToggle2"></button>
|
||||||
<!-- QuestionPapper Container start -->
|
<!-- QuestionPapper Container start -->
|
||||||
<div class="d-flex" id="wrapper">
|
<div class="d-flex" id="wrapper">
|
||||||
<!-- Sidebar-->
|
<!-- Sidebar-->
|
||||||
@ -694,8 +850,6 @@ h1.title{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- sidebar end -->
|
<!-- sidebar end -->
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
// Initialize Quill with your specific configuration
|
// Initialize Quill with your specific configuration
|
||||||
@ -734,6 +888,17 @@ h1.title{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
document.getElementById('sidebarToggle3').addEventListener('click', function () {
|
||||||
|
var sidebar = document.getElementById('rightSidebar');
|
||||||
|
document.body.classList.toggle('sidebar-open');
|
||||||
|
if (sidebar.style.width === '250px') {
|
||||||
|
sidebar.style.width = '0';
|
||||||
|
} else {
|
||||||
|
sidebar.style.width = '250px';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('sendMessageButton').addEventListener('click', function () {
|
document.getElementById('sendMessageButton').addEventListener('click', function () {
|
||||||
sendMessage(quill);
|
sendMessage(quill);
|
||||||
});
|
});
|
||||||
@ -781,14 +946,13 @@ h1.title{
|
|||||||
$(mathFieldPreviousDiv).hide();
|
$(mathFieldPreviousDiv).hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
function sendMessage(quill) {
|
|
||||||
|
async function sendMessage(quill) {
|
||||||
var workarea = document.getElementById('workarea');
|
var workarea = document.getElementById('workarea');
|
||||||
var mathField = document.getElementById('workarea_math');
|
var mathField = document.getElementById('workarea_math');
|
||||||
var messagesContainer = document.getElementById('messages');
|
var messagesContainer = document.getElementById('messages');
|
||||||
console.log("workarea",workarea);
|
console.log("workarea",workarea);
|
||||||
|
|
||||||
console.log("mathField",mathField);
|
console.log("mathField",mathField);
|
||||||
|
|
||||||
console.log("messagesContainer",messagesContainer);
|
console.log("messagesContainer",messagesContainer);
|
||||||
|
|
||||||
var content = '';
|
var content = '';
|
||||||
@ -797,8 +961,9 @@ h1.title{
|
|||||||
if ($('#Choicemath_messageInput').prop('checked')) {
|
if ($('#Choicemath_messageInput').prop('checked')) {
|
||||||
// Use MathQuill API to get the math field content
|
// Use MathQuill API to get the math field content
|
||||||
var mathFieldContent = mathField.getValue();
|
var mathFieldContent = mathField.getValue();
|
||||||
console.log(mathFieldContent);
|
|
||||||
content = convertToLatex(mathFieldContent)
|
|
||||||
|
content = await convertToLatex(mathFieldContent);
|
||||||
} else {
|
} else {
|
||||||
content = quill.root.innerHTML.trim();
|
content = quill.root.innerHTML.trim();
|
||||||
}
|
}
|
||||||
@ -807,15 +972,18 @@ h1.title{
|
|||||||
console.log("Message Content: ", content);
|
console.log("Message Content: ", content);
|
||||||
|
|
||||||
if (content !== '') {
|
if (content !== '') {
|
||||||
var messageElement = document.createElement('div');
|
|
||||||
messageElement.className = 'message';
|
|
||||||
messageElement.innerHTML = content;
|
|
||||||
|
|
||||||
messagesContainer.appendChild(messageElement);
|
// var messageElement = document.createElement('div');
|
||||||
|
// messageElement.className = 'message';
|
||||||
|
messagesContainer.innerHTML += content;
|
||||||
|
|
||||||
|
// Append the div to the messagesContainer
|
||||||
|
// messagesContainer.appendChild(messageElement);
|
||||||
|
MathJax.typeset([messagesContainer]);
|
||||||
|
|
||||||
if ($('#Choicemath_messageInput').prop('checked')) {
|
if ($('#Choicemath_messageInput').prop('checked')) {
|
||||||
// Clear the math field content
|
// Clear the math field content
|
||||||
mathField.latex('');
|
// mathField.latex('');
|
||||||
} else {
|
} else {
|
||||||
quill.setText('');
|
quill.setText('');
|
||||||
}
|
}
|
||||||
@ -824,22 +992,67 @@ h1.title{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function convertToLatex(text, mathstatus) {
|
||||||
|
// Parse mathstatus into a boolean
|
||||||
|
const mathStatusBoolean = true
|
||||||
|
// Check if the text contains <p> tags
|
||||||
|
|
||||||
|
console.log("ff")
|
||||||
|
return new Promise(async(resolve, reject) => {
|
||||||
|
|
||||||
|
if (!/<p>|<\/p>/i.test(text)) {
|
||||||
|
console.log('text:' , text)
|
||||||
|
if (mathStatusBoolean) {
|
||||||
|
console.log('text1:' , text)
|
||||||
|
// Use MathJax to convert the text to LaTeX
|
||||||
|
const cov = await MathJax.tex2chtml(text).outerHTML;
|
||||||
|
console.log('cov:' , cov);
|
||||||
|
resolve(cov);
|
||||||
|
//return cov;
|
||||||
|
} else {
|
||||||
|
// Return the text as-is
|
||||||
|
resolve(text);
|
||||||
|
//return text;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("pq")
|
||||||
|
const cov = await MathJax.tex2chtml(text).outerHTML;
|
||||||
|
console.log('cov:' , cov)
|
||||||
|
resolve(cov);
|
||||||
|
//return cov;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="sidebar" id="rightSidebar">
|
<div class="sidebar" id="rightSidebar">
|
||||||
<div class="chat-box">
|
<div class="chat-box">
|
||||||
<h2>Live Chat</h2>
|
<button class="work-area1" id="sidebarToggle3"></button>
|
||||||
<div id="messages" class="chat-history"></div>
|
<h2>Work Area</h2>
|
||||||
|
<div id="messages" class="chat-history" ></div>
|
||||||
<form id="messageForm" action="#" method="post" onsubmit="sendMessage(); return false;">
|
<form id="messageForm" action="#" method="post" onsubmit="sendMessage(); return false;">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<!-- The contentEditable div for Quill -->
|
<!-- The contentEditable div for Quill -->
|
||||||
<div class="richText" id="workarea" contentEditable="true" placeholder="Type your message and press Enter..." ></div>
|
<div class="row">
|
||||||
<div>
|
<div class="col-12">
|
||||||
<math-field id="workarea_math" style="width: 100%; " contenteditable="true"></math-field>
|
<div class="richText worksection" id="workarea" contentEditable="true" placeholder="Type your message and press Enter..."></div>
|
||||||
<div class="items2 col-lg-4">
|
</div>
|
||||||
<input style="width:14px; height:14px" type="checkbox" id="Choicemath_messageInput"> <span class="math">Math</span>
|
<div class="col-12">
|
||||||
</div></div>
|
<div>
|
||||||
<button id="sendMessageButton" type="button">Send</button>
|
<math-field id="workarea_math" style="width: 100%; " contenteditable="true"></math-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-6 items2" style="display: flex; align-items: center;">
|
||||||
|
<input style="width:14px; height:14px; margin-right: 5px;" type="checkbox" id="Choicemath_messageInput"/>
|
||||||
|
<span class="math">Math</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-6" style="display: flex; align-items: center;">
|
||||||
|
<button id="sendMessageButton" class="sendMessageButton" type="button">Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -1035,6 +1248,7 @@ h1.title{
|
|||||||
|
|
||||||
<!-- RTC Hide and Show Script -->
|
<!-- RTC Hide and Show Script -->
|
||||||
<script src="rtc_hide_and_show.js"></script>
|
<script src="rtc_hide_and_show.js"></script>
|
||||||
|
<!-- <script src="QuestionPaperPreview.js"></script> -->
|
||||||
|
|
||||||
<!-- decrypt -->
|
<!-- decrypt -->
|
||||||
<script src="decode.js"></script>
|
<script src="decode.js"></script>
|
||||||
@ -1117,15 +1331,15 @@ $(document).ready(function() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
$(document).on("click", function (event) {
|
// $(document).on("click", function (event) {
|
||||||
|
|
||||||
|
|
||||||
var questionPaperDiv = $(".QuestionPaperClass");
|
// var questionPaperDiv = $(".QuestionPaperClass");
|
||||||
if (!questionPaperDiv.is(event.target) && questionPaperDiv.has(event.target).length === 0) {
|
// if (!questionPaperDiv.is(event.target) && questionPaperDiv.has(event.target).length === 0) {
|
||||||
$('.ql-toolbar').hide();
|
// $('.ql-toolbar').hide();
|
||||||
}
|
// }
|
||||||
|
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
@ -1188,11 +1402,68 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Function for Finding the JSON File in the folder
|
||||||
|
function findFile(filePath) {
|
||||||
|
try {
|
||||||
|
const stats = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stats.isFile()) {
|
||||||
|
|
||||||
|
// File exists
|
||||||
|
// console.log(`File found at: ${filePath}`);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// console.error(`Path is not a file: ${filePath}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// console.error(`File not found: ${filePath}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function to load XML from a file
|
// Function to load XML from a file
|
||||||
function loadXML(xmlFileName) {
|
function loadXML(xmlFileName) {
|
||||||
var decodeData ="";
|
var decodeData ="";
|
||||||
|
var encodedXmlFilePath = `${xmlPath}${xmlFileName}`;
|
||||||
|
|
||||||
|
var jsonDecodeData = "";
|
||||||
|
var jsonFileName = xmlFileName.split('.xml');
|
||||||
|
var encodedJsonFilePath = `${xmlPath}${jsonFileName[0]}_answer.json`;
|
||||||
|
|
||||||
|
var filelist = findFile(encodedJsonFilePath);
|
||||||
|
|
||||||
|
if(filelist !== false)
|
||||||
|
{
|
||||||
|
//JSON File Read Function
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(encodedJsonFilePath, 'utf8', (error, data) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('Error reading file:', error);
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
if (isEncrypted === 'YES') {
|
||||||
|
|
||||||
|
jsonDecodeData = decode(encodedJsonFilePath);
|
||||||
|
localStorage.setItem('json_Decode_Data_For_Mcq_Crt_Ans', jsonDecodeData);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
jsonDecodeData = data;
|
||||||
|
localStorage.setItem('json_Decode_Data_For_Mcq_Crt_Ans', jsonDecodeData);
|
||||||
|
|
||||||
|
}
|
||||||
|
resolve(jsonDecodeData);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//XML File Read Function
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.readFile(`${xmlPath}${xmlFileName}`, 'utf8', (error, data) => {
|
fs.readFile(`${xmlPath}${xmlFileName}`, 'utf8', (error, data) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -1201,11 +1472,13 @@ function loadXML(xmlFileName) {
|
|||||||
} else {
|
} else {
|
||||||
if (isEncrypted === 'YES') {
|
if (isEncrypted === 'YES') {
|
||||||
// decrypt function call go to decode.js
|
// decrypt function call go to decode.js
|
||||||
decodeData = decode(data);
|
decodeData = decode(encodedXmlFilePath);
|
||||||
|
|
||||||
} else{
|
} else{
|
||||||
decodeData = data;
|
decodeData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('jsonDecodeData : ', jsonDecodeData);
|
||||||
resolve(decodeData);
|
resolve(decodeData);
|
||||||
xml2json(decodeData);
|
xml2json(decodeData);
|
||||||
// json2nav();
|
// json2nav();
|
||||||
@ -1336,6 +1609,32 @@ var quill = new Quill('#Question_description', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// var quill = new Quill('#workarea', {
|
||||||
|
// theme: 'snow',
|
||||||
|
// modules: {
|
||||||
|
// toolbar:{
|
||||||
|
// container:toolbarOptions,
|
||||||
|
// clipboard: {
|
||||||
|
// matchVisual: true,
|
||||||
|
// },
|
||||||
|
// ImageResize:{
|
||||||
|
// displaySize:true,
|
||||||
|
// modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
var quill = new Quill('#ql-editor',{
|
||||||
|
theme:'snow',
|
||||||
|
module:{
|
||||||
|
ImageResize:{
|
||||||
|
displaySize:true,
|
||||||
|
modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// function imageHandler() {
|
// function imageHandler() {
|
||||||
// var range = this.quill.getSelection();
|
// var range = this.quill.getSelection();
|
||||||
@ -1357,7 +1656,9 @@ rtc_hide_and_show(setitem);
|
|||||||
});
|
});
|
||||||
|
|
||||||
var Question_description_Div = $("#Question_description");
|
var Question_description_Div = $("#Question_description");
|
||||||
|
console.log("Question_description_Div",Question_description_Div);
|
||||||
var Question_description_previousDiv = Question_description_Div.prev();
|
var Question_description_previousDiv = Question_description_Div.prev();
|
||||||
|
console.log("Question_description_previousDiv",Question_description_previousDiv);
|
||||||
Question_description_previousDiv.attr("id", "Question_description_rtc");
|
Question_description_previousDiv.attr("id", "Question_description_rtc");
|
||||||
var questionDescriptionRtc = 'Question_description_rtc';
|
var questionDescriptionRtc = 'Question_description_rtc';
|
||||||
$('#Question_description').focus(function() {
|
$('#Question_description').focus(function() {
|
||||||
@ -1366,6 +1667,13 @@ rtc_hide_and_show(questionDescriptionRtc);
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// var chat_Div = $("#workarea");
|
||||||
|
// var chat_previousDiv = chat_Div.prev();
|
||||||
|
// chat_previousDiv.attr("id", "messageInput_rtc");
|
||||||
|
// var chatRtc = 'messageInput_rtc';
|
||||||
|
// $('#workarea').focus(function() {
|
||||||
|
// rtc_hide_and_show(chatRtc);
|
||||||
|
// });
|
||||||
|
|
||||||
var checkboxElement = document.createElement('input');
|
var checkboxElement = document.createElement('input');
|
||||||
checkboxElement.type = 'checkbox';
|
checkboxElement.type = 'checkbox';
|
||||||
|
|||||||
0
credentials/in/.gitkeep
Normal file
0
credentials/in/.gitkeep
Normal file
0
credentials/out/.gitkeep
Normal file
0
credentials/out/.gitkeep
Normal file
173
dashboard.html
173
dashboard.html
@ -302,6 +302,10 @@ margin-left: -16px;
|
|||||||
<script src="assets/js/jquery.barfiller.js"></script>
|
<script src="assets/js/jquery.barfiller.js"></script>
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
|
|
||||||
|
<script src="encode.js"></script>
|
||||||
|
<script src="decode.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- jquery js -->
|
<!-- jquery js -->
|
||||||
|
|
||||||
@ -377,6 +381,8 @@ sourceStream.on('error', (err) => {
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
const encode = require('./encode');
|
||||||
|
|
||||||
// Get the modal
|
// Get the modal
|
||||||
var modal = document.getElementById("myModal");
|
var modal = document.getElementById("myModal");
|
||||||
|
|
||||||
@ -416,24 +422,165 @@ function validateFile(input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to download a file by filename
|
// // Function to download a file by filename
|
||||||
|
// function downloadFile(filename) {
|
||||||
|
|
||||||
|
// const fileURL = `${xmlPath}${filename}`;
|
||||||
|
// console.log(fileURL)
|
||||||
|
|
||||||
|
// // Create a hidden anchor element to trigger the download
|
||||||
|
// const a = document.createElement('a');
|
||||||
|
// a.style.display = 'none';
|
||||||
|
// a.href = fileURL;
|
||||||
|
// a.download = filename;
|
||||||
|
|
||||||
|
// // Append the anchor to the body and click it to trigger the download
|
||||||
|
// document.body.appendChild(a);
|
||||||
|
// a.click();
|
||||||
|
|
||||||
|
// // Remove the anchor element
|
||||||
|
// document.body.removeChild(a);
|
||||||
|
// }
|
||||||
|
|
||||||
function downloadFile(filename) {
|
function downloadFile(filename) {
|
||||||
|
|
||||||
const fileURL = `${xmlPath}${filename}`;
|
const xmlFilePath = `${xmlPath}${filename}`;
|
||||||
console.log(fileURL)
|
|
||||||
|
|
||||||
// Create a hidden anchor element to trigger the download
|
const xmlFileNameParts = filename.split('.xml');
|
||||||
const a = document.createElement('a');
|
const xmlBaseName = xmlFileNameParts[0];
|
||||||
a.style.display = 'none';
|
const jsonFileName = `${xmlBaseName}_answer.json`;
|
||||||
a.href = fileURL;
|
const jsonFilePath = `${xmlPath}${jsonFileName}`;
|
||||||
a.download = filename;
|
console.log(jsonFilePath);
|
||||||
|
|
||||||
// Append the anchor to the body and click it to trigger the download
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
|
|
||||||
// Remove the anchor element
|
var fileList = findFile(jsonFilePath);
|
||||||
document.body.removeChild(a);
|
console.log(fileList)
|
||||||
|
|
||||||
|
const downloadsPath = process.env.DOWNLOAD_XML_FILE_PATH;
|
||||||
|
// const downloadsPath = '/varr/www/html';
|
||||||
|
const isEncrypted = process.env.ENCRYPTED;
|
||||||
|
const filePathToSave = path.join(downloadsPath, filename);
|
||||||
|
const jsonFilePathToSave = path.join(downloadsPath, jsonFileName);
|
||||||
|
console.log(filePathToSave);
|
||||||
|
console.log(jsonFilePathToSave);
|
||||||
|
|
||||||
|
|
||||||
|
if(isEncrypted == 'YES'){
|
||||||
|
|
||||||
|
console.log('isEncrypted');
|
||||||
|
|
||||||
|
// XML File
|
||||||
|
|
||||||
|
const decodeData = decode(xmlFilePath);
|
||||||
|
const encodeData = encode(decodeData, filePathToSave);
|
||||||
|
|
||||||
|
|
||||||
|
// JSON File
|
||||||
|
if(fileList !== false)
|
||||||
|
{
|
||||||
|
const jsonDecodeData = decode(jsonFilePath);
|
||||||
|
const jsonEncodeData = encode(jsonDecodeData, jsonFilePathToSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
console.log('isEncrypted NOT');
|
||||||
|
|
||||||
|
//Download XML FIle
|
||||||
|
fs.writeFile(filePathToSave, xmlFilePath, 'utf-8', (err) => {
|
||||||
|
|
||||||
|
var errorMessage = "";
|
||||||
|
if (err) {
|
||||||
|
// console.log(err.code);
|
||||||
|
if(err.code == 'EACCES'){
|
||||||
|
|
||||||
|
errorMessage = `Permission Denied.<br> Path: ${filePathToSave}`;
|
||||||
|
}
|
||||||
|
else if(err.code == 'ENOENT'){
|
||||||
|
|
||||||
|
errorMessage = `No Such File Directory. <br> Path: ${filePathToSave}`;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
errorMessage = `Unknown Error. <br> Path: ${filePathToSave}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "File Download Failed",
|
||||||
|
html: errorMessage,
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "File Downloaded",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Download JSON FIle
|
||||||
|
|
||||||
|
if(fileList !== false)
|
||||||
|
{
|
||||||
|
|
||||||
|
fs.writeFile(jsonFilePathToSave, jsonFilePath, 'utf-8', (err) => {
|
||||||
|
|
||||||
|
var errorMessage = "";
|
||||||
|
if (err) {
|
||||||
|
console.log(err.code);
|
||||||
|
if(err.code == 'EACCES'){
|
||||||
|
errorMessage = `Permission Denied.<br> Path: ${jsonFilePathToSave}`;
|
||||||
|
console.log(errorMessage);
|
||||||
|
}
|
||||||
|
else if(err.code == 'ENOENT'){
|
||||||
|
errorMessage = `No Such File Directory. <br> Path: ${jsonFilePathToSave}`;
|
||||||
|
console.log(errorMessage);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
errorMessage = `Unknown Error. <br> Path: ${jsonFilePathToSave}`;
|
||||||
|
console.log(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "File Download Failed",
|
||||||
|
html: errorMessage,
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "File Downloaded",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Function for Finding the JSON File in the folder
|
||||||
|
function findFile(filePath) {
|
||||||
|
try {
|
||||||
|
const stats = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stats.isFile()) {
|
||||||
|
|
||||||
|
// File exists
|
||||||
|
// console.log(`File found at: ${filePath}`);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// console.error(`Path is not a file: ${filePath}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// console.error(`File not found: ${filePath}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
51
decode.js
51
decode.js
@ -1,23 +1,46 @@
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
function decode(encryptedDataFilePath) {
|
||||||
|
|
||||||
|
// console.log('encryptedDataFilePath :', encryptedDataFilePath);
|
||||||
|
const privateKeyPath = process.env.PRIVATE_KEY_PATH;
|
||||||
|
const encryptedFileContent = fs.readFileSync(encryptedDataFilePath);
|
||||||
|
|
||||||
|
// Extract the encrypted AES key, IV, and ciphertext
|
||||||
|
const encryptedAesKeyDec = encryptedFileContent.slice(0, 256); // Assuming 2048-bit RSA key, 256 bytes for the encrypted AES key
|
||||||
|
const ivDec = encryptedFileContent.slice(256, 256 + 16); // IV is 16 bytes
|
||||||
|
const ciphertext = encryptedFileContent.slice(256 + 16);
|
||||||
|
|
||||||
function decode(encryptedData) {
|
|
||||||
try {
|
try {
|
||||||
const algorithm = 'aes-256-cbc';
|
|
||||||
const iv = Buffer.from(encryptedData.slice(0, 24), 'base64');
|
|
||||||
const keyHex = 'd0ca711dc0c599de0847cb86f415cd34d602a322f0f07dc89bce9e1481f481b3';
|
|
||||||
const derivedKey = Buffer.from(keyHex, 'hex');
|
|
||||||
const encryptedText = encryptedData.slice(24);
|
|
||||||
|
|
||||||
const decipher = crypto.createDecipheriv(algorithm, derivedKey, iv);
|
// Decrypt the AES key with the private key
|
||||||
let decrypted = decipher.update(encryptedText, 'base64', 'utf8');
|
const privateKeyObj = fs.readFileSync(privateKeyPath, 'utf-8');
|
||||||
decrypted += decipher.final('utf8');
|
const decryptedAesKey = crypto.privateDecrypt(
|
||||||
|
{
|
||||||
|
key: privateKeyObj,
|
||||||
|
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
||||||
|
oaepHash: 'sha256',
|
||||||
|
},
|
||||||
|
encryptedAesKeyDec
|
||||||
|
);
|
||||||
|
|
||||||
|
// Decrypt the file using AES
|
||||||
|
// const decipher = crypto.createDecipheriv('aes-128-cbc', decryptedAesKey, ivDec);
|
||||||
|
// let decryptedData = decipher.update(ciphertext);
|
||||||
|
// decryptedData = Buffer.concat([decryptedData, decipher.final()]);
|
||||||
|
|
||||||
|
const decipher = crypto.createDecipheriv('aes-128-cbc', decryptedAesKey, ivDec);
|
||||||
|
let decryptedData = decipher.update(ciphertext, 'hex', 'utf-8');
|
||||||
|
decryptedData += decipher.final('utf-8');
|
||||||
|
|
||||||
|
// console.log('File decrypted successfully.');
|
||||||
|
// console.log('Decrypted String:', decryptedData);
|
||||||
|
return decryptedData;
|
||||||
|
|
||||||
console.log('Decrypted String:', decrypted);
|
|
||||||
return decrypted;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Decryption failed:', error.message);
|
|
||||||
return null;
|
console.error('Decryption failed:', error.message);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = decode;
|
module.exports = decode;
|
||||||
|
|||||||
98
encode.js
98
encode.js
@ -1,23 +1,93 @@
|
|||||||
|
const fs = require('fs');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
function encode(inputString) {
|
function encode(inputString, downloadFilePath = false) {
|
||||||
try {
|
|
||||||
const algorithm = 'aes-256-cbc';
|
|
||||||
const iv = crypto.randomBytes(16);
|
|
||||||
const keyHex = 'd0ca711dc0c599de0847cb86f415cd34d602a322f0f07dc89bce9e1481f481b3';
|
|
||||||
const derivedKey = Buffer.from(keyHex, 'hex');
|
|
||||||
const cipher = crypto.createCipheriv(algorithm, derivedKey, iv);
|
|
||||||
|
|
||||||
let encrypted = cipher.update(inputString, 'utf8', 'base64');
|
console.log('encod downloadFilePath : ', downloadFilePath)
|
||||||
encrypted += cipher.final('base64');
|
|
||||||
|
var certificatePath = '';
|
||||||
|
|
||||||
|
if(downloadFilePath !== false)
|
||||||
|
{
|
||||||
|
certificatePath = process.env.DOWNLOAD_PUBLIC_KEY_PATH;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
certificatePath = process.env.PUBLIC_KEY_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const aesKey = crypto.randomBytes(16); // Change the byte length for different key lengths
|
||||||
|
const iv = crypto.randomBytes(16); // Initialization vector for AES-CBC
|
||||||
|
|
||||||
|
// Encrypt the file using AES
|
||||||
|
const cipher = crypto.createCipheriv('aes-128-cbc', aesKey, iv);
|
||||||
|
let encryptedData = cipher.update(inputString);
|
||||||
|
encryptedData = Buffer.concat([encryptedData, cipher.final()]);
|
||||||
|
|
||||||
|
// Get the public key from the self-signed certificate
|
||||||
|
const publicKey = fs.readFileSync(certificatePath, 'utf-8');
|
||||||
|
|
||||||
|
// Encrypt the AES key with the public key
|
||||||
|
const encryptedAesKey = crypto.publicEncrypt(
|
||||||
|
{
|
||||||
|
key: publicKey,
|
||||||
|
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
||||||
|
oaepHash: 'sha256',
|
||||||
|
},
|
||||||
|
aesKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save the encrypted file and encrypted AES key
|
||||||
|
var encryptedResult = Buffer.concat([encryptedAesKey, iv, encryptedData])
|
||||||
|
console.log('File encrypted successfully.');
|
||||||
|
console.log('Encrypted String:', encryptedResult);
|
||||||
|
|
||||||
|
if(downloadFilePath !== false)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(downloadFilePath, encryptedResult);
|
||||||
|
console.log('File downloaded successfully.');
|
||||||
|
Swal.fire({
|
||||||
|
title: "File Downloaded",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error writing file:', error.message);
|
||||||
|
var errorMessage = "";
|
||||||
|
|
||||||
|
if(error.code == 'EACCES'){
|
||||||
|
|
||||||
|
errorMessage = `Permission Denied.<br> Path: ${downloadFilePath}`;
|
||||||
|
}
|
||||||
|
else if(error.code == 'ENOENT'){
|
||||||
|
|
||||||
|
errorMessage = `No Such File Directory. <br> Path: ${downloadFilePath}`;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
errorMessage = `Unknown Error. <br> Path: ${downloadFilePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "File Download Failed",
|
||||||
|
html: errorMessage,
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
return encryptedResult;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
const encryptedData = iv.toString('base64') + encrypted;
|
|
||||||
console.log('Encrypted String:', encryptedData);
|
|
||||||
return encryptedData;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Encryption failed:', error.message);
|
console.error('Encryption failed:', error.message);
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = encode;
|
module.exports = encode;
|
||||||
|
|||||||
26
encodeEnv.js
Normal file
26
encodeEnv.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
// Function to encode data to base64
|
||||||
|
function encodeToBase64(data) {
|
||||||
|
return Buffer.from(data, 'utf-8').toString('base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to encode .env file to base64
|
||||||
|
function encodeEnvFileToBase64(envFilePath, outputFilePath) {
|
||||||
|
// Read the content of the .env file
|
||||||
|
const envData = fs.readFileSync(envFilePath, 'utf-8');
|
||||||
|
|
||||||
|
// Encode the data to base64
|
||||||
|
const base64Data = encodeToBase64(envData);
|
||||||
|
|
||||||
|
// Write the base64-encoded data to a new file
|
||||||
|
fs.writeFileSync(outputFilePath, base64Data, 'utf-8');
|
||||||
|
|
||||||
|
console.log('File encoded to base64 successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example usage
|
||||||
|
const envFilePath = '/.env';
|
||||||
|
const outputFilePath = '/encoded_base64.env';
|
||||||
|
|
||||||
|
encodeEnvFileToBase64(envFilePath, outputFilePath);
|
||||||
@ -5,6 +5,7 @@ function jsonToHtml(jsonData) {
|
|||||||
localStorage.setItem('scroll', 1)
|
localStorage.setItem('scroll', 1)
|
||||||
localStorage.setItem('EditNavExpend', 1)
|
localStorage.setItem('EditNavExpend', 1)
|
||||||
|
|
||||||
|
|
||||||
const count = jsonData.sections.length;
|
const count = jsonData.sections.length;
|
||||||
// console.log(`Count of sections: ${count}`);
|
// console.log(`Count of sections: ${count}`);
|
||||||
|
|
||||||
@ -139,6 +140,7 @@ function QuestionsForEach(Question, questionAreaId, questionRandomNo){
|
|||||||
{
|
{
|
||||||
groupQuestion(false, false, false, questionTitle, questionDescription, questionType, questionSubType, mathEnabled, Choice, questionAreaId, questionRandomNo, questionMarks, questionUUID, questionDisplayMarks,questionId);
|
groupQuestion(false, false, false, questionTitle, questionDescription, questionType, questionSubType, mathEnabled, Choice, questionAreaId, questionRandomNo, questionMarks, questionUUID, questionDisplayMarks,questionId);
|
||||||
// groupQuestion(QuestionObj);
|
// groupQuestion(QuestionObj);
|
||||||
|
|
||||||
Choice = Choice.slice(1);
|
Choice = Choice.slice(1);
|
||||||
Choice.forEach(function(choicenames, index) {
|
Choice.forEach(function(choicenames, index) {
|
||||||
var choiceName = choicenames.choice_name;
|
var choiceName = choicenames.choice_name;
|
||||||
|
|||||||
174
json2xml.js
174
json2xml.js
@ -1,7 +1,146 @@
|
|||||||
function json2xml() {
|
function json2xml() {
|
||||||
// console.clear();
|
// console.clear();
|
||||||
var obj = localStorage.getItem("json");
|
var obj = localStorage.getItem("json");
|
||||||
// console.log('***********************************************************');
|
|
||||||
|
// var obj = `{
|
||||||
|
// "question_paper_title": "<p><br></p>",
|
||||||
|
// "question_paper_description": "<p><br></p>",
|
||||||
|
// "max_marks": "",
|
||||||
|
// "course_ID": "",
|
||||||
|
// "course_Code": "",
|
||||||
|
// "subject_ID": "",
|
||||||
|
// "subject_Code": "",
|
||||||
|
// "paper_No": "",
|
||||||
|
// "subject_Name": "",
|
||||||
|
// "sub_Paper_Prefix": "",
|
||||||
|
// "question_Paper_uuid": "f676ad21-b0d2-4a80-8c77-6cd2b35f1b34",
|
||||||
|
// "sections": [
|
||||||
|
// {
|
||||||
|
// "section_title": "<p>0</p>",
|
||||||
|
// "section_description": "<p><br></p>",
|
||||||
|
// "section_marks": "0",
|
||||||
|
// "section_uuid": "7c62e594-3b93-444f-9fa6-a05f87869db6",
|
||||||
|
// "section_display_marks": true,
|
||||||
|
// "section_attempt_any": "",
|
||||||
|
// "questions": [
|
||||||
|
// {
|
||||||
|
// "question": "<p>1</p>",
|
||||||
|
// "question_description": "<p><br></p>",
|
||||||
|
// "question_type": "group",
|
||||||
|
// "question_sub_type": false,
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "display_marks": true,
|
||||||
|
// "marks": "",
|
||||||
|
// "choice_question_uuid": "40f37294-e7cb-4f19-9166-72f7a04f6391",
|
||||||
|
// "answers": [
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "387d9b85-4702-4e77-a8c3-29d713b7689e",
|
||||||
|
// "no": "a"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "1a6be686-9e7c-4b07-bf15-b9e07a01fd62",
|
||||||
|
// "no": "b"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "0640c05b-522e-422c-8050-0d5982aa3c74",
|
||||||
|
// "no": "c"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "e59f90b0-79d5-413e-85a4-ee3c181230d8",
|
||||||
|
// "no": "d"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "correct_answer": ["1a6be686-9e7c-4b07-bf15-b9e07a01fd62"]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "question": "<p>2</p>",
|
||||||
|
// "question_description": "<p><br></p>",
|
||||||
|
// "question_type": "group",
|
||||||
|
// "question_sub_type": false,
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "display_marks": true,
|
||||||
|
// "marks": "",
|
||||||
|
// "choice_question_uuid": "7a1c83e7-e9ae-4424-9336-6135eaa6b833",
|
||||||
|
// "answers": [
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "0cbb8330-8ce9-4d69-b547-68cee529a636",
|
||||||
|
// "no": "a"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "25dc4fdc-7bcf-4bea-aaa5-dc42a22c08b5",
|
||||||
|
// "no": "b"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "5b0da327-076f-488c-a46e-0b8251c83283",
|
||||||
|
// "no": "c"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "d3934305-d6fd-4601-8b1b-08067f47a8dd",
|
||||||
|
// "no": "d"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "correct_answer": ["d3934305-d6fd-4601-8b1b-08067f47a8dd"]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "question": "<p>3</p>",
|
||||||
|
// "question_description": "<p><br></p>",
|
||||||
|
// "question_type": "group",
|
||||||
|
// "question_sub_type": false,
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "display_marks": true,
|
||||||
|
// "marks": "",
|
||||||
|
// "choice_question_uuid": "6f929b53-9ebc-40fb-800e-46c42b75f2d9",
|
||||||
|
// "answers": [
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "f839312c-8de5-4cd5-8d6c-3ffd3b9efea6",
|
||||||
|
// "no": "a"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "905db769-82b2-4240-af06-fe0b15ee1f73",
|
||||||
|
// "no": "b"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "6a16126f-8100-49f8-ae33-71d4848030cf",
|
||||||
|
// "no": "c"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "choice_name": "<p><br></p>",
|
||||||
|
// "is_math_enabled": false,
|
||||||
|
// "choice_uuid": "143f648a-d52c-42ff-9428-1c080326e1c8",
|
||||||
|
// "no": "d"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "correct_answer": ["143f648a-d52c-42ff-9428-1c080326e1c8", "6a16126f-8100-49f8-ae33-71d4848030cf"]
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// `
|
||||||
|
// console.log(obj);
|
||||||
|
// console.log('***********************************************************');
|
||||||
|
|
||||||
function createXMLDocument(namespace = null) {
|
function createXMLDocument(namespace = null) {
|
||||||
if (typeof document.implementation.createDocument === 'function') {
|
if (typeof document.implementation.createDocument === 'function') {
|
||||||
@ -208,7 +347,16 @@ function json2xml() {
|
|||||||
if (tempSection['questions'].length != 0) {
|
if (tempSection['questions'].length != 0) {
|
||||||
for (question in tempSection['questions']) {
|
for (question in tempSection['questions']) {
|
||||||
var singleQuestion = tempSection['questions'][question];
|
var singleQuestion = tempSection['questions'][question];
|
||||||
if (singleQuestion.hasOwnProperty('question_type')) // normal questions
|
|
||||||
|
|
||||||
|
//for Separate Correct Answer From MCQ
|
||||||
|
if(singleQuestion.question_type == 'group'){
|
||||||
|
|
||||||
|
separateCorrectAnswerFromMcqAsJson(singleQuestion)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (singleQuestion.hasOwnProperty('question_type')) // normal questions
|
||||||
{
|
{
|
||||||
var singleQuestionElement = getXMLNodesOfQuestionData(singleQuestion);
|
var singleQuestionElement = getXMLNodesOfQuestionData(singleQuestion);
|
||||||
//attach each single question into section item node
|
//attach each single question into section item node
|
||||||
@ -233,3 +381,25 @@ function json2xml() {
|
|||||||
localStorage.setItem("xml", xmlString);
|
localStorage.setItem("xml", xmlString);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const outputJson = { questions: [] };
|
||||||
|
|
||||||
|
function separateCorrectAnswerFromMcqAsJson(tempSection) {
|
||||||
|
|
||||||
|
const questionId = tempSection.choice_question_uuid;
|
||||||
|
const answers = tempSection.correct_answer;
|
||||||
|
|
||||||
|
// Create an object for each question and push it to the output array
|
||||||
|
outputJson.questions.push({
|
||||||
|
questionId,
|
||||||
|
answers
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert the output object to JSON string
|
||||||
|
const outputJsonString = JSON.stringify(outputJson, null, 2);
|
||||||
|
localStorage.setItem("Correct_Answer_Json", outputJsonString);
|
||||||
|
console.log('outputJsonString : ', outputJsonString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
835
package-lock.json
generated
835
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,8 @@
|
|||||||
"cropperjs": "^1.6.1",
|
"cropperjs": "^1.6.1",
|
||||||
"desandro-matches-selector": "^2.0.2",
|
"desandro-matches-selector": "^2.0.2",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
|
"electron-dl": "^3.5.1",
|
||||||
|
"electron-download-manager": "^2.1.2",
|
||||||
"electron-context-menu": "^3.6.1",
|
"electron-context-menu": "^3.6.1",
|
||||||
"ev-emitter": "^2.1.2",
|
"ev-emitter": "^2.1.2",
|
||||||
"fizzy-ui-utils": "^3.0.0",
|
"fizzy-ui-utils": "^3.0.0",
|
||||||
@ -33,6 +35,7 @@
|
|||||||
"jquery-ui": "^1.13.2",
|
"jquery-ui": "^1.13.2",
|
||||||
"jsdom": "^22.1.0",
|
"jsdom": "^22.1.0",
|
||||||
"mathjax": "^3.2.2",
|
"mathjax": "^3.2.2",
|
||||||
|
"mathjax-node": "^2.1.1",
|
||||||
"mathlive": "^0.95.5",
|
"mathlive": "^0.95.5",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"quill-image-resize": "^3.0.9",
|
"quill-image-resize": "^3.0.9",
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
function rtc_hide_and_show(rtcid) {
|
function rtc_hide_and_show(rtcid) {
|
||||||
|
|
||||||
// console.log('show id :'+rtcid)
|
|
||||||
var id = localStorage.getItem('rtc');
|
var id = localStorage.getItem('rtc');
|
||||||
var hideid = document.getElementById(id);
|
var hideid = document.getElementById(id);
|
||||||
// console.log('hide id :' + id)
|
// console.log('hide id :' + id)
|
||||||
$(hideid).hide();
|
$(hideid).hide();
|
||||||
|
|
||||||
var showid = document.getElementById(rtcid);
|
var showid = document.getElementById(rtcid);
|
||||||
|
console.log('hide id :' + id)
|
||||||
$(showid).show();
|
$(showid).show();
|
||||||
localStorage.setItem('rtc',rtcid);
|
localStorage.setItem('rtc',rtcid);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function add_button_hide_and_show(BtnID){
|
function add_button_hide_and_show(BtnID){
|
||||||
|
|
||||||
// console.log('show id :'+BtnID)
|
// console.log('show id :'+BtnID)
|
||||||
|
|||||||
99
savexml.js
99
savexml.js
@ -34,53 +34,90 @@ files.forEach((file) => {
|
|||||||
////////
|
////////
|
||||||
//end the autosave
|
//end the autosave
|
||||||
|
|
||||||
function saveXmlToFile(xmlData, filePath,reorder=false, xmlfilename) {
|
function saveXmlToFile(xmlData, filePath,reorder=false, xmlfilename, jsonData, jsonfilePath) {
|
||||||
// console.log(xmlfilename);
|
// console.log(xmlData);
|
||||||
// console.log(filePath);
|
// console.log(filePath);
|
||||||
// Check if the file path is provided
|
// Check if the file path is provided
|
||||||
if (!filePath) {
|
if (!filePath) {
|
||||||
console.error('File path is required.');
|
console.error('File path is required.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the XML data to the specified file path
|
// Write the XML data to the specified file path
|
||||||
fs.writeFileSync(filePath, xmlData, 'utf8', (err) => {
|
fs.writeFileSync(filePath, xmlData, 'utf8', (err) => {
|
||||||
console.log("fs write inside ");
|
console.log("fs write inside ");
|
||||||
alert("fs write inside")
|
alert("fs write inside")
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error writing XML file:', err);
|
console.error('Error writing XML file:', err);
|
||||||
} else {
|
} else {
|
||||||
console.log('XML file saved successfully.');
|
console.log('XML file saved successfully.');
|
||||||
|
|
||||||
// Clear all data in local storage
|
// Clear all data in local storage
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(jsonData !== ""){
|
||||||
|
|
||||||
|
// Write the JSON data to the specified file path
|
||||||
|
fs.writeFileSync(jsonfilePath, jsonData, 'utf8', (err) => {
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
console.error('Error writing XML file:', err);
|
||||||
|
} else {
|
||||||
|
console.log('JSON file saved successfully.');
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
localStorage.clear();
|
|
||||||
if(reorder){
|
|
||||||
window.location.reload();
|
|
||||||
}else{
|
|
||||||
window.location.href = 'addform.html?filename=' + xmlfilename;
|
|
||||||
// window.location.reload();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
localStorage.clear();
|
||||||
|
if(reorder){
|
||||||
|
window.location.reload();
|
||||||
|
}else{
|
||||||
|
window.location.href = 'addform.html?filename=' + xmlfilename;
|
||||||
|
// window.location.reload();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function savexml(UserFilename,reorder=false) {
|
function savexml(UserFilename,reorder=false) {
|
||||||
console.log("reorder",reorder);
|
console.log("reorder",reorder);
|
||||||
// Get the XML string from localStorage
|
// Get the XML string from localStorage
|
||||||
var xmlString = localStorage.getItem("xml");
|
var xmlString = localStorage.getItem("xml");
|
||||||
|
var jsonString = localStorage.getItem("Correct_Answer_Json");
|
||||||
|
console.log('save json : ', jsonString);
|
||||||
|
console.log('save xml : ', xmlString);
|
||||||
|
|
||||||
//check Encrypted or not
|
//check Encrypted or not
|
||||||
var enc = "";
|
var enc = "";
|
||||||
|
var encJson = "";
|
||||||
if (isEncrypted === 'YES') {
|
if (isEncrypted === 'YES') {
|
||||||
// Encrypt
|
// Encrypt
|
||||||
enc = encode(xmlString);
|
enc = encode(xmlString);
|
||||||
|
if(jsonString)
|
||||||
|
{
|
||||||
|
encJson = encode(jsonString);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
enc = xmlString;
|
enc = xmlString;
|
||||||
|
if(jsonString)
|
||||||
|
{
|
||||||
|
encJson = jsonString;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('save xml : ', enc);
|
||||||
|
|
||||||
//XmlPath get from .env
|
//XmlPath get from .env
|
||||||
const xmlPathenv=process.env.XML_FILE_PATH;
|
const xmlPathenv=process.env.XML_FILE_PATH;
|
||||||
const xmlPath = path.join(__dirname, xmlPathenv)
|
const xmlPath = path.join(__dirname, xmlPathenv)
|
||||||
@ -89,20 +126,20 @@ function savexml(UserFilename,reorder=false) {
|
|||||||
|
|
||||||
// Create a filename using on the subtitle
|
// Create a filename using on the subtitle
|
||||||
var xmlfilename = `${UserFilename}.xml`;
|
var xmlfilename = `${UserFilename}.xml`;
|
||||||
console.log('xmlfilename : ', xmlfilename)
|
var jsonfilename = `${UserFilename}_answer.json`;
|
||||||
// var jsonfilename = `${UserFilename}.json`;
|
|
||||||
|
|
||||||
// file path where you want to save the XML file
|
// file path where you want to save the XML file
|
||||||
// const xmlfilePath = process.cwd() + `/${xmlPath}` + xmlfilename;
|
// const xmlfilePath = process.cwd() + `/${xmlPath}` + xmlfilename;
|
||||||
|
|
||||||
const xmlfilePath = `${xmlPath}` + xmlfilename;
|
const xmlfilePath = `${xmlPath}` + xmlfilename;
|
||||||
|
const jsonfilePath = `${xmlPath}` + jsonfilename;
|
||||||
// const jsonfilePath = process.cwd() + '/xml/' + jsonfilename;
|
// const jsonfilePath = process.cwd() + '/xml/' + jsonfilename;
|
||||||
|
|
||||||
if(reorder){
|
if(reorder){
|
||||||
saveXmlToFile(enc, xmlfilePath,reorder=true, xmlfilename);
|
saveXmlToFile(enc, xmlfilePath,reorder=true, xmlfilename, encJson, jsonfilePath);
|
||||||
}else{
|
}else{
|
||||||
// Call the function to save the XML file
|
// Call the function to save the XML file
|
||||||
saveXmlToFile(enc, xmlfilePath, false, xmlfilename);
|
saveXmlToFile(enc, xmlfilePath, false, xmlfilename, encJson, jsonfilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3738,6 +3738,10 @@ width:85px;
|
|||||||
.modal_form_button button:hover{
|
.modal_form_button button:hover{
|
||||||
background: #bf303b;
|
background: #bf303b;
|
||||||
|
|
||||||
|
}
|
||||||
|
.popup-save button:hover{
|
||||||
|
background: #bf303b;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
|
|||||||
0
xml/.gitkeep
Normal file
0
xml/.gitkeep
Normal file
1
xml/Sample.xml
Normal file
1
xml/Sample.xml
Normal file
File diff suppressed because one or more lines are too long
39
xml2json.js
39
xml2json.js
@ -1,9 +1,11 @@
|
|||||||
|
|
||||||
function xml2json(xmlData) {
|
function xml2json(xmlData) {
|
||||||
// console.clear();
|
// console.clear();
|
||||||
// console.log('xml to json converstion');
|
// console.log('xml to json converstion');
|
||||||
// console.log(xmlData);
|
// console.log(xmlData);
|
||||||
|
|
||||||
|
var jsonDecodeData = localStorage.getItem('json_Decode_Data_For_Mcq_Crt_Ans');
|
||||||
|
// console.log(jsonDecodeData);
|
||||||
|
|
||||||
function getAttributesOfXMLNode(node)
|
function getAttributesOfXMLNode(node)
|
||||||
{
|
{
|
||||||
// Get attributes of the node (if any)
|
// Get attributes of the node (if any)
|
||||||
@ -48,6 +50,7 @@ function getQuestionsNodes(questionNode,type)
|
|||||||
questionObj['display_marks'] = questionNode.childNodes[4].firstChild.nodeValue;
|
questionObj['display_marks'] = questionNode.childNodes[4].firstChild.nodeValue;
|
||||||
questionObj['is_math_enabled'] = questionNode.childNodes[6].firstChild.nodeValue;
|
questionObj['is_math_enabled'] = questionNode.childNodes[6].firstChild.nodeValue;
|
||||||
questionObj['answers'] = [];
|
questionObj['answers'] = [];
|
||||||
|
questionObj['correct_answer'] = [];
|
||||||
|
|
||||||
var choiceList = questionNode.childNodes[7].childNodes;
|
var choiceList = questionNode.childNodes[7].childNodes;
|
||||||
|
|
||||||
@ -65,6 +68,36 @@ console.log(choiceList)
|
|||||||
questionObj['answers'].push(tempChoiceobj);
|
questionObj['answers'].push(tempChoiceobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(jsonDecodeData !== null)
|
||||||
|
{
|
||||||
|
var jsonParsedData = JSON.parse(jsonDecodeData);
|
||||||
|
|
||||||
|
// console.log('jsonParsedData : ', jsonParsedData)
|
||||||
|
|
||||||
|
// Iterate over each question
|
||||||
|
for (const question of jsonParsedData.questions) {
|
||||||
|
|
||||||
|
const questionId = question.questionId;
|
||||||
|
const answers = question.answers;
|
||||||
|
|
||||||
|
console.log(typeof answers)
|
||||||
|
|
||||||
|
// console.log(`Question ID: ${questionId}`);
|
||||||
|
|
||||||
|
if(answers !== undefined) {
|
||||||
|
// console.log(`Not Undifined Answer`);
|
||||||
|
for (const answer of answers) {
|
||||||
|
|
||||||
|
// console.log(` Answer ID: ${answer}`);
|
||||||
|
|
||||||
|
if(questionId == questionObj['attributes']['Id']) {
|
||||||
|
questionObj['correct_answer'].push(answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log('jsonDecodeData.length', jsonDecodeData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return questionObj;
|
return questionObj;
|
||||||
|
|
||||||
@ -169,10 +202,12 @@ jsonObj['sections'] = [];
|
|||||||
|
|
||||||
var jsonData = JSON.stringify(jsonObj);
|
var jsonData = JSON.stringify(jsonObj);
|
||||||
// console.log('Xml to Json Conversion ');
|
// console.log('Xml to Json Conversion ');
|
||||||
// console.log(jsonData);
|
console.log('jsonData : ', jsonData);
|
||||||
// console.log(jsonObj);
|
// console.log(jsonObj);
|
||||||
jsonToHtml(jsonObj);
|
jsonToHtml(jsonObj);
|
||||||
// console.log(jsonToHtml(jsonObj))
|
// console.log(jsonToHtml(jsonObj))
|
||||||
|
localStorage.removeItem('json_Decode_Data_For_Mcq_Crt_Ans');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user