@learnmd/core 0.0.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/components/LearnMDProvider.d.ts +33 -0
- package/dist/components/LearnMDProvider.d.ts.map +1 -0
- package/dist/components/LearnMDProvider.js +16 -0
- package/dist/components/LearnMDProvider.js.map +1 -0
- package/dist/gamification/index.d.ts +77 -0
- package/dist/gamification/index.d.ts.map +1 -0
- package/dist/gamification/index.js +402 -0
- package/dist/gamification/index.js.map +1 -0
- package/dist/i18n/index.d.ts +119 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +261 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/index.d.ts +57 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +182 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/plugins/index.d.ts +150 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +291 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/pdf/index.d.ts +8 -0
- package/dist/plugins/pdf/index.d.ts.map +1 -0
- package/dist/plugins/pdf/index.js +53 -0
- package/dist/plugins/pdf/index.js.map +1 -0
- package/dist/router/index.d.ts +111 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +268 -0
- package/dist/router/index.js.map +1 -0
- package/dist/storage/index.d.ts +110 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +390 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types/index.d.ts +283 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 LearnMD Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 🏗️ @learnmd/core
|
|
2
|
+
|
|
3
|
+
The heart of the LearnMD engine. This package contains the fundamental logic for parsing, internationalization, storage, and state management.
|
|
4
|
+
|
|
5
|
+
## 📦 Features
|
|
6
|
+
|
|
7
|
+
- **MDX Integration**: Seamlessly bridges Markdown content with React components.
|
|
8
|
+
- **i18n Engine**: Handles paragraph-level translations and language persistence.
|
|
9
|
+
- **Storage Adapter**: Flexible persistence layer for progress tracking (LocalStorage, etc).
|
|
10
|
+
- **Gamification**: Logic for points, badges, and achievement criteria.
|
|
11
|
+
- **Router**: Managed navigation between modules and lessons.
|
|
12
|
+
|
|
13
|
+
## 🛠️ Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { defineConfig, createLearnMD } from '@learnmd/core';
|
|
17
|
+
|
|
18
|
+
export const config = defineConfig({
|
|
19
|
+
title: 'My Awesome Course',
|
|
20
|
+
defaultLanguage: 'en',
|
|
21
|
+
// ...
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 🏗️ Architecture
|
|
26
|
+
|
|
27
|
+
- `/parser`: Logic for handling MDX transformations.
|
|
28
|
+
- `/i18n`: The translation manager.
|
|
29
|
+
- `/storage`: Progress persistence adapters.
|
|
30
|
+
- `/types`: Comprehensive TypeScript definitions for courses, lessons, and metrics.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LearnMDConfig } from '../index.js';
|
|
3
|
+
export declare const LearnMDContext: React.Context<{
|
|
4
|
+
i18n: import("../index.js").I18nManager;
|
|
5
|
+
storage: import("../index.js").StorageManager;
|
|
6
|
+
gamification: import("../index.js").GamificationManager | null;
|
|
7
|
+
router: import("../index.js").RouterManager;
|
|
8
|
+
config: {
|
|
9
|
+
defaultLanguage: string;
|
|
10
|
+
basePath: string;
|
|
11
|
+
storagePrefix: string;
|
|
12
|
+
enableGamification: boolean;
|
|
13
|
+
enableAnalytics: boolean;
|
|
14
|
+
};
|
|
15
|
+
} | null>;
|
|
16
|
+
export declare function useLearnMD(): {
|
|
17
|
+
i18n: import("../index.js").I18nManager;
|
|
18
|
+
storage: import("../index.js").StorageManager;
|
|
19
|
+
gamification: import("../index.js").GamificationManager | null;
|
|
20
|
+
router: import("../index.js").RouterManager;
|
|
21
|
+
config: {
|
|
22
|
+
defaultLanguage: string;
|
|
23
|
+
basePath: string;
|
|
24
|
+
storagePrefix: string;
|
|
25
|
+
enableGamification: boolean;
|
|
26
|
+
enableAnalytics: boolean;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export declare function LearnMDProvider({ config, children }: {
|
|
30
|
+
config: LearnMDConfig;
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
//# sourceMappingURL=LearnMDProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LearnMDProvider.d.ts","sourceRoot":"","sources":["../../src/components/LearnMDProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,eAAO,MAAM,cAAc;;;;;;;;;;;;SAA+D,CAAC;AAE3F,wBAAgB,UAAU;;;;;;;;;;;;EAMzB;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAIzG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
3
|
+
import { createLearnMD } from '../index.js';
|
|
4
|
+
export const LearnMDContext = createContext(null);
|
|
5
|
+
export function useLearnMD() {
|
|
6
|
+
const context = useContext(LearnMDContext);
|
|
7
|
+
if (!context) {
|
|
8
|
+
throw new Error('useLearnMD must be used within a LearnMDProvider');
|
|
9
|
+
}
|
|
10
|
+
return context;
|
|
11
|
+
}
|
|
12
|
+
export function LearnMDProvider({ config, children }) {
|
|
13
|
+
const learnmd = useMemo(() => createLearnMD(config), [config]);
|
|
14
|
+
return _jsx(LearnMDContext.Provider, { value: learnmd, children: children });
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=LearnMDProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LearnMDProvider.js","sourceRoot":"","sources":["../../src/components/LearnMDProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AAE3D,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAA0C,IAAI,CAAC,CAAC;AAE3F,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAwD;IACxG,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/D,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAA2B,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Badge, Achievement, UserProfile, CourseProgress, LessonProgress } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Default badges configuration
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_BADGES: Omit<Badge, 'earnedAt' | 'courseId'>[];
|
|
6
|
+
/**
|
|
7
|
+
* Default achievements configuration
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_ACHIEVEMENTS: Omit<Achievement, 'unlockedAt'>[];
|
|
10
|
+
/**
|
|
11
|
+
* Points configuration
|
|
12
|
+
*/
|
|
13
|
+
export declare const POINTS_CONFIG: {
|
|
14
|
+
lessonCompleted: number;
|
|
15
|
+
quizPassed: number;
|
|
16
|
+
quizPerfectScore: number;
|
|
17
|
+
dailyBonus: number;
|
|
18
|
+
streakBonus: {
|
|
19
|
+
7: number;
|
|
20
|
+
30: number;
|
|
21
|
+
100: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Gamification manager
|
|
26
|
+
*/
|
|
27
|
+
export declare class GamificationManager {
|
|
28
|
+
private readonly badges;
|
|
29
|
+
private readonly achievements;
|
|
30
|
+
private readonly pointsConfig;
|
|
31
|
+
constructor();
|
|
32
|
+
/**
|
|
33
|
+
* Register a custom badge
|
|
34
|
+
*/
|
|
35
|
+
registerBadge(badge: Omit<Badge, 'earnedAt' | 'courseId'>): void;
|
|
36
|
+
/**
|
|
37
|
+
* Register a custom achievement
|
|
38
|
+
*/
|
|
39
|
+
registerAchievement(achievement: Omit<Achievement, 'unlockedAt'>): void;
|
|
40
|
+
/**
|
|
41
|
+
* Calculate points for lesson completion
|
|
42
|
+
*/
|
|
43
|
+
calculateLessonPoints(quizScore?: number, quizPassed?: boolean): number;
|
|
44
|
+
/**
|
|
45
|
+
* Check and award badges for lesson completion
|
|
46
|
+
*/
|
|
47
|
+
checkBadges(progress: CourseProgress, lessonProgress: LessonProgress, userProfile: UserProfile): Badge[];
|
|
48
|
+
/**
|
|
49
|
+
* Check and award achievements
|
|
50
|
+
*/
|
|
51
|
+
checkAchievements(userProfile: UserProfile): Achievement[];
|
|
52
|
+
/**
|
|
53
|
+
* Update user streak
|
|
54
|
+
*/
|
|
55
|
+
updateStreak(userProfile: UserProfile): UserProfile;
|
|
56
|
+
/**
|
|
57
|
+
* Get all available badges
|
|
58
|
+
*/
|
|
59
|
+
getAllBadges(): Omit<Badge, 'earnedAt' | 'courseId'>[];
|
|
60
|
+
/**
|
|
61
|
+
* Get all available achievements
|
|
62
|
+
*/
|
|
63
|
+
getAllAchievements(): Omit<Achievement, 'unlockedAt'>[];
|
|
64
|
+
/**
|
|
65
|
+
* Get badge by ID
|
|
66
|
+
*/
|
|
67
|
+
getBadge(id: string): Omit<Badge, 'earnedAt' | 'courseId'> | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Get achievement by ID
|
|
70
|
+
*/
|
|
71
|
+
getAchievement(id: string): Omit<Achievement, 'unlockedAt'> | undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create gamification manager instance
|
|
75
|
+
*/
|
|
76
|
+
export declare function createGamificationManager(): GamificationManager;
|
|
77
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gamification/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEhG;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,EAyEhE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EAyEjE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;CAUzB,CAAC;AAEF;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoD;IAC3E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+C;IAC5E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;;IAQpD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,IAAI;IAIvE;;OAEG;IACH,qBAAqB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM;IAcvE;;OAEG;IACH,WAAW,CACT,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,WAAW,GACvB,KAAK,EAAE;IAgFV;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW,EAAE;IAkE1D;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW;IA2CnD;;OAEG;IACH,YAAY,IAAI,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,EAAE;IAItD;;OAEG;IACH,kBAAkB,IAAI,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE;IAIvD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,SAAS;IAItE;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,SAAS;CAGxE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,mBAAmB,CAE/D"}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default badges configuration
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_BADGES = [
|
|
5
|
+
{
|
|
6
|
+
id: 'first-lesson',
|
|
7
|
+
name: { en: 'First Steps', es: 'Primeros Pasos' },
|
|
8
|
+
description: {
|
|
9
|
+
en: 'Complete your first lesson',
|
|
10
|
+
es: 'Completa tu primera lección',
|
|
11
|
+
},
|
|
12
|
+
icon: '🎯',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'quick-learner',
|
|
16
|
+
name: { en: 'Quick Learner', es: 'Aprendiz Rápido' },
|
|
17
|
+
description: {
|
|
18
|
+
en: 'Complete 5 lessons in one day',
|
|
19
|
+
es: 'Completa 5 lecciones en un día',
|
|
20
|
+
},
|
|
21
|
+
icon: '⚡',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: ' perfectionist',
|
|
25
|
+
name: { en: 'Perfectionist', es: 'Perfeccionista' },
|
|
26
|
+
description: {
|
|
27
|
+
en: 'Get 100% on a quiz',
|
|
28
|
+
es: 'Obtén 100% en un quiz',
|
|
29
|
+
},
|
|
30
|
+
icon: '💯',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'course-complete',
|
|
34
|
+
name: { en: 'Course Complete', es: 'Curso Completado' },
|
|
35
|
+
description: {
|
|
36
|
+
en: 'Complete an entire course',
|
|
37
|
+
es: 'Completa un curso entero',
|
|
38
|
+
},
|
|
39
|
+
icon: '🎓',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'week-streak',
|
|
43
|
+
name: { en: 'Week Warrior', es: 'Guerrero Semanal' },
|
|
44
|
+
description: {
|
|
45
|
+
en: 'Maintain a 7-day streak',
|
|
46
|
+
es: 'Mantén una racha de 7 días',
|
|
47
|
+
},
|
|
48
|
+
icon: '🔥',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'month-streak',
|
|
52
|
+
name: { en: 'Monthly Master', es: 'Maestro Mensual' },
|
|
53
|
+
description: {
|
|
54
|
+
en: 'Maintain a 30-day streak',
|
|
55
|
+
es: 'Mantén una racha de 30 días',
|
|
56
|
+
},
|
|
57
|
+
icon: '👑',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'knowledge-seeker',
|
|
61
|
+
name: { en: 'Knowledge Seeker', es: 'Buscador de Conocimiento' },
|
|
62
|
+
description: {
|
|
63
|
+
en: 'Complete 10 lessons',
|
|
64
|
+
es: 'Completa 10 lecciones',
|
|
65
|
+
},
|
|
66
|
+
icon: '📚',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'scholar',
|
|
70
|
+
name: { en: 'Scholar', es: 'Erudito' },
|
|
71
|
+
description: {
|
|
72
|
+
en: 'Complete 50 lessons',
|
|
73
|
+
es: 'Completa 50 lecciones',
|
|
74
|
+
},
|
|
75
|
+
icon: '🏆',
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
/**
|
|
79
|
+
* Default achievements configuration
|
|
80
|
+
*/
|
|
81
|
+
export const DEFAULT_ACHIEVEMENTS = [
|
|
82
|
+
{
|
|
83
|
+
id: 'lessons-10',
|
|
84
|
+
name: { en: 'Dedicated Learner', es: 'Aprendiz Dedicado' },
|
|
85
|
+
description: {
|
|
86
|
+
en: 'Complete 10 lessons',
|
|
87
|
+
es: 'Completa 10 lecciones',
|
|
88
|
+
},
|
|
89
|
+
criteria: {
|
|
90
|
+
type: 'lessons_completed',
|
|
91
|
+
value: 10,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'lessons-50',
|
|
96
|
+
name: { en: 'Knowledge Master', es: 'Maestro del Conocimiento' },
|
|
97
|
+
description: {
|
|
98
|
+
en: 'Complete 50 lessons',
|
|
99
|
+
es: 'Completa 50 lecciones',
|
|
100
|
+
},
|
|
101
|
+
criteria: {
|
|
102
|
+
type: 'lessons_completed',
|
|
103
|
+
value: 50,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'points-1000',
|
|
108
|
+
name: { en: 'Point Collector', es: 'Coleccionista de Puntos' },
|
|
109
|
+
description: {
|
|
110
|
+
en: 'Earn 1000 points',
|
|
111
|
+
es: 'Gana 1000 puntos',
|
|
112
|
+
},
|
|
113
|
+
criteria: {
|
|
114
|
+
type: 'points_earned',
|
|
115
|
+
value: 1000,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 'streak-7',
|
|
120
|
+
name: { en: 'Consistent Learner', es: 'Aprendiz Consistente' },
|
|
121
|
+
description: {
|
|
122
|
+
en: 'Maintain a 7-day streak',
|
|
123
|
+
es: 'Mantén una racha de 7 días',
|
|
124
|
+
},
|
|
125
|
+
criteria: {
|
|
126
|
+
type: 'streak_days',
|
|
127
|
+
value: 7,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 'streak-30',
|
|
132
|
+
name: { en: 'Unstoppable', es: 'Imparable' },
|
|
133
|
+
description: {
|
|
134
|
+
en: 'Maintain a 30-day streak',
|
|
135
|
+
es: 'Mantén una racha de 30 días',
|
|
136
|
+
},
|
|
137
|
+
criteria: {
|
|
138
|
+
type: 'streak_days',
|
|
139
|
+
value: 30,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'quizzes-10',
|
|
144
|
+
name: { en: 'Quiz Master', es: 'Maestro de Quizzes' },
|
|
145
|
+
description: {
|
|
146
|
+
en: 'Pass 10 quizzes',
|
|
147
|
+
es: 'Aprueba 10 quizzes',
|
|
148
|
+
},
|
|
149
|
+
criteria: {
|
|
150
|
+
type: 'quizzes_passed',
|
|
151
|
+
value: 10,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
/**
|
|
156
|
+
* Points configuration
|
|
157
|
+
*/
|
|
158
|
+
export const POINTS_CONFIG = {
|
|
159
|
+
lessonCompleted: 10,
|
|
160
|
+
quizPassed: 20,
|
|
161
|
+
quizPerfectScore: 30,
|
|
162
|
+
dailyBonus: 5,
|
|
163
|
+
streakBonus: {
|
|
164
|
+
7: 50,
|
|
165
|
+
30: 200,
|
|
166
|
+
100: 500,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Gamification manager
|
|
171
|
+
*/
|
|
172
|
+
export class GamificationManager {
|
|
173
|
+
constructor() {
|
|
174
|
+
Object.defineProperty(this, "badges", {
|
|
175
|
+
enumerable: true,
|
|
176
|
+
configurable: true,
|
|
177
|
+
writable: true,
|
|
178
|
+
value: void 0
|
|
179
|
+
});
|
|
180
|
+
Object.defineProperty(this, "achievements", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
configurable: true,
|
|
183
|
+
writable: true,
|
|
184
|
+
value: void 0
|
|
185
|
+
});
|
|
186
|
+
Object.defineProperty(this, "pointsConfig", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
configurable: true,
|
|
189
|
+
writable: true,
|
|
190
|
+
value: void 0
|
|
191
|
+
});
|
|
192
|
+
this.badges = new Map(DEFAULT_BADGES.map((b) => [b.id, b]));
|
|
193
|
+
this.achievements = new Map(DEFAULT_ACHIEVEMENTS.map((a) => [a.id, a]));
|
|
194
|
+
this.pointsConfig = POINTS_CONFIG;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Register a custom badge
|
|
198
|
+
*/
|
|
199
|
+
registerBadge(badge) {
|
|
200
|
+
this.badges.set(badge.id, badge);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Register a custom achievement
|
|
204
|
+
*/
|
|
205
|
+
registerAchievement(achievement) {
|
|
206
|
+
this.achievements.set(achievement.id, achievement);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Calculate points for lesson completion
|
|
210
|
+
*/
|
|
211
|
+
calculateLessonPoints(quizScore, quizPassed) {
|
|
212
|
+
let points = this.pointsConfig.lessonCompleted;
|
|
213
|
+
if (quizPassed) {
|
|
214
|
+
points += this.pointsConfig.quizPassed;
|
|
215
|
+
}
|
|
216
|
+
if (quizScore === 100) {
|
|
217
|
+
points += this.pointsConfig.quizPerfectScore;
|
|
218
|
+
}
|
|
219
|
+
return points;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Check and award badges for lesson completion
|
|
223
|
+
*/
|
|
224
|
+
checkBadges(progress, lessonProgress, userProfile) {
|
|
225
|
+
const earnedBadges = [];
|
|
226
|
+
const now = Date.now();
|
|
227
|
+
// First lesson badge
|
|
228
|
+
if (progress.completedLessons.length === 1 &&
|
|
229
|
+
!userProfile.badges.some((b) => b.id === 'first-lesson')) {
|
|
230
|
+
const badge = this.badges.get('first-lesson');
|
|
231
|
+
if (badge) {
|
|
232
|
+
earnedBadges.push({ ...badge, earnedAt: now });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Quick learner badge (5 lessons in one day)
|
|
236
|
+
const today = new Date().toDateString();
|
|
237
|
+
const lessonsToday = progress.completedLessons.filter((slug) => {
|
|
238
|
+
const lp = progress.lessons[slug];
|
|
239
|
+
return lp?.completedAt && new Date(lp.completedAt).toDateString() === today;
|
|
240
|
+
}).length;
|
|
241
|
+
if (lessonsToday >= 5 && !userProfile.badges.some((b) => b.id === 'quick-learner')) {
|
|
242
|
+
const badge = this.badges.get('quick-learner');
|
|
243
|
+
if (badge) {
|
|
244
|
+
earnedBadges.push({ ...badge, earnedAt: now });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Perfectionist badge
|
|
248
|
+
if (lessonProgress.quizScore === 100 &&
|
|
249
|
+
!userProfile.badges.some((b) => b.id === 'perfectionist')) {
|
|
250
|
+
const badge = this.badges.get('perfectionist');
|
|
251
|
+
if (badge) {
|
|
252
|
+
earnedBadges.push({ ...badge, earnedAt: now, courseId: progress.courseId });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Course complete badge
|
|
256
|
+
if (progress.completedLessons.length > 0 &&
|
|
257
|
+
!userProfile.badges.some((b) => b.id === 'course-complete')) {
|
|
258
|
+
// Check if all lessons are completed (this would need total lessons count)
|
|
259
|
+
// For now, we'll award it when 10 lessons are completed
|
|
260
|
+
if (progress.completedLessons.length >= 10) {
|
|
261
|
+
const badge = this.badges.get('course-complete');
|
|
262
|
+
if (badge) {
|
|
263
|
+
earnedBadges.push({ ...badge, earnedAt: now, courseId: progress.courseId });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Knowledge seeker badge (10 lessons)
|
|
268
|
+
if (progress.completedLessons.length >= 10 &&
|
|
269
|
+
!userProfile.badges.some((b) => b.id === 'knowledge-seeker')) {
|
|
270
|
+
const badge = this.badges.get('knowledge-seeker');
|
|
271
|
+
if (badge) {
|
|
272
|
+
earnedBadges.push({ ...badge, earnedAt: now });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Scholar badge (50 lessons)
|
|
276
|
+
if (progress.completedLessons.length >= 50 &&
|
|
277
|
+
!userProfile.badges.some((b) => b.id === 'scholar')) {
|
|
278
|
+
const badge = this.badges.get('scholar');
|
|
279
|
+
if (badge) {
|
|
280
|
+
earnedBadges.push({ ...badge, earnedAt: now });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return earnedBadges;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Check and award achievements
|
|
287
|
+
*/
|
|
288
|
+
checkAchievements(userProfile) {
|
|
289
|
+
const earnedAchievements = [];
|
|
290
|
+
const now = Date.now();
|
|
291
|
+
// Count total lessons completed
|
|
292
|
+
const totalLessons = Object.values(userProfile.coursesProgress).reduce((sum, progress) => sum + progress.completedLessons.length, 0);
|
|
293
|
+
// Lessons achievements
|
|
294
|
+
for (const achievement of this.achievements.values()) {
|
|
295
|
+
if (achievement.criteria.type === 'lessons_completed') {
|
|
296
|
+
if (totalLessons >= achievement.criteria.value &&
|
|
297
|
+
!userProfile.achievements.some((a) => a.id === achievement.id)) {
|
|
298
|
+
earnedAchievements.push({ ...achievement, unlockedAt: now });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Points achievements
|
|
303
|
+
for (const achievement of this.achievements.values()) {
|
|
304
|
+
if (achievement.criteria.type === 'points_earned') {
|
|
305
|
+
if (userProfile.totalPoints >= achievement.criteria.value &&
|
|
306
|
+
!userProfile.achievements.some((a) => a.id === achievement.id)) {
|
|
307
|
+
earnedAchievements.push({ ...achievement, unlockedAt: now });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Streak achievements
|
|
312
|
+
for (const achievement of this.achievements.values()) {
|
|
313
|
+
if (achievement.criteria.type === 'streak_days') {
|
|
314
|
+
if (userProfile.streak.current >= achievement.criteria.value &&
|
|
315
|
+
!userProfile.achievements.some((a) => a.id === achievement.id)) {
|
|
316
|
+
earnedAchievements.push({ ...achievement, unlockedAt: now });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Quiz achievements
|
|
321
|
+
const totalQuizzesPassed = Object.values(userProfile.coursesProgress).reduce((sum, progress) => sum + Object.values(progress.lessons).filter((l) => l.quizPassed).length, 0);
|
|
322
|
+
for (const achievement of this.achievements.values()) {
|
|
323
|
+
if (achievement.criteria.type === 'quizzes_passed') {
|
|
324
|
+
if (totalQuizzesPassed >= achievement.criteria.value &&
|
|
325
|
+
!userProfile.achievements.some((a) => a.id === achievement.id)) {
|
|
326
|
+
earnedAchievements.push({ ...achievement, unlockedAt: now });
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return earnedAchievements;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Update user streak
|
|
334
|
+
*/
|
|
335
|
+
updateStreak(userProfile) {
|
|
336
|
+
const today = new Date().toISOString().split('T')[0];
|
|
337
|
+
const lastActive = userProfile.streak.lastActiveDate;
|
|
338
|
+
if (lastActive === today) {
|
|
339
|
+
// Already active today
|
|
340
|
+
return userProfile;
|
|
341
|
+
}
|
|
342
|
+
const yesterday = new Date();
|
|
343
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
344
|
+
const yesterdayStr = yesterday.toISOString().split('T')[0];
|
|
345
|
+
if (lastActive === yesterdayStr) {
|
|
346
|
+
// Continue streak
|
|
347
|
+
userProfile.streak.current += 1;
|
|
348
|
+
userProfile.streak.longest = Math.max(userProfile.streak.current, userProfile.streak.longest);
|
|
349
|
+
// Award streak badges
|
|
350
|
+
const streakBadges = [
|
|
351
|
+
{ days: 7, badgeId: 'week-streak' },
|
|
352
|
+
{ days: 30, badgeId: 'month-streak' },
|
|
353
|
+
];
|
|
354
|
+
for (const { days, badgeId } of streakBadges) {
|
|
355
|
+
if (userProfile.streak.current === days) {
|
|
356
|
+
const badge = this.badges.get(badgeId);
|
|
357
|
+
if (badge && !userProfile.badges.some((b) => b.id === badgeId)) {
|
|
358
|
+
userProfile.badges.push({ ...badge, earnedAt: Date.now() });
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
// Reset streak
|
|
365
|
+
userProfile.streak.current = 1;
|
|
366
|
+
}
|
|
367
|
+
userProfile.streak.lastActiveDate = today;
|
|
368
|
+
userProfile.updatedAt = Date.now();
|
|
369
|
+
return userProfile;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get all available badges
|
|
373
|
+
*/
|
|
374
|
+
getAllBadges() {
|
|
375
|
+
return Array.from(this.badges.values());
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Get all available achievements
|
|
379
|
+
*/
|
|
380
|
+
getAllAchievements() {
|
|
381
|
+
return Array.from(this.achievements.values());
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Get badge by ID
|
|
385
|
+
*/
|
|
386
|
+
getBadge(id) {
|
|
387
|
+
return this.badges.get(id);
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Get achievement by ID
|
|
391
|
+
*/
|
|
392
|
+
getAchievement(id) {
|
|
393
|
+
return this.achievements.get(id);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Create gamification manager instance
|
|
398
|
+
*/
|
|
399
|
+
export function createGamificationManager() {
|
|
400
|
+
return new GamificationManager();
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gamification/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAA2C;IACpE;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,gBAAgB,EAAE;QACjD,WAAW,EAAE;YACX,EAAE,EAAE,4BAA4B;YAChC,EAAE,EAAE,6BAA6B;SAClC;QACD,IAAI,EAAE,IAAI;KACX;IACD;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE;QACpD,WAAW,EAAE;YACX,EAAE,EAAE,+BAA+B;YACnC,EAAE,EAAE,gCAAgC;SACrC;QACD,IAAI,EAAE,GAAG;KACV;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,gBAAgB,EAAE;QACnD,WAAW,EAAE;YACX,EAAE,EAAE,oBAAoB;YACxB,EAAE,EAAE,uBAAuB;SAC5B;QACD,IAAI,EAAE,IAAI;KACX;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,kBAAkB,EAAE;QACvD,WAAW,EAAE;YACX,EAAE,EAAE,2BAA2B;YAC/B,EAAE,EAAE,0BAA0B;SAC/B;QACD,IAAI,EAAE,IAAI;KACX;IACD;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,kBAAkB,EAAE;QACpD,WAAW,EAAE;YACX,EAAE,EAAE,yBAAyB;YAC7B,EAAE,EAAE,4BAA4B;SACjC;QACD,IAAI,EAAE,IAAI;KACX;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,iBAAiB,EAAE;QACrD,WAAW,EAAE;YACX,EAAE,EAAE,0BAA0B;YAC9B,EAAE,EAAE,6BAA6B;SAClC;QACD,IAAI,EAAE,IAAI;KACX;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,0BAA0B,EAAE;QAChE,WAAW,EAAE;YACX,EAAE,EAAE,qBAAqB;YACzB,EAAE,EAAE,uBAAuB;SAC5B;QACD,IAAI,EAAE,IAAI;KACX;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE;QACtC,WAAW,EAAE;YACX,EAAE,EAAE,qBAAqB;YACzB,EAAE,EAAE,uBAAuB;SAC5B;QACD,IAAI,EAAE,IAAI;KACX;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsC;IACrE;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE,mBAAmB,EAAE;QAC1D,WAAW,EAAE;YACX,EAAE,EAAE,qBAAqB;YACzB,EAAE,EAAE,uBAAuB;SAC5B;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,mBAAmB;YACzB,KAAK,EAAE,EAAE;SACV;KACF;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,0BAA0B,EAAE;QAChE,WAAW,EAAE;YACX,EAAE,EAAE,qBAAqB;YACzB,EAAE,EAAE,uBAAuB;SAC5B;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,mBAAmB;YACzB,KAAK,EAAE,EAAE;SACV;KACF;IACD;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,yBAAyB,EAAE;QAC9D,WAAW,EAAE;YACX,EAAE,EAAE,kBAAkB;YACtB,EAAE,EAAE,kBAAkB;SACvB;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,IAAI;SACZ;KACF;IACD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,sBAAsB,EAAE;QAC9D,WAAW,EAAE;YACX,EAAE,EAAE,yBAAyB;YAC7B,EAAE,EAAE,4BAA4B;SACjC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,CAAC;SACT;KACF;IACD;QACE,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE;QAC5C,WAAW,EAAE;YACX,EAAE,EAAE,0BAA0B;YAC9B,EAAE,EAAE,6BAA6B;SAClC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,EAAE;SACV;KACF;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,oBAAoB,EAAE;QACrD,WAAW,EAAE;YACX,EAAE,EAAE,iBAAiB;YACrB,EAAE,EAAE,oBAAoB;SACzB;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,EAAE;SACV;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,eAAe,EAAE,EAAE;IACnB,UAAU,EAAE,EAAE;IACd,gBAAgB,EAAE,EAAE;IACpB,UAAU,EAAE,CAAC;IACb,WAAW,EAAE;QACX,CAAC,EAAE,EAAE;QACL,EAAE,EAAE,GAAG;QACP,GAAG,EAAE,GAAG;KACT;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAK9B;QAJiB;;;;;WAA0D;QAC1D;;;;;WAA2D;QAC3D;;;;;WAAmC;QAGlD,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,KAA2C;QACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,WAA4C;QAC9D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,SAAkB,EAAE,UAAoB;QAC5D,IAAI,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC;QAE/C,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;QACzC,CAAC;QAED,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC;QAC/C,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,WAAW,CACT,QAAwB,EACxB,cAA8B,EAC9B,WAAwB;QAExB,MAAM,YAAY,GAAY,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,qBAAqB;QACrB,IACE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;YACtC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,EACxD,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC9C,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC7D,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClC,OAAO,EAAE,EAAE,WAAW,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,YAAY,EAAE,KAAK,KAAK,CAAC;QAC9E,CAAC,CAAC,CAAC,MAAM,CAAC;QAEV,IAAI,YAAY,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,EAAE,CAAC;YACnF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC/C,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,IACE,cAAc,CAAC,SAAS,KAAK,GAAG;YAChC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,EACzD,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC/C,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,IACE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;YACpC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,iBAAiB,CAAC,EAC3D,CAAC;YACD,2EAA2E;YAC3E,wDAAwD;YACxD,IAAI,QAAQ,CAAC,gBAAgB,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBACjD,IAAI,KAAK,EAAE,CAAC;oBACV,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IACE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,IAAI,EAAE;YACtC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,EAC5D,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAClD,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,IACE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,IAAI,EAAE;YACtC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,EACnD,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACzC,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,WAAwB;QACxC,MAAM,kBAAkB,GAAkB,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,gCAAgC;QAChC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,MAAM,CACpE,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EACzD,CAAC,CACF,CAAC;QAEF,uBAAuB;QACvB,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACrD,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBACtD,IACE,YAAY,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK;oBAC1C,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC,EAC9D,CAAC;oBACD,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACrD,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBAClD,IACE,WAAW,CAAC,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK;oBACrD,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC,EAC9D,CAAC;oBACD,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACrD,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAChD,IACE,WAAW,CAAC,MAAM,CAAC,OAAO,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK;oBACxD,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC,EAC9D,CAAC;oBACD,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,MAAM,CAC1E,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,EAC3F,CAAC,CACF,CAAC;QAEF,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACrD,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACnD,IACE,kBAAkB,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK;oBAChD,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC,EAC9D,CAAC;oBACD,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,WAAwB;QACnC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC;QAErD,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;YACzB,uBAAuB;YACvB,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3D,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;YAChC,kBAAkB;YAClB,WAAW,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;YAChC,WAAW,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAE9F,sBAAsB;YACtB,MAAM,YAAY,GAAG;gBACnB,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE;gBACnC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE;aACtC,CAAC;YAEF,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,YAAY,EAAE,CAAC;gBAC7C,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;oBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACvC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC;wBAC/D,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBAC9D,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,eAAe;YACf,WAAW,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;QACjC,CAAC;QAED,WAAW,CAAC,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;QAC1C,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEnC,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,EAAU;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,EAAU;QACvB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO,IAAI,mBAAmB,EAAE,CAAC;AACnC,CAAC"}
|