Compare commits

...

39 Commits

Author SHA1 Message Date
Frappe PR Bot
b48e007ea8 chore(release): Bumped to Version 2.17.0 2024-12-18 14:51:51 +00:00
Jannat Patel
d5e8973866 Merge pull request #1196 from frappe/l10n_develop2
chore: sync translations from crowdin
2024-12-18 14:18:51 +05:30
Jannat Patel
a8c530f98c chore: Esperanto translations 2024-12-18 06:07:10 +05:30
Jannat Patel
47769ccd62 Merge pull request #1195 from pateljannat/issues-56
feat: load more in quiz list
2024-12-17 18:33:39 +05:30
Jannat Patel
bfc1d9a0a8 feat: load more in quiz list 2024-12-17 17:48:49 +05:30
Jannat Patel
824484e608 Merge pull request #1194 from pateljannat/issues-55
fix: markdown parser link issue
2024-12-17 16:57:31 +05:30
Jannat Patel
d3f7baae4c fix: markdown parser link issue 2024-12-17 16:35:30 +05:30
Jannat Patel
8d961e9b71 Merge pull request #1193 from pateljannat/issues-54
feat: load more in quiz submissions
2024-12-17 12:48:53 +05:30
Jannat Patel
f22855920c Merge pull request #1192 from frappe/l10n_develop2
chore: sync translations from crowdin
2024-12-17 12:24:18 +05:30
Jannat Patel
18728e3519 Merge pull request #1186 from frappe/pot_develop_2024-12-13
chore: update POT file
2024-12-17 12:24:06 +05:30
Jannat Patel
65dc2838d3 feat: load more in quiz submissions 2024-12-17 12:23:44 +05:30
Jannat Patel
be930ce076 chore: Persian translations 2024-12-17 05:37:38 +05:30
Jannat Patel
1ea47a008c Merge pull request #1191 from pateljannat/scormcontent-issue
fix: scormcontent package load issue
2024-12-16 19:25:32 +05:30
Jannat Patel
e0169cff79 fix: scormcontent package load issue 2024-12-16 19:12:15 +05:30
Jannat Patel
7c53ac10e2 Merge pull request #1189 from pateljannat/lesson-md-parser
feat: markdown parser for lessons
2024-12-16 18:29:45 +05:30
Jannat Patel
212e0de6e9 chore: resolved conflicts 2024-12-16 18:13:49 +05:30
Jannat Patel
8e74384b5a Merge branch 'develop' of https://github.com/frappe/lms into lesson-md-parser 2024-12-16 18:12:17 +05:30
Jannat Patel
86e7e68ce1 chore: removed unused packages 2024-12-16 18:12:13 +05:30
Jannat Patel
a77999dbb6 Merge pull request #1190 from pateljannat/quiz-marks-issue
fix: delete quiz and submission before deleting course
2024-12-16 18:10:23 +05:30
Jannat Patel
3288fb0f06 chore: replace mariadb-client-10.6 with mariadb-client for ui tests 2024-12-16 17:56:57 +05:30
Jannat Patel
a81b384f90 fix: mariadb dependency installation 2024-12-16 17:30:00 +05:30
Jannat Patel
75c11d3fcc fix: course category was not reflecting on course form 2024-12-16 17:21:12 +05:30
Jannat Patel
51a6cc035c fix: delete quiz and submission before deleting course 2024-12-16 17:14:30 +05:30
Jannat Patel
ae8008d05c chore: bumped up mariadb image version 2024-12-16 17:00:55 +05:30
Jannat Patel
7f44177986 feat: markdown parser for links and lists 2024-12-16 16:41:55 +05:30
Jannat Patel
d88aaedf3f Merge branch 'develop' of https://github.com/frappe/lms into lesson-md-parser 2024-12-16 16:40:32 +05:30
frappe-pr-bot
802d4ccb0b chore: update POT file 2024-12-13 16:04:40 +00:00
Jannat Patel
76a84c7f5d Merge pull request #1183 from pateljannat/batch-dashboard
feat: show student course and assessment progress on batch page
2024-12-13 12:11:59 +05:30
Jannat Patel
40aefba203 fix: styling of batch list headers 2024-12-13 12:03:00 +05:30
Jannat Patel
6cdfb822b4 fix: batch time issue 2024-12-13 11:45:54 +05:30
Jannat Patel
fdacab66f7 feat: show student course and assessment progress on batch page 2024-12-13 10:44:56 +05:30
Jannat Patel
5cc12e71df Merge pull request #1182 from pateljannat/fix-readme-2
docs: updated readme header, footer and screenshots
2024-12-12 16:33:24 +05:30
Jannat Patel
f5e5fa2f36 docs: fixed screenshot captions 2024-12-12 16:18:54 +05:30
Jannat Patel
6022b83b8c docs: removed extra space under screenshots 2024-12-12 16:06:30 +05:30
Jannat Patel
a01b1657cc docs: added captions to README screenshots 2024-12-12 16:05:39 +05:30
Jannat Patel
6b785bd0e6 docs: updated readme header, footer and screenshots 2024-12-12 15:59:57 +05:30
Jannat Patel
0beffc3083 Merge pull request #1181 from pateljannat/fix-readme
fix: readme
2024-12-11 12:49:37 +05:30
Jannat Patel
d345d09b13 fix: readme 2024-12-11 12:49:11 +05:30
Jannat Patel
38e1eb8fc7 feat: markdown parser for lessons 2024-12-11 11:57:35 +05:30
31 changed files with 827 additions and 139 deletions

BIN
.github/batch.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
.github/batches.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

After

Width:  |  Height:  |  Size: 912 KiB

View File

@@ -5,7 +5,7 @@ echo "Setting Up System Dependencies..."
sudo apt update sudo apt update
sudo apt remove mysql-server mysql-client sudo apt remove mysql-server mysql-client
sudo apt install libcups2-dev redis-server mariadb-client-10.6 sudo apt-get install libcups2-dev redis-server mariadb-client
install_wkhtmltopdf() { install_wkhtmltopdf() {
wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb

BIN
.github/hero.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 842 KiB

After

Width:  |  Height:  |  Size: 2.0 MiB

BIN
.github/quiz.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -24,7 +24,7 @@ jobs:
services: services:
mariadb: mariadb:
image: mariadb:10.6 image: mariadb:10.8
env: env:
MARIADB_ROOT_PASSWORD: 123 MARIADB_ROOT_PASSWORD: 123
ports: ports:

View File

@@ -1,11 +1,10 @@
<div align="center" markdown="1"> <div align="center" markdown="1">
<img src=".github/lms-logo.png" alt="Frappe Learning logo" width="100"/> <img src=".github/lms-logo.png" alt="Frappe Learning logo" width="80" height="80"/>
<h1>Frappe Learning</h1> <h1>Frappe Learning</h1>
**Easy to use, open source, Learning Management System** **Easy to use, open source, Learning Management System**
![GitHub release (latest by date)](https://img.shields.io/github/v/release/frappe/lms)
![Tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/vandxn/main&style=flat&logo=cypress) ![Tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/vandxn/main&style=flat&logo=cypress)
</div> </div>
@@ -24,10 +23,10 @@
## Frappe Learning ## Frappe Learning
Frappe Learning is an easy-to-use learning system that helps you bring structure to your content. Frappe Learning is an easy-to-use learning system that helps you bring structure to your content.
## Motivation ### Motivation
In 2021, we were looking for a Learning Management System to launch [Mon.School](https://mon.school) for FOSS United. We checked out Moodle, but it didnt feel right. The forms were unnecessarily lengthy and the UI was confusing. It shouldn't be this hard to create a course right? So I started making a learning system for Mon.School which soon became a product in itself. The aim is to have a simple platform that anyone can use to launch a course of their own and make knowledge sharing easier. In 2021, we were looking for a Learning Management System to launch [Mon.School](https://mon.school) for FOSS United. We checked out Moodle, but it didnt feel right. The forms were unnecessarily lengthy and the UI was confusing. It shouldn't be this hard to create a course right? So I started making a learning system for Mon.School which soon became a product in itself. The aim is to have a simple platform that anyone can use to launch a course of their own and make knowledge sharing easier.
## Key Features ### Key Features
- **Structured Learning**: Design a course with a 3-level hierarchy, where your courses have chapters and you can group your lessons within these chapters. This ensures that the context of the lesson is set by the chapter. - **Structured Learning**: Design a course with a 3-level hierarchy, where your courses have chapters and you can group your lessons within these chapters. This ensures that the context of the lesson is set by the chapter.
@@ -37,24 +36,42 @@ In 2021, we were looking for a Learning Management System to launch [Mon.School]
- **Getting Certified**: Once a learner has completed the course or batch, you can grant them a certificate. The app provides an inbuilt certificate template. You can use this or else create a template of your own and use that instead. - **Getting Certified**: Once a learner has completed the course or batch, you can grant them a certificate. The app provides an inbuilt certificate template. You can use this or else create a template of your own and use that instead.
### Batches to group learners <details>
<summary>View Screenshots</summary>
![Batch](.github/batches.png)
### Quiz to evaluate them ![Batch](.github/batch.png)
<div align="center">
<sub>
Create batches to group your learners
</sub>
</div>
<br>
![Quiz](.github/quiz.png) ![Quiz](.github/quiz.png)
<div align="center">
<sub>
Evaluate their knowledge by quizzes
</sub>
</div>
<br>
### Certificate to authenticate their knowledge
![Cerficicate](.github/certificate.png) ![Cerficicate](.github/certificate.png)
<div align="center">
<sub>
Autenticate their work with certification
</sub>
</div>
</details>
## Under the Hood
- [**Frappe Framework**](https://github.com/frappe/frappe): A full-stack web application framework written in Python and Javascript. The framework provides a robust foundation for building web applications, including a database abstraction layer, user authentication, and a REST API. ### Under the Hood
- [**Frappe UI**](https://github.com/frappe/frappe-ui): A Vue-based UI library, to provide a modern user interface. The Frappe UI library provides a variety of components that can be used to build single-page applications on top of the Frappe Framework. - [**Frappe Framework**](https://github.com/frappe/frappe): A full-stack web application framework.
- [**Frappe UI**](https://github.com/frappe/frappe-ui): A Vue-based UI library, to provide a modern user interface.
## Production Setup ## Production Setup
@@ -97,7 +114,7 @@ python3 ./easy-install.py deploy \
Replace the following parameters with your values: Replace the following parameters with your values:
- `your_email.example.com`: Your email address - `your_email.example.com`: Your email address
- `subdomain.domain.tld`: Your domain name where Insights will be hosted - `subdomain.domain.tld`: Your domain name where Learning will be hosted
The script will set up a production-ready instance of Frappe Learning with all the necessary configurations in about 5 minutes. The script will set up a production-ready instance of Frappe Learning with all the necessary configurations in about 5 minutes.
@@ -113,16 +130,16 @@ You need Docker, docker-compose and git setup on your machine. Refer [Docker doc
cd frappe-learning cd frappe-learning
# Download the docker-compose file # Download the docker-compose file
wget -O docker-compose.yml https://raw.githubusercontent.com/frappe/insights/develop/docker/docker-compose.yml wget -O docker-compose.yml https://raw.githubusercontent.com/frappe/lms/develop/docker/docker-compose.yml
# Download the setup script # Download the setup script
wget -O init.sh https://raw.githubusercontent.com/frappe/insights/develop/docker/init.sh wget -O init.sh https://raw.githubusercontent.com/frappe/lms/develop/docker/init.sh
**Step 2**: Run the container and daemonize it **Step 2**: Run the container and daemonize it
docker compose up -d docker compose up -d
**Step 3**: The site [http://lms.localhost:8000/insights](http://lms.localhost:8000/lms) should now be available. The default credentials are: **Step 3**: The site [http://lms.localhost:8000/lms](http://lms.localhost:8000/lms) should now be available. The default credentials are:
- Username: Administrator - Username: Administrator
- Password: admin - Password: admin
@@ -134,7 +151,7 @@ To setup the repository locally follow the steps mentioned below:
1. Start the server by running `bench start` 1. Start the server by running `bench start`
1. In a separate terminal window, create a new site by running `bench new-site learning.test` 1. In a separate terminal window, create a new site by running `bench new-site learning.test`
1. Map your site to localhost with the command `bench --site learning.test add-to-hosts` 1. Map your site to localhost with the command `bench --site learning.test add-to-hosts`
1. Get the Insights app. Run `bench get-app https://github.com/frappe/lms` 1. Get the Learning app. Run `bench get-app https://github.com/frappe/lms`
1. Run `bench --site learning.test install-app lms`. 1. Run `bench --site learning.test install-app lms`.
1. Now open the URL `http://learning.test:8000/lms` in your browser, you should see the app running 1. Now open the URL `http://learning.test:8000/lms` in your browser, you should see the app running
@@ -145,7 +162,8 @@ To setup the repository locally follow the steps mentioned below:
- [Documentation](https://docs.frappe.io/learning) - [Documentation](https://docs.frappe.io/learning)
- [YouTube](https://www.youtube.com/channel/UCn3bV5kx77HsVwtnlCeEi_A) - [YouTube](https://www.youtube.com/channel/UCn3bV5kx77HsVwtnlCeEi_A)
<h2></h2> <br>
<br>
<div align="center" style="padding-top: 0.75rem;"> <div align="center" style="padding-top: 0.75rem;">
<a href="https://frappe.io" target="_blank"> <a href="https://frappe.io" target="_blank">
<picture> <picture>

View File

@@ -2,7 +2,7 @@ version: "3.7"
name: lms name: lms
services: services:
mariadb: mariadb:
image: mariadb:10.6 image: mariadb:10.8
command: command:
- --character-set-server=utf8mb4 - --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci - --collation-server=utf8mb4_unicode_ci

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between mb-4">
<div class="text-lg font-semibold mb-4"> <div class="text-lg font-semibold">
{{ __('Assessments') }} {{ __('Assessments') }}
</div> </div>
<Button v-if="canSeeAddButton()" @click="showModal = true"> <Button v-if="canSeeAddButton()" @click="showModal = true">
@@ -38,7 +38,10 @@
<ListRow :row="row" v-for="row in assessments.data"> <ListRow :row="row" v-for="row in assessments.data">
<template #default="{ column, item }"> <template #default="{ column, item }">
<ListRowItem :item="row[column.key]" :align="column.align"> <ListRowItem :item="row[column.key]" :align="column.align">
<div> <div v-if="column.key == 'assessment_type'">
{{ row[column.key] == 'LMS Quiz' ? 'Quiz' : 'Assignment' }}
</div>
<div v-else>
{{ row[column.key] }} {{ row[column.key] }}
</div> </div>
</ListRowItem> </ListRowItem>
@@ -177,10 +180,12 @@ const getAssessmentColumns = () => {
{ {
label: 'Assessment', label: 'Assessment',
key: 'title', key: 'title',
width: '30rem',
}, },
{ {
label: 'Type', label: 'Type',
key: 'assessment_type', key: 'assessment_type',
width: '10rem',
}, },
] ]
@@ -189,6 +194,7 @@ const getAssessmentColumns = () => {
label: 'Status/Score', label: 'Status/Score',
key: 'status', key: 'status',
align: 'center', align: 'center',
width: '10rem',
}) })
} }
return columns return columns

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
<div class="text-xl font-semibold"> <div class="text-lg font-semibold">
{{ __('Courses') }} {{ __('Courses') }}
</div> </div>
<Button v-if="canSeeAddButton()" @click="openCourseModal()"> <Button v-if="canSeeAddButton()" @click="openCourseModal()">
@@ -118,13 +118,13 @@ const getCoursesColumns = () => {
}, },
{ {
label: 'Lessons', label: 'Lessons',
key: 'lesson_count', key: 'lessons',
align: 'right', align: 'right',
}, },
{ {
label: 'Enrollments', label: 'Enrollments',
align: 'right', align: 'right',
key: 'enrollment_count', key: 'enrollments',
}, },
] ]
} }

View File

@@ -1,12 +1,14 @@
<template> <template>
<Button class="float-right mb-3" @click="openStudentModal()"> <div class="flex items-center justify-between mb-4">
<div class="text-lg font-semibold">
{{ __('Students') }}
</div>
<Button @click="openStudentModal()">
<template #prefix> <template #prefix>
<Plus class="h-4 w-4" /> <Plus class="h-4 w-4" />
</template> </template>
{{ __('Add') }} {{ __('Add') }}
</Button> </Button>
<div class="text-lg font-semibold mb-4">
{{ __('Students') }}
</div> </div>
<div v-if="students.data?.length"> <div v-if="students.data?.length">
<ListView <ListView
@@ -18,12 +20,16 @@
<ListHeader <ListHeader
class="mb-2 grid items-center space-x-4 rounded bg-gray-100 p-2" class="mb-2 grid items-center space-x-4 rounded bg-gray-100 p-2"
> >
<ListHeaderItem :item="item" v-for="item in getStudentColumns()"> <ListHeaderItem
:item="item"
v-for="item in getStudentColumns()"
:title="item.label"
>
<template #prefix="{ item }"> <template #prefix="{ item }">
<component <FeatherIcon
v-if="item.icon" v-if="item.icon"
:is="item.icon" :name="item.icon"
class="h-4 w-4 stroke-1.5 ml-4" class="h-4 w-4 stroke-1.5"
/> />
</template> </template>
</ListHeaderItem> </ListHeaderItem>
@@ -42,9 +48,22 @@
/> />
</div> </div>
</template> </template>
<div> <div v-if="column.key == 'courses'">
{{ row[column.key] }} {{ row[column.key] }}
</div> </div>
<div v-else-if="column.icon == 'book-open'">
{{ Math.ceil(row.courses[column.key]) }}
</div>
<div v-else-if="column.icon == 'help-circle'">
<Badge
v-if="isAssignment(row.assessments[column.key])"
:theme="getStatusTheme(row.assessments[column.key])"
class="text-xs"
>
{{ row.assessments[column.key] }}
</Badge>
<div v-else>{{ parseInt(row.assessments[column.key]) }}</div>
</div>
</ListRowItem> </ListRowItem>
</template> </template>
</ListRow> </ListRow>
@@ -74,7 +93,11 @@
</template> </template>
<script setup> <script setup>
import { import {
Avatar,
Badge,
Button,
createResource, createResource,
FeatherIcon,
ListHeader, ListHeader,
ListHeaderItem, ListHeaderItem,
ListSelectBanner, ListSelectBanner,
@@ -82,8 +105,6 @@ import {
ListRows, ListRows,
ListView, ListView,
ListRowItem, ListRowItem,
Avatar,
Button,
} from 'frappe-ui' } from 'frappe-ui'
import { Trash2, Plus } from 'lucide-vue-next' import { Trash2, Plus } from 'lucide-vue-next'
import { ref } from 'vue' import { ref } from 'vue'
@@ -109,27 +130,41 @@ const students = createResource({
}) })
const getStudentColumns = () => { const getStudentColumns = () => {
return [ let columns = [
{ {
label: 'Full Name', label: 'Full Name',
key: 'full_name', key: 'full_name',
width: 2, width: '15rem',
},
{
label: 'Courses Done',
key: 'courses_completed',
align: 'center',
},
{
label: 'Assessments Done',
key: 'assessments_completed',
align: 'center',
},
{
label: 'Last Active',
key: 'last_active',
}, },
] ]
if (students.data?.[0].assessments) {
Object.keys(students.data?.[0].assessments).forEach((assessment) => {
columns.push({
label: assessment,
key: assessment,
width: '10rem',
icon: 'help-circle',
align: isAssignment(students.data?.[0].assessments[assessment])
? 'left'
: 'center',
})
})
}
if (students.data?.[0].courses) {
Object.keys(students.data?.[0].courses).forEach((course) => {
columns.push({
label: course,
key: course,
width: '10rem',
icon: 'book-open',
align: 'center',
})
})
}
return columns
} }
const openStudentModal = () => { const openStudentModal = () => {
@@ -160,4 +195,18 @@ const removeStudents = (selections, unselectAll) => {
} }
) )
} }
const getStatusTheme = (status) => {
if (status === 'Pass') {
return 'green'
} else if (status == 'Not Graded') {
return 'orange'
} else {
return 'red'
}
}
const isAssignment = (value) => {
return isNaN(value)
}
</script> </script>

View File

@@ -59,7 +59,7 @@
<div v-if="course.status != 'Approved'"> <div v-if="course.status != 'Approved'">
<Badge <Badge
variant="solid" variant="subtle"
:theme="course.status === 'Under Review' ? 'orange' : 'blue'" :theme="course.status === 'Under Review' ? 'orange' : 'blue'"
size="sm" size="sm"
> >

View File

@@ -26,7 +26,7 @@ const props = defineProps({
required: true, required: true,
}, },
title: { title: {
type: String, type: [String, null],
required: true, required: true,
}, },
}) })

View File

@@ -28,6 +28,7 @@
import { Dialog, createResource } from 'frappe-ui' import { Dialog, createResource } from 'frappe-ui'
import { ref } from 'vue' import { ref } from 'vue'
import Link from '@/components/Controls/Link.vue' import Link from '@/components/Controls/Link.vue'
import { showToast } from '@/utils'
const students = defineModel('reloadStudents') const students = defineModel('reloadStudents')
const student = ref() const student = ref()
@@ -61,8 +62,11 @@ const addStudent = (close) => {
{ {
onSuccess() { onSuccess() {
students.value.reload() students.value.reload()
close()
student.value = null student.value = null
close()
},
onError(err) {
showToast(__('Error'), __(err.messages?.[0] || err), 'x')
}, },
} }
) )

View File

@@ -252,7 +252,7 @@ import {
} from 'frappe-ui' } from 'frappe-ui'
import Link from '@/components/Controls/Link.vue' import Link from '@/components/Controls/Link.vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { showToast } from '../utils' import { showToast } from '@/utils'
import { Image } from 'lucide-vue-next' import { Image } from 'lucide-vue-next'
import { capture } from '@/telemetry' import { capture } from '@/telemetry'
import MultiSelect from '@/components/Controls/MultiSelect.vue' import MultiSelect from '@/components/Controls/MultiSelect.vue'
@@ -345,6 +345,10 @@ const batchDetail = createResource({
data.instructors.forEach((instructor) => { data.instructors.forEach((instructor) => {
instructors.value.push(instructor.instructor) instructors.value.push(instructor.instructor)
}) })
} else if (['start_time', 'end_time'].includes(key)) {
let [hours, minutes, seconds] = data[key].split(':')
hours = hours.length == 1 ? '0' + hours : hours
batch[key] = `${hours}:${minutes}`
} else if (Object.hasOwn(batch, key)) batch[key] = data[key] } else if (Object.hasOwn(batch, key)) batch[key] = data[key]
}) })
let checkboxes = ['published', 'paid_batch', 'allow_self_enrollment'] let checkboxes = ['published', 'paid_batch', 'allow_self_enrollment']

View File

@@ -133,8 +133,8 @@
</div> </div>
<FormControl <FormControl
v-model="newTag" v-model="newTag"
:placeholder="__('Keywords for the course')" :placeholder="__('Add a keyword and then press enter')"
class="w-52" class="w-72"
@keyup.enter="updateTags()" @keyup.enter="updateTags()"
id="tags" id="tags"
/> />
@@ -288,6 +288,7 @@ const course = reactive({
video_link: '', video_link: '',
course_image: null, course_image: null,
tags: '', tags: '',
category: '',
published: false, published: false,
published_on: '', published_on: '',
featured: false, featured: false,

View File

@@ -132,6 +132,7 @@ const renderEditor = (holder) => {
holder: holder, holder: holder,
tools: getEditorTools(true), tools: getEditorTools(true),
autofocus: true, autofocus: true,
defaultBlock: 'markdown',
}) })
} }

View File

@@ -5,6 +5,9 @@
<Breadcrumbs :items="breadcrumbs" /> <Breadcrumbs :items="breadcrumbs" />
</header> </header>
<div v-if="submissions.data?.length" class="md:w-3/4 md:mx-auto py-5 mx-5"> <div v-if="submissions.data?.length" class="md:w-3/4 md:mx-auto py-5 mx-5">
<div class="text-xl font-semibold mb-5">
{{ submissions.data[0].quiz_title }}
</div>
<ListView <ListView
:columns="quizColumns" :columns="quizColumns"
:rows="submissions.data" :rows="submissions.data"
@@ -31,12 +34,18 @@
</router-link> </router-link>
</ListRows> </ListRows>
</ListView> </ListView>
<div class="flex justify-center my-5">
<Button v-if="submissions.hasNextPage" @click="submissions.next()">
{{ __('Load More') }}
</Button>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { import {
createListResource, createListResource,
Breadcrumbs, Breadcrumbs,
Button,
ListView, ListView,
ListRow, ListRow,
ListRows, ListRows,
@@ -76,12 +85,7 @@ const quizColumns = computed(() => {
{ {
label: __('Member'), label: __('Member'),
key: 'member_name', key: 'member_name',
width: 2, width: 1,
},
{
label: __('Quiz'),
key: 'quiz_title',
width: 2,
}, },
{ {
label: __('Score'), label: __('Score'),

View File

@@ -46,6 +46,11 @@
</router-link> </router-link>
</ListRows> </ListRows>
</ListView> </ListView>
<div class="flex justify-center my-5">
<Button v-if="quizzes.hasNextPage" @click="quizzes.next()">
{{ __('Load More') }}
</Button>
</div>
</div> </div>
<div <div
v-else v-else
@@ -67,13 +72,13 @@
<script setup> <script setup>
import { import {
Breadcrumbs, Breadcrumbs,
Button,
createListResource, createListResource,
ListView, ListView,
ListRows, ListRows,
ListRow, ListRow,
ListHeader, ListHeader,
ListHeaderItem, ListHeaderItem,
Button,
} from 'frappe-ui' } from 'frappe-ui'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { computed, inject, onMounted } from 'vue' import { computed, inject, onMounted } from 'vue'
@@ -103,9 +108,6 @@ const quizzes = createListResource({
auto: true, auto: true,
cache: ['quizzes', user.data?.name], cache: ['quizzes', user.data?.name],
orderBy: 'modified desc', orderBy: 'modified desc',
onSuccess(data) {
data.forEach((row) => {})
},
}) })
const quizColumns = computed(() => { const quizColumns = computed(() => {

View File

@@ -2,6 +2,7 @@ import { toast } from 'frappe-ui'
import { useTimeAgo } from '@vueuse/core' import { useTimeAgo } from '@vueuse/core'
import { Quiz } from '@/utils/quiz' import { Quiz } from '@/utils/quiz'
import { Upload } from '@/utils/upload' import { Upload } from '@/utils/upload'
import { Markdown } from '@/utils/markdownParser'
import Header from '@editorjs/header' import Header from '@editorjs/header'
import Paragraph from '@editorjs/paragraph' import Paragraph from '@editorjs/paragraph'
import { CodeBox } from '@/utils/code' import { CodeBox } from '@/utils/code'
@@ -147,9 +148,15 @@ export function htmlToText(html) {
export function getEditorTools() { export function getEditorTools() {
return { return {
header: Header, header: {
class: Header,
config: {
placeholder: 'Header',
},
},
quiz: Quiz, quiz: Quiz,
upload: Upload, upload: Upload,
markdown: Markdown,
image: SimpleImage, image: SimpleImage,
table: Table, table: Table,
paragraph: { paragraph: {

View File

@@ -0,0 +1,152 @@
export class Markdown {
constructor({ data, api, readOnly, config }) {
this.api = api
this.data = data || {}
this.config = config || {}
this.text = data.text || ''
this.readOnly = readOnly
}
static get isReadOnlySupported() {
return true
}
static get conversionConfig() {
return {
export: 'text',
import: 'text',
}
}
render() {
this.wrapper = document.createElement('div')
this.wrapper.classList.add('cdx-block')
this.wrapper.classList.add('ce-paragraph')
this.wrapper.innerHTML = this.text
if (!this.readOnly) {
this.wrapper.contentEditable = true
this.wrapper.innerHTML = this.text
this.wrapper.addEventListener('keydown', (event) => {
const value = event.target.textContent
if (event.keyCode === 32 && value.startsWith('#')) {
this.convertToHeader(event, value)
} else if (event.keyCode === 13) {
this.parseContent(event)
}
})
this.wrapper.addEventListener('paste', (event) =>
this.handlePaste(event)
)
}
return this.wrapper
}
convertToHeader(event, value) {
event.preventDefault()
if (['#', '##', '###', '####', '#####', '######'].includes(value)) {
let level = value.length
event.target.textContent = ''
this.convertBlock('header', {
level: level,
})
}
}
parseContent(event) {
event.preventDefault()
const previousLine = this.wrapper.textContent
if (previousLine && this.hasImage(previousLine)) {
this.wrapper.textContent = ''
this.convertBlock('image')
} else if (previousLine && this.hasLink(previousLine)) {
const { text, url } = this.extractLink(previousLine)
const anchorTag = `<a href="${url}" target="_blank">${text}</a>`
this.convertBlock('paragraph', {
text: previousLine.replace(/\[.+?\]\(.+?\)/, anchorTag),
})
} else if (previousLine && previousLine.startsWith('- ')) {
this.convertBlock('list', {
style: 'unordered',
items: [
{
content: previousLine.replace('- ', ''),
},
],
})
} else if (previousLine && previousLine.startsWith('1. ')) {
this.convertBlock('list', {
style: 'ordered',
items: [
{
content: previousLine.replace('1. ', ''),
},
],
})
} else if (previousLine && this.canBeEmbed(previousLine)) {
this.wrapper.textContent = ''
this.convertBlock('embed', {
source: previousLine,
})
}
}
async convertBlock(type, data, index = null) {
const currentIndex = this.api.blocks.getCurrentBlockIndex()
const currentBlock = this.api.blocks.getBlockByIndex(currentIndex)
await this.api.blocks.convert(currentBlock.id, type, data)
this.api.caret.focus(true)
}
handlePaste(event) {
event.preventDefault()
const clipboardData = event.clipboardData || window.clipboardData
const pastedText = clipboardData.getData('text/plain')
const sanitizedText = this.processPastedContent(pastedText)
document.execCommand('insertText', false, sanitizedText)
}
processPastedContent(text) {
return text.trim()
}
save(blockContent) {
return {
text: blockContent.innerHTML,
}
}
hasImage(line) {
return /!\[.+?\]\(.+?\)/.test(line)
}
extractImage(line) {
const match = line.match(/!\[(.+?)\]\((.+?)\)/)
if (match) {
return { alt: match[1], url: match[2] }
}
return { alt: '', url: '' }
}
hasLink(line) {
return /\[.+?\]\(.+?\)/.test(line)
}
extractLink(line) {
const match = line.match(/\[(.+?)\]\((.+?)\)/)
if (match) {
return { text: match[1], url: match[2] }
}
return { text: '', url: '' }
}
canBeEmbed(line) {
return /^https?:\/\/.+/.test(line)
}
}
export default Markdown

View File

@@ -752,6 +752,11 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
"@types/json-schema@^7.0.8":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/linkify-it@^5": "@types/linkify-it@^5":
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76"
@@ -765,11 +770,23 @@
"@types/linkify-it" "^5" "@types/linkify-it" "^5"
"@types/mdurl" "^2" "@types/mdurl" "^2"
"@types/mdast@^3.0.0":
version "3.0.15"
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5"
integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==
dependencies:
"@types/unist" "^2"
"@types/mdurl@^2": "@types/mdurl@^2":
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd"
integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==
"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
version "2.0.11"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
"@types/web-bluetooth@^0.0.20": "@types/web-bluetooth@^0.0.20":
version "0.0.20" version "0.0.20"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597" resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
@@ -892,6 +909,26 @@ ace-builds@^1.36.2:
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.36.5.tgz#ae9cc7a32eccc2f484926131c00545cd6b78a6a6" resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.36.5.tgz#ae9cc7a32eccc2f484926131c00545cd6b78a6a6"
integrity sha512-mZ5KVanRT6nLRDLqtG/1YQQLX/gZVC/v526cm1Ru/MTSlrbweSmqv2ZT0d2GaHpJq035MwCMIrj+LgDAUnDXrg== integrity sha512-mZ5KVanRT6nLRDLqtG/1YQQLX/gZVC/v526cm1Ru/MTSlrbweSmqv2ZT0d2GaHpJq035MwCMIrj+LgDAUnDXrg==
ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==
ansi-regex@^5.0.1: ansi-regex@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
@@ -944,6 +981,11 @@ aria-hidden@^1.2.4:
dependencies: dependencies:
tslib "^2.0.0" tslib "^2.0.0"
async@~0.2.6:
version "0.2.10"
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
integrity sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==
autoprefixer@^10.4.2: autoprefixer@^10.4.2:
version "10.4.20" version "10.4.20"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b"
@@ -956,11 +998,21 @@ autoprefixer@^10.4.2:
picocolors "^1.0.1" picocolors "^1.0.1"
postcss-value-parser "^4.2.0" postcss-value-parser "^4.2.0"
bail@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==
balanced-match@^1.0.0: balanced-match@^1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
binary-extensions@^2.0.0: binary-extensions@^2.0.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
@@ -1000,6 +1052,21 @@ caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001669:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz#0e04b8d90de8753188e93c9989d56cb19d902670" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz#0e04b8d90de8753188e93c9989d56cb19d902670"
integrity sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA== integrity sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==
character-entities-legacy@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==
character-entities@^1.0.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b"
integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==
character-reference-invalid@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
chart.js@^4.4.1: chart.js@^4.4.1:
version "4.4.7" version "4.4.7"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.7.tgz#7a01ee0b4dac3c03f2ab0589af888db296d896fa" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.7.tgz#7a01ee0b4dac3c03f2ab0589af888db296d896fa"
@@ -1081,6 +1148,22 @@ cross-spawn@^7.0.0:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
css-loader@^5.0.0:
version "5.2.7"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae"
integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==
dependencies:
icss-utils "^5.1.0"
loader-utils "^2.0.0"
postcss "^8.2.15"
postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0"
postcss-modules-values "^4.0.0"
postcss-value-parser "^4.1.0"
schema-utils "^3.0.0"
semver "^7.3.5"
cssesc@^3.0.0: cssesc@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -1096,6 +1179,13 @@ dayjs@^1.11.6:
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
debug@^4.0.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
ms "^2.1.3"
debug@~4.3.1, debug@~4.3.2: debug@~4.3.1, debug@~4.3.2:
version "4.3.7" version "4.3.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
@@ -1128,6 +1218,17 @@ eastasianwidth@^0.2.0:
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
editorjs-md-parser@^0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/editorjs-md-parser/-/editorjs-md-parser-0.0.3.tgz#cd54c6caca72590894eb5c61827b73ecbb557666"
integrity sha512-8ohPGuCoO3oag5wjky+sukP5BV4fEGhnzElxOfoLhpdYrLmMB1uTVgOOlYknoZLozAWOb4cpx1zUS9qVvK0V4g==
dependencies:
css-loader "^5.0.0"
remark "^13.0.0"
remark-parse "^9.0.0"
require "^2.4.20"
style-loader "^2.0.0"
electron-to-chromium@^1.5.41: electron-to-chromium@^1.5.41:
version "1.5.68" version "1.5.68"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz#4f46be4d465ef00e2100d5557b66f4af70e3ce6c" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz#4f46be4d465ef00e2100d5557b66f4af70e3ce6c"
@@ -1143,6 +1244,11 @@ emoji-regex@^9.2.2:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
emojis-list@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
engine.io-client@~6.6.1: engine.io-client@~6.6.1:
version "6.6.2" version "6.6.2"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.6.2.tgz#e0a09e1c90effe5d6264da1c56d7281998f1e50b" resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.6.2.tgz#e0a09e1c90effe5d6264da1c56d7281998f1e50b"
@@ -1208,7 +1314,12 @@ estree-walker@^2.0.2:
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
fast-deep-equal@^3.1.3: extend@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3" version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
@@ -1224,6 +1335,11 @@ fast-glob@^3.3.2:
merge2 "^1.3.0" merge2 "^1.3.0"
micromatch "^4.0.4" micromatch "^4.0.4"
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fastq@^1.6.0: fastq@^1.6.0:
version "1.17.1" version "1.17.1"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47"
@@ -1339,11 +1455,29 @@ hasown@^2.0.2:
dependencies: dependencies:
function-bind "^1.1.2" function-bind "^1.1.2"
icss-utils@^5.0.0, icss-utils@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
idb-keyval@^6.2.0: idb-keyval@^6.2.0:
version "6.2.1" version "6.2.1"
resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33"
integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==
is-alphabetical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==
is-alphanumerical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf"
integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==
dependencies:
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-binary-path@~2.1.0: is-binary-path@~2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@@ -1351,6 +1485,11 @@ is-binary-path@~2.1.0:
dependencies: dependencies:
binary-extensions "^2.0.0" binary-extensions "^2.0.0"
is-buffer@^2.0.0:
version "2.0.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
is-core-module@^2.13.0: is-core-module@^2.13.0:
version "2.15.1" version "2.15.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37"
@@ -1358,6 +1497,11 @@ is-core-module@^2.13.0:
dependencies: dependencies:
hasown "^2.0.2" hasown "^2.0.2"
is-decimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5"
integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==
is-extglob@^2.1.1: is-extglob@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@@ -1375,11 +1519,21 @@ is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies: dependencies:
is-extglob "^2.1.1" is-extglob "^2.1.1"
is-hexadecimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
is-number@^7.0.0: is-number@^7.0.0:
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-plain-obj@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
isexe@^2.0.0: isexe@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -1399,6 +1553,16 @@ jiti@^1.21.6:
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268"
integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json5@^2.1.2:
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
lilconfig@^3.0.0, lilconfig@^3.1.3: lilconfig@^3.0.0, lilconfig@^3.1.3:
version "3.1.3" version "3.1.3"
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4"
@@ -1421,6 +1585,15 @@ linkifyjs@^4.1.0:
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08"
integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==
loader-utils@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
json5 "^2.1.2"
lodash.castarray@^4.4.0: lodash.castarray@^4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
@@ -1436,6 +1609,11 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
longest-streak@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
lru-cache@^10.2.0: lru-cache@^10.2.0:
version "10.4.3" version "10.4.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
@@ -1470,6 +1648,34 @@ markdown-it@^14.0.0:
punycode.js "^2.3.1" punycode.js "^2.3.1"
uc.micro "^2.1.0" uc.micro "^2.1.0"
mdast-util-from-markdown@^0.8.0:
version "0.8.5"
resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c"
integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==
dependencies:
"@types/mdast" "^3.0.0"
mdast-util-to-string "^2.0.0"
micromark "~2.11.0"
parse-entities "^2.0.0"
unist-util-stringify-position "^2.0.0"
mdast-util-to-markdown@^0.6.0:
version "0.6.5"
resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe"
integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==
dependencies:
"@types/unist" "^2.0.0"
longest-streak "^2.0.0"
mdast-util-to-string "^2.0.0"
parse-entities "^2.0.0"
repeat-string "^1.0.0"
zwitch "^1.0.0"
mdast-util-to-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==
mdurl@^2.0.0: mdurl@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0"
@@ -1480,6 +1686,14 @@ merge2@^1.3.0:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromark@~2.11.0:
version "2.11.4"
resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a"
integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==
dependencies:
debug "^4.0.0"
parse-entities "^2.0.0"
micromatch@^4.0.4, micromatch@^4.0.8: micromatch@^4.0.4, micromatch@^4.0.8:
version "4.0.8" version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
@@ -1554,6 +1768,13 @@ object-hash@^3.0.0:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
optimist@~0.3.5:
version "0.3.7"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9"
integrity sha512-TCx0dXQzVtSCg2OgY/bO9hjM9cV4XYx09TVK+s3+FhkjT6LovsLe+pPMzpWf+6yXK/hUizs2gUoTw3jHM0VaTQ==
dependencies:
wordwrap "~0.0.2"
orderedmap@^2.0.0: orderedmap@^2.0.0:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2" resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2"
@@ -1564,6 +1785,18 @@ package-json-from-dist@^1.0.0:
resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
parse-entities@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
dependencies:
character-entities "^1.0.0"
character-entities-legacy "^1.0.0"
character-reference-invalid "^1.0.0"
is-alphanumerical "^1.0.0"
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
path-key@^3.1.0: path-key@^3.1.0:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
@@ -1634,6 +1867,34 @@ postcss-load-config@^4.0.2:
lilconfig "^3.0.0" lilconfig "^3.0.0"
yaml "^2.3.4" yaml "^2.3.4"
postcss-modules-extract-imports@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002"
integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==
postcss-modules-local-by-default@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz#b0db6bc81ffc7bdc52eb0f84d6ca0bedf0e36d21"
integrity sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==
dependencies:
icss-utils "^5.0.0"
postcss-selector-parser "^7.0.0"
postcss-value-parser "^4.1.0"
postcss-modules-scope@^3.0.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz#1bbccddcb398f1d7a511e0a2d1d047718af4078c"
integrity sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==
dependencies:
postcss-selector-parser "^7.0.0"
postcss-modules-values@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c"
integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==
dependencies:
icss-utils "^5.0.0"
postcss-nested@^6.2.0: postcss-nested@^6.2.0:
version "6.2.0" version "6.2.0"
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131"
@@ -1657,12 +1918,20 @@ postcss-selector-parser@^6.1.1, postcss-selector-parser@^6.1.2:
cssesc "^3.0.0" cssesc "^3.0.0"
util-deprecate "^1.0.2" util-deprecate "^1.0.2"
postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: postcss-selector-parser@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz#41bd8b56f177c093ca49435f65731befe25d6b9c"
integrity sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.4.43, postcss@^8.4.47, postcss@^8.4.48, postcss@^8.4.5: postcss@^8.2.15, postcss@^8.4.43, postcss@^8.4.47, postcss@^8.4.48, postcss@^8.4.5:
version "8.4.49" version "8.4.49"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19"
integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
@@ -1835,6 +2104,11 @@ punycode.js@^2.3.1:
resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
queue-microtask@^1.2.2: queue-microtask@^1.2.2:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -1871,6 +2145,42 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
remark-parse@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640"
integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==
dependencies:
mdast-util-from-markdown "^0.8.0"
remark-stringify@^9.0.0:
version "9.0.1"
resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-9.0.1.tgz#576d06e910548b0a7191a71f27b33f1218862894"
integrity sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==
dependencies:
mdast-util-to-markdown "^0.6.0"
remark@^13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/remark/-/remark-13.0.0.tgz#d15d9bf71a402f40287ebe36067b66d54868e425"
integrity sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==
dependencies:
remark-parse "^9.0.0"
remark-stringify "^9.0.0"
unified "^9.1.0"
repeat-string@^1.0.0:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
require@^2.4.20:
version "2.4.20"
resolved "https://registry.yarnpkg.com/require/-/require-2.4.20.tgz#66cb6baaabb65de8a71d793f5c65fd184f3798b6"
integrity sha512-7eop5rvh38qhQQQOoUyf68meVIcxT2yFySNywTbxoEECgkX4KDqqDRaEszfvFnuB3fuZVjDdJZ1TI/Esr16RRA==
dependencies:
std "0.1.40"
uglify-js "2.3.0"
resolve@^1.1.7, resolve@^1.22.8: resolve@^1.1.7, resolve@^1.22.8:
version "1.22.8" version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
@@ -1924,6 +2234,20 @@ run-parallel@^1.1.9:
dependencies: dependencies:
queue-microtask "^1.2.2" queue-microtask "^1.2.2"
schema-utils@^3.0.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe"
integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==
dependencies:
"@types/json-schema" "^7.0.8"
ajv "^6.12.5"
ajv-keywords "^3.5.2"
semver@^7.3.5:
version "7.6.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
shebang-command@^2.0.0: shebang-command@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@@ -1976,6 +2300,18 @@ source-map-js@^1.2.0, source-map-js@^1.2.1:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
source-map@~0.1.7:
version "0.1.43"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
integrity sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==
dependencies:
amdefine ">=0.0.4"
std@0.1.40:
version "0.1.40"
resolved "https://registry.yarnpkg.com/std/-/std-0.1.40.tgz#3678a5f65094d9e1b6b5e26edbfc0212b8342b71"
integrity sha512-wUf57hkDGCoVShrhPA8Q7lAg2Qosk+FaMlECmAsr1A4/rL2NRXFHQGBcgMUFKVkPEemJFW9gzjCQisRty14ohg==
"string-width-cjs@npm:string-width@^4.2.0": "string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
@@ -2024,6 +2360,14 @@ strip-ansi@^7.0.1:
dependencies: dependencies:
ansi-regex "^6.0.1" ansi-regex "^6.0.1"
style-loader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c"
integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==
dependencies:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
sucrase@^3.35.0: sucrase@^3.35.0:
version "3.35.0" version "3.35.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"
@@ -2098,6 +2442,11 @@ to-regex-range@^5.0.1:
dependencies: dependencies:
is-number "^7.0.0" is-number "^7.0.0"
trough@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
ts-interface-checker@^0.1.9: ts-interface-checker@^0.1.9:
version "0.1.13" version "0.1.13"
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
@@ -2118,6 +2467,34 @@ uc.micro@^2.0.0, uc.micro@^2.1.0:
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee"
integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==
uglify-js@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.3.0.tgz#2cdec16d378a8a2b6ecfb6989784cf8b7ae5491f"
integrity sha512-AQvbxRKdaQeYADywQaao0k8Tj+7NGEVTne6xwgX1yQpv/G8b0CKdIw70HkCptwfvNGDsVe+0Bng3U9hfWbxxfg==
dependencies:
async "~0.2.6"
optimist "~0.3.5"
source-map "~0.1.7"
unified@^9.1.0:
version "9.2.2"
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"
integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==
dependencies:
bail "^1.0.0"
extend "^3.0.0"
is-buffer "^2.0.0"
is-plain-obj "^2.0.0"
trough "^1.0.0"
vfile "^4.0.0"
unist-util-stringify-position@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==
dependencies:
"@types/unist" "^2.0.2"
update-browserslist-db@^1.1.1: update-browserslist-db@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5"
@@ -2126,11 +2503,36 @@ update-browserslist-db@^1.1.1:
escalade "^3.2.0" escalade "^3.2.0"
picocolors "^1.1.0" picocolors "^1.1.0"
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
util-deprecate@^1.0.2: util-deprecate@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
vfile-message@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a"
integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==
dependencies:
"@types/unist" "^2.0.0"
unist-util-stringify-position "^2.0.0"
vfile@^4.0.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624"
integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==
dependencies:
"@types/unist" "^2.0.0"
is-buffer "^2.0.0"
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
vite@^5.0.11: vite@^5.0.11:
version "5.4.11" version "5.4.11"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"
@@ -2194,6 +2596,11 @@ which@^2.0.1:
dependencies: dependencies:
isexe "^2.0.0" isexe "^2.0.0"
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
integrity sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
@@ -2226,3 +2633,8 @@ yaml@^2.3.4:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773"
integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg== integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==
zwitch@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==

View File

@@ -1 +1 @@
__version__ = "2.16.0" __version__ = "2.17.0"

View File

@@ -841,8 +841,6 @@ def delete_course(course):
frappe.delete_doc("Lesson Reference", lesson) frappe.delete_doc("Lesson Reference", lesson)
for lesson in lessons: for lesson in lessons:
frappe.db.delete("LMS Course Progress", {"lesson": lesson})
topics = frappe.get_all( topics = frappe.get_all(
"Discussion Topic", "Discussion Topic",
{"reference_doctype": "Course Lesson", "reference_docname": lesson}, {"reference_doctype": "Course Lesson", "reference_docname": lesson},
@@ -862,6 +860,9 @@ def delete_course(course):
for chapter in chapters: for chapter in chapters:
frappe.delete_doc("Course Chapter", chapter) frappe.delete_doc("Course Chapter", chapter)
frappe.db.delete("LMS Course Progress", {"course": course})
frappe.db.delete("LMS Quiz", {"course": course})
frappe.db.delete("LMS Quiz Submission", {"course": course})
frappe.db.delete("LMS Enrollment", {"course": course}) frappe.db.delete("LMS Enrollment", {"course": course})
frappe.delete_doc("LMS Course", course) frappe.delete_doc("LMS Course", course)

View File

@@ -17,6 +17,7 @@ class LMSQuizSubmission(Document):
self.notify_member() self.notify_member()
def validate_marks(self): def validate_marks(self):
self.score = 0
for row in self.result: for row in self.result:
if cint(row.marks) > cint(row.marks_out_of): if cint(row.marks) > cint(row.marks_out_of):
frappe.throw( frappe.throw(

View File

@@ -874,26 +874,6 @@ def is_onboarding_complete():
} }
def has_submitted_assessment(assessment, type, member=None):
if not member:
member = frappe.session.user
doctype = (
"LMS Assignment Submission" if type == "LMS Assignment" else "LMS Quiz Submission"
)
docfield = "assignment" if type == "LMS Assignment" else "quiz"
filters = {}
filters[docfield] = assessment
filters["member"] = member
return frappe.db.exists(doctype, filters)
def has_graded_assessment(submission):
status = frappe.db.get_value("LMS Assignment Submission", submission, "status")
return False if status == "Not Graded" else True
def get_evaluator(course, batch): def get_evaluator(course, batch):
evaluator = None evaluator = None
evaluator = frappe.db.get_value( evaluator = frappe.db.get_value(
@@ -1459,13 +1439,11 @@ def get_quiz_details(assessment, member):
@frappe.whitelist() @frappe.whitelist()
def get_batch_students(batch): def get_batch_students(batch):
students = [] students = []
students_list = frappe.get_all( students_list = frappe.get_all(
"Batch Student", filters={"parent": batch}, fields=["student", "name"] "Batch Student", filters={"parent": batch}, fields=["student", "name"]
) )
batch_courses = frappe.get_all("Batch Course", {"parent": batch}, pluck="course") batch_courses = frappe.get_all("Batch Course", {"parent": batch}, ["course", "title"])
assessments = frappe.get_all( assessments = frappe.get_all(
"LMS Assessment", "LMS Assessment",
filters={"parent": batch}, filters={"parent": batch},
@@ -1483,29 +1461,64 @@ def get_batch_students(batch):
) )
detail.last_active = format_datetime(detail.last_active, "dd MMM YY") detail.last_active = format_datetime(detail.last_active, "dd MMM YY")
detail.name = student.name detail.name = student.name
students.append(detail) detail.courses = frappe._dict()
detail.assessments = frappe._dict()
""" Iterate through courses and track their progress """
for course in batch_courses: for course in batch_courses:
progress = frappe.db.get_value( progress = frappe.db.get_value(
"LMS Enrollment", {"course": course, "member": student.student}, "progress" "LMS Enrollment", {"course": course.course, "member": student.student}, "progress"
) )
detail.courses[course.title] = progress
if progress == 100: if progress == 100:
courses_completed += 1 courses_completed += 1
detail.courses_completed = courses_completed """ Iterate through assessments and track their progress """
for assessment in assessments: for assessment in assessments:
if has_submitted_assessment( title = frappe.db.get_value(
assessment.assessment_type, assessment.assessment_name, "title"
)
status = has_submitted_assessment(
assessment.assessment_name, assessment.assessment_type, student.student assessment.assessment_name, assessment.assessment_type, student.student
): )
detail.assessments[title] = status
if status not in ["Not Attempted", 0]:
assessments_completed += 1 assessments_completed += 1
detail.courses_completed = courses_completed
detail.assessments_completed = assessments_completed detail.assessments_completed = assessments_completed
students.append(detail)
return students return students
def has_submitted_assessment(assessment, assessment_type, member=None):
if not member:
member = frappe.session.user
if assessment_type == "LMS Assignment":
doctype = "LMS Assignment Submission"
docfield = "assignment"
fields = ["status"]
not_attempted = "Not Attempted"
elif assessment_type == "LMS Quiz":
doctype = "LMS Quiz Submission"
docfield = "quiz"
fields = ["percentage"]
not_attempted = 0
filters = {}
filters[docfield] = assessment
filters["member"] = member
attempt = frappe.db.exists(doctype, filters)
if attempt:
attempt_details = frappe.db.get_value(doctype, filters, fields)
return attempt_details
else:
return not_attempted
@frappe.whitelist() @frappe.whitelist()
def get_discussion_topics(doctype, docname, single_thread): def get_discussion_topics(doctype, docname, single_thread):
if single_thread: if single_thread:

View File

@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: jannat@frappe.io\n" "Report-Msgid-Bugs-To: jannat@frappe.io\n"
"POT-Creation-Date: 2024-12-06 16:04+0000\n" "POT-Creation-Date: 2024-12-13 16:04+0000\n"
"PO-Revision-Date: 2024-12-09 23:31\n" "PO-Revision-Date: 2024-12-18 00:37\n"
"Last-Translator: jannat@frappe.io\n" "Last-Translator: jannat@frappe.io\n"
"Language-Team: Esperanto\n" "Language-Team: Esperanto\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -101,7 +101,7 @@ msgstr "crwdns149210:0crwdne149210:0"
#: frontend/src/components/Assessments.vue:11 #: frontend/src/components/Assessments.vue:11
#: frontend/src/components/BatchCourses.vue:11 #: frontend/src/components/BatchCourses.vue:11
#: frontend/src/components/BatchStudents.vue:6 #: frontend/src/components/BatchStudents.vue:10
#: frontend/src/components/Categories.vue:26 #: frontend/src/components/Categories.vue:26
#: frontend/src/components/LiveClass.vue:11 #: frontend/src/components/LiveClass.vue:11
#: frontend/src/components/Members.vue:43 frontend/src/pages/ProgramForm.vue:30 #: frontend/src/components/Members.vue:43 frontend/src/pages/ProgramForm.vue:30
@@ -1702,7 +1702,7 @@ msgstr "crwdns149728:0crwdne149728:0"
msgid "Enrollment Count" msgid "Enrollment Count"
msgstr "crwdns149730:0crwdne149730:0" msgstr "crwdns149730:0crwdne149730:0"
#: lms/lms/utils.py:1702 #: lms/lms/utils.py:1715
msgid "Enrollment Failed" msgid "Enrollment Failed"
msgstr "crwdns149732:0crwdne149732:0" msgstr "crwdns149732:0crwdne149732:0"
@@ -1738,6 +1738,7 @@ msgstr "crwdns149742:0crwdne149742:0"
#: frontend/src/components/Modals/Question.vue:249 #: frontend/src/components/Modals/Question.vue:249
#: frontend/src/components/Modals/Question.vue:269 #: frontend/src/components/Modals/Question.vue:269
#: frontend/src/components/Modals/Question.vue:326 #: frontend/src/components/Modals/Question.vue:326
#: frontend/src/components/Modals/StudentModal.vue:69
#: frontend/src/components/SettingDetails.vue:62 #: frontend/src/components/SettingDetails.vue:62
#: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:350 #: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:350
#: frontend/src/pages/QuizForm.vue:365 #: frontend/src/pages/QuizForm.vue:365
@@ -2812,7 +2813,7 @@ msgstr "crwdns150108:0crwdne150108:0"
msgid "LiveCode URL" msgid "LiveCode URL"
msgstr "crwdns150110:0crwdne150110:0" msgstr "crwdns150110:0crwdne150110:0"
#: frontend/src/components/Members.vue:95 #: frontend/src/components/Members.vue:106
msgid "Load More" msgid "Load More"
msgstr "crwdns150112:0crwdne150112:0" msgstr "crwdns150112:0crwdne150112:0"
@@ -3230,7 +3231,7 @@ msgstr "crwdns150238:0crwdne150238:0"
msgid "Next Question" msgid "Next Question"
msgstr "crwdns150240:0crwdne150240:0" msgstr "crwdns150240:0crwdne150240:0"
#: frontend/src/components/Assessments.vue:63 lms/templates/assessments.html:58 #: frontend/src/components/Assessments.vue:66 lms/templates/assessments.html:58
msgid "No Assessments" msgid "No Assessments"
msgstr "crwdns150242:0crwdne150242:0" msgstr "crwdns150242:0crwdne150242:0"
@@ -3687,7 +3688,7 @@ msgstr "crwdns150404:0crwdne150404:0"
msgid "Please click on the following button to set your new password" msgid "Please click on the following button to set your new password"
msgstr "crwdns150406:0crwdne150406:0" msgstr "crwdns150406:0crwdne150406:0"
#: lms/lms/utils.py:1824 lms/lms/utils.py:1828 #: lms/lms/utils.py:1837 lms/lms/utils.py:1841
msgid "Please complete the previous courses in the program to enroll in this course." msgid "Please complete the previous courses in the program to enroll in this course."
msgstr "crwdns151772:0crwdne151772:0" msgstr "crwdns151772:0crwdne151772:0"
@@ -4700,13 +4701,13 @@ msgstr "crwdns150746:0{0}crwdne150746:0"
#. Label of the students (Table) field in DocType 'LMS Batch' #. Label of the students (Table) field in DocType 'LMS Batch'
#. Label of the show_students (Check) field in DocType 'LMS Settings' #. Label of the show_students (Check) field in DocType 'LMS Settings'
#: frontend/src/components/BatchStudents.vue:9 #: frontend/src/components/BatchStudents.vue:4
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Students" msgid "Students"
msgstr "crwdns150748:0crwdne150748:0" msgstr "crwdns150748:0crwdne150748:0"
#: frontend/src/components/BatchStudents.vue:157 #: frontend/src/components/BatchStudents.vue:191
msgid "Students deleted successfully" msgid "Students deleted successfully"
msgstr "crwdns150750:0crwdne150750:0" msgstr "crwdns150750:0crwdne150750:0"
@@ -4758,7 +4759,7 @@ msgstr "crwdns150766:0{0}crwdne150766:0"
#: frontend/src/components/BatchCourses.vue:150 #: frontend/src/components/BatchCourses.vue:150
#: frontend/src/components/BatchOverlay.vue:135 #: frontend/src/components/BatchOverlay.vue:135
#: frontend/src/components/BatchStudents.vue:157 #: frontend/src/components/BatchStudents.vue:191
#: frontend/src/components/CourseCardOverlay.vue:161 #: frontend/src/components/CourseCardOverlay.vue:161
#: frontend/src/components/Modals/AnnouncementModal.vue:99 #: frontend/src/components/Modals/AnnouncementModal.vue:99
#: frontend/src/components/Modals/AssessmentModal.vue:73 #: frontend/src/components/Modals/AssessmentModal.vue:73
@@ -4946,7 +4947,7 @@ msgstr "crwdns151798:0crwdne151798:0"
msgid "There are no seats available in this batch." msgid "There are no seats available in this batch."
msgstr "crwdns150808:0crwdne150808:0" msgstr "crwdns150808:0crwdne150808:0"
#: frontend/src/components/BatchStudents.vue:67 #: frontend/src/components/BatchStudents.vue:86
msgid "There are no students in this batch." msgid "There are no students in this batch."
msgstr "crwdns150810:0crwdne150810:0" msgstr "crwdns150810:0crwdne150810:0"
@@ -4977,7 +4978,7 @@ msgstr "crwdns150818:0crwdne150818:0"
msgid "This course has:" msgid "This course has:"
msgstr "crwdns150820:0crwdne150820:0" msgstr "crwdns150820:0crwdne150820:0"
#: lms/lms/utils.py:1582 #: lms/lms/utils.py:1595
msgid "This course is free." msgid "This course is free."
msgstr "crwdns150822:0crwdne150822:0" msgstr "crwdns150822:0crwdne150822:0"
@@ -5119,7 +5120,7 @@ msgstr "crwdns150852:0crwdne150852:0"
msgid "To Date" msgid "To Date"
msgstr "crwdns150854:0crwdne150854:0" msgstr "crwdns150854:0crwdne150854:0"
#: lms/lms/utils.py:1593 #: lms/lms/utils.py:1606
msgid "To join this batch, please contact the Administrator." msgid "To join this batch, please contact the Administrator."
msgstr "crwdns150858:0crwdne150858:0" msgstr "crwdns150858:0crwdne150858:0"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: jannat@frappe.io\n" "Report-Msgid-Bugs-To: jannat@frappe.io\n"
"POT-Creation-Date: 2024-12-06 16:04+0000\n" "POT-Creation-Date: 2024-12-06 16:04+0000\n"
"PO-Revision-Date: 2024-12-09 23:31\n" "PO-Revision-Date: 2024-12-17 00:07\n"
"Last-Translator: jannat@frappe.io\n" "Last-Translator: jannat@frappe.io\n"
"Language-Team: Persian\n" "Language-Team: Persian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -2469,7 +2469,7 @@ msgstr ""
#: frontend/src/pages/CourseForm.vue:136 #: frontend/src/pages/CourseForm.vue:136
msgid "Keywords for the course" msgid "Keywords for the course"
msgstr "" msgstr "کلمات کلیدی برای دوره"
#. Name of a Workspace #. Name of a Workspace
#: lms/lms/workspace/lms/lms.json #: lms/lms/workspace/lms/lms.json
@@ -3265,7 +3265,7 @@ msgstr ""
#: frontend/src/pages/Courses.vue:147 #: frontend/src/pages/Courses.vue:147
msgid "No courses found" msgid "No courses found"
msgstr "" msgstr "هیچ دوره ای پیدا نشد"
#: frontend/src/pages/Programs.vue:83 #: frontend/src/pages/Programs.vue:83
msgid "No courses in this program" msgid "No courses in this program"

View File

@@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Frappe LMS VERSION\n" "Project-Id-Version: Frappe LMS VERSION\n"
"Report-Msgid-Bugs-To: jannat@frappe.io\n" "Report-Msgid-Bugs-To: jannat@frappe.io\n"
"POT-Creation-Date: 2024-12-06 16:04+0000\n" "POT-Creation-Date: 2024-12-13 16:04+0000\n"
"PO-Revision-Date: 2024-12-06 16:04+0000\n" "PO-Revision-Date: 2024-12-13 16:04+0000\n"
"Last-Translator: jannat@frappe.io\n" "Last-Translator: jannat@frappe.io\n"
"Language-Team: jannat@frappe.io\n" "Language-Team: jannat@frappe.io\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -99,7 +99,7 @@ msgstr ""
#: frontend/src/components/Assessments.vue:11 #: frontend/src/components/Assessments.vue:11
#: frontend/src/components/BatchCourses.vue:11 #: frontend/src/components/BatchCourses.vue:11
#: frontend/src/components/BatchStudents.vue:6 #: frontend/src/components/BatchStudents.vue:10
#: frontend/src/components/Categories.vue:26 #: frontend/src/components/Categories.vue:26
#: frontend/src/components/LiveClass.vue:11 #: frontend/src/components/LiveClass.vue:11
#: frontend/src/components/Members.vue:43 frontend/src/pages/ProgramForm.vue:30 #: frontend/src/components/Members.vue:43 frontend/src/pages/ProgramForm.vue:30
@@ -1700,7 +1700,7 @@ msgstr ""
msgid "Enrollment Count" msgid "Enrollment Count"
msgstr "" msgstr ""
#: lms/lms/utils.py:1702 #: lms/lms/utils.py:1715
msgid "Enrollment Failed" msgid "Enrollment Failed"
msgstr "" msgstr ""
@@ -1736,6 +1736,7 @@ msgstr ""
#: frontend/src/components/Modals/Question.vue:249 #: frontend/src/components/Modals/Question.vue:249
#: frontend/src/components/Modals/Question.vue:269 #: frontend/src/components/Modals/Question.vue:269
#: frontend/src/components/Modals/Question.vue:326 #: frontend/src/components/Modals/Question.vue:326
#: frontend/src/components/Modals/StudentModal.vue:69
#: frontend/src/components/SettingDetails.vue:62 #: frontend/src/components/SettingDetails.vue:62
#: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:350 #: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:350
#: frontend/src/pages/QuizForm.vue:365 #: frontend/src/pages/QuizForm.vue:365
@@ -2810,7 +2811,7 @@ msgstr ""
msgid "LiveCode URL" msgid "LiveCode URL"
msgstr "" msgstr ""
#: frontend/src/components/Members.vue:95 #: frontend/src/components/Members.vue:106
msgid "Load More" msgid "Load More"
msgstr "" msgstr ""
@@ -3228,7 +3229,7 @@ msgstr ""
msgid "Next Question" msgid "Next Question"
msgstr "" msgstr ""
#: frontend/src/components/Assessments.vue:63 lms/templates/assessments.html:58 #: frontend/src/components/Assessments.vue:66 lms/templates/assessments.html:58
msgid "No Assessments" msgid "No Assessments"
msgstr "" msgstr ""
@@ -3685,7 +3686,7 @@ msgstr ""
msgid "Please click on the following button to set your new password" msgid "Please click on the following button to set your new password"
msgstr "" msgstr ""
#: lms/lms/utils.py:1824 lms/lms/utils.py:1828 #: lms/lms/utils.py:1837 lms/lms/utils.py:1841
msgid "Please complete the previous courses in the program to enroll in this course." msgid "Please complete the previous courses in the program to enroll in this course."
msgstr "" msgstr ""
@@ -4698,13 +4699,13 @@ msgstr ""
#. Label of the students (Table) field in DocType 'LMS Batch' #. Label of the students (Table) field in DocType 'LMS Batch'
#. Label of the show_students (Check) field in DocType 'LMS Settings' #. Label of the show_students (Check) field in DocType 'LMS Settings'
#: frontend/src/components/BatchStudents.vue:9 #: frontend/src/components/BatchStudents.vue:4
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Students" msgid "Students"
msgstr "" msgstr ""
#: frontend/src/components/BatchStudents.vue:157 #: frontend/src/components/BatchStudents.vue:191
msgid "Students deleted successfully" msgid "Students deleted successfully"
msgstr "" msgstr ""
@@ -4756,7 +4757,7 @@ msgstr ""
#: frontend/src/components/BatchCourses.vue:150 #: frontend/src/components/BatchCourses.vue:150
#: frontend/src/components/BatchOverlay.vue:135 #: frontend/src/components/BatchOverlay.vue:135
#: frontend/src/components/BatchStudents.vue:157 #: frontend/src/components/BatchStudents.vue:191
#: frontend/src/components/CourseCardOverlay.vue:161 #: frontend/src/components/CourseCardOverlay.vue:161
#: frontend/src/components/Modals/AnnouncementModal.vue:99 #: frontend/src/components/Modals/AnnouncementModal.vue:99
#: frontend/src/components/Modals/AssessmentModal.vue:73 #: frontend/src/components/Modals/AssessmentModal.vue:73
@@ -4944,7 +4945,7 @@ msgstr ""
msgid "There are no seats available in this batch." msgid "There are no seats available in this batch."
msgstr "" msgstr ""
#: frontend/src/components/BatchStudents.vue:67 #: frontend/src/components/BatchStudents.vue:86
msgid "There are no students in this batch." msgid "There are no students in this batch."
msgstr "" msgstr ""
@@ -4975,7 +4976,7 @@ msgstr ""
msgid "This course has:" msgid "This course has:"
msgstr "" msgstr ""
#: lms/lms/utils.py:1582 #: lms/lms/utils.py:1595
msgid "This course is free." msgid "This course is free."
msgstr "" msgstr ""
@@ -5117,7 +5118,7 @@ msgstr ""
msgid "To Date" msgid "To Date"
msgstr "" msgstr ""
#: lms/lms/utils.py:1593 #: lms/lms/utils.py:1606
msgid "To join this batch, please contact the Administrator." msgid "To join this batch, please contact the Administrator."
msgstr "" msgstr ""

View File

@@ -162,3 +162,14 @@ class SCORMRenderer(BaseRenderer):
) )
response.mimetype = mimetypes.guess_type(path)[0] response.mimetype = mimetypes.guess_type(path)[0]
return response return response
else:
path = path.replace(".html", "")
if os.path.exists(path) and os.path.isdir(path):
index_path = os.path.join(path, "index.html")
if os.path.exists(index_path):
f = open(index_path, "rb")
response = Response(
wrap_file(frappe.local.request.environ, f), direct_passthrough=True
)
response.mimetype = mimetypes.guess_type(index_path)[0]
return response