@speakableio/core 0.1.67 → 0.1.69

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.
@@ -0,0 +1,42 @@
1
+ import { FieldValue } from 'firebase/firestore';
2
+
3
+ interface GradingStandard {
4
+ type: 'actfl' | 'wida' | 'custom';
5
+ customStandardId?: string | undefined;
6
+ dateMade: FieldValue;
7
+ courseId?: string;
8
+ assignmentId?: string;
9
+ teacherId?: string;
10
+ cardId: string;
11
+ setId: string;
12
+ level: string;
13
+ justification: string;
14
+ prompt: string;
15
+ transcript: string;
16
+ audioUrl?: string;
17
+ responseType: 'spoken' | 'written';
18
+ language: string;
19
+ }
20
+
21
+ declare const logGradingStandardLog: (data: {
22
+ type: GradingStandard["type"];
23
+ level?: GradingStandard["level"];
24
+ courseId?: GradingStandard["courseId"];
25
+ }) => void;
26
+
27
+ declare const logOpenAssignment: (data?: {}) => void;
28
+ declare const logOpenActivityPreview: (data?: {}) => void;
29
+ declare const logSubmitAssignment: (data?: {}) => void;
30
+ declare const logCreateAssignment: (data?: {}) => void;
31
+ declare const logStartAssignment: (data?: {}) => void;
32
+
33
+ declare const logRepeatSuccess: (data?: {
34
+ courseId?: string;
35
+ [key: string]: any;
36
+ }) => void;
37
+ declare const logRepeatFail: (data?: {
38
+ courseId?: string;
39
+ [key: string]: any;
40
+ }) => void;
41
+
42
+ export { logCreateAssignment, logGradingStandardLog, logOpenActivityPreview, logOpenAssignment, logRepeatFail, logRepeatSuccess, logStartAssignment, logSubmitAssignment };
@@ -0,0 +1,42 @@
1
+ import { FieldValue } from 'firebase/firestore';
2
+
3
+ interface GradingStandard {
4
+ type: 'actfl' | 'wida' | 'custom';
5
+ customStandardId?: string | undefined;
6
+ dateMade: FieldValue;
7
+ courseId?: string;
8
+ assignmentId?: string;
9
+ teacherId?: string;
10
+ cardId: string;
11
+ setId: string;
12
+ level: string;
13
+ justification: string;
14
+ prompt: string;
15
+ transcript: string;
16
+ audioUrl?: string;
17
+ responseType: 'spoken' | 'written';
18
+ language: string;
19
+ }
20
+
21
+ declare const logGradingStandardLog: (data: {
22
+ type: GradingStandard["type"];
23
+ level?: GradingStandard["level"];
24
+ courseId?: GradingStandard["courseId"];
25
+ }) => void;
26
+
27
+ declare const logOpenAssignment: (data?: {}) => void;
28
+ declare const logOpenActivityPreview: (data?: {}) => void;
29
+ declare const logSubmitAssignment: (data?: {}) => void;
30
+ declare const logCreateAssignment: (data?: {}) => void;
31
+ declare const logStartAssignment: (data?: {}) => void;
32
+
33
+ declare const logRepeatSuccess: (data?: {
34
+ courseId?: string;
35
+ [key: string]: any;
36
+ }) => void;
37
+ declare const logRepeatFail: (data?: {
38
+ courseId?: string;
39
+ [key: string]: any;
40
+ }) => void;
41
+
42
+ export { logCreateAssignment, logGradingStandardLog, logOpenActivityPreview, logOpenAssignment, logRepeatFail, logRepeatSuccess, logStartAssignment, logSubmitAssignment };
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/entry-points/analytics.ts
21
+ var analytics_exports = {};
22
+ __export(analytics_exports, {
23
+ logCreateAssignment: () => logCreateAssignment,
24
+ logGradingStandardLog: () => logGradingStandardLog,
25
+ logOpenActivityPreview: () => logOpenActivityPreview,
26
+ logOpenAssignment: () => logOpenAssignment,
27
+ logRepeatFail: () => logRepeatFail,
28
+ logRepeatSuccess: () => logRepeatSuccess,
29
+ logStartAssignment: () => logStartAssignment,
30
+ logSubmitAssignment: () => logSubmitAssignment
31
+ });
32
+ module.exports = __toCommonJS(analytics_exports);
33
+
34
+ // src/lib/firebase/api.ts
35
+ var FirebaseAPI = class _FirebaseAPI {
36
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
37
+ constructor() {
38
+ this.config = null;
39
+ }
40
+ static getInstance() {
41
+ if (!_FirebaseAPI.instance) {
42
+ _FirebaseAPI.instance = new _FirebaseAPI();
43
+ }
44
+ return _FirebaseAPI.instance;
45
+ }
46
+ initialize(config) {
47
+ this.config = config;
48
+ }
49
+ get db() {
50
+ if (!this.config) throw new Error("Firebase API not initialized");
51
+ return this.config.db;
52
+ }
53
+ get helpers() {
54
+ if (!this.config) throw new Error("Firebase API not initialized");
55
+ return this.config.helpers;
56
+ }
57
+ get httpsCallable() {
58
+ var _a;
59
+ return (_a = this.config) == null ? void 0 : _a.httpsCallable;
60
+ }
61
+ logEvent(name, data) {
62
+ var _a;
63
+ (_a = this.config) == null ? void 0 : _a.logEvent(name, data);
64
+ }
65
+ accessQueryConstraints() {
66
+ const { query, orderBy, limit, startAt, startAfter, endAt, endBefore, where, increment } = this.helpers;
67
+ return {
68
+ query,
69
+ orderBy,
70
+ limit,
71
+ startAt,
72
+ startAfter,
73
+ endAt,
74
+ endBefore,
75
+ where,
76
+ increment
77
+ };
78
+ }
79
+ accessHelpers() {
80
+ const { doc, collection, writeBatch, serverTimestamp, setDoc } = this.helpers;
81
+ return {
82
+ doc: (path) => doc(this.db, path),
83
+ collection: (path) => collection(this.db, path),
84
+ writeBatch: () => writeBatch(this.db),
85
+ serverTimestamp,
86
+ setDoc
87
+ };
88
+ }
89
+ async getDoc(path) {
90
+ const { getDoc, doc } = this.helpers;
91
+ const docRef = doc(this.db, path);
92
+ const docSnap = await getDoc(docRef);
93
+ const data = docSnap.exists() ? {
94
+ ...docSnap.data(),
95
+ id: docSnap.id
96
+ } : null;
97
+ return {
98
+ id: docSnap.id,
99
+ data
100
+ };
101
+ }
102
+ async getDocs(path, ...queryConstraints) {
103
+ const { getDocs, query, collection } = this.helpers;
104
+ const collectionRef = collection(this.db, path);
105
+ const q = queryConstraints.length > 0 ? query(collectionRef, ...queryConstraints) : collectionRef;
106
+ const querySnapshot = await getDocs(q);
107
+ const data = querySnapshot.docs.map((doc) => ({
108
+ data: doc.data(),
109
+ id: doc.id
110
+ }));
111
+ return {
112
+ data,
113
+ querySnapshot,
114
+ empty: querySnapshot.empty
115
+ };
116
+ }
117
+ async addDoc(path, data) {
118
+ const { addDoc, collection } = this.helpers;
119
+ const collectionRef = collection(this.db, path);
120
+ const docRef = await addDoc(collectionRef, data);
121
+ return {
122
+ ...data,
123
+ id: docRef.id
124
+ };
125
+ }
126
+ async setDoc(path, data, options = {}) {
127
+ const { setDoc, doc } = this.helpers;
128
+ const docRef = doc(this.db, path);
129
+ await setDoc(docRef, data, options);
130
+ }
131
+ async updateDoc(path, data) {
132
+ const { updateDoc, doc } = this.helpers;
133
+ const docRef = doc(this.db, path);
134
+ await updateDoc(docRef, data);
135
+ }
136
+ async deleteDoc(path) {
137
+ const { deleteDoc, doc } = this.helpers;
138
+ const docRef = doc(this.db, path);
139
+ await deleteDoc(docRef);
140
+ }
141
+ async runTransaction(updateFunction) {
142
+ const { runTransaction } = this.helpers;
143
+ return runTransaction(this.db, updateFunction);
144
+ }
145
+ async runBatch(operations) {
146
+ const { writeBatch } = this.helpers;
147
+ const batch = writeBatch(this.db);
148
+ await Promise.all(operations.map((op) => op()));
149
+ await batch.commit();
150
+ }
151
+ writeBatch() {
152
+ const { writeBatch } = this.helpers;
153
+ const batch = writeBatch(this.db);
154
+ return batch;
155
+ }
156
+ };
157
+ var api = FirebaseAPI.getInstance();
158
+
159
+ // src/lib/firebase/firebase-analytics/grading-standard.ts
160
+ var logGradingStandardLog = (data) => {
161
+ var _a, _b, _c;
162
+ if (data.courseId && data.type && data.level) {
163
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
164
+ eventType: data.type || "custom",
165
+ level: data.level,
166
+ courseId: data.courseId
167
+ });
168
+ }
169
+ api.logEvent("logGradingStandard", data);
170
+ };
171
+
172
+ // src/constants/analytics.constants.ts
173
+ var ANALYTICS_EVENT_TYPES = {
174
+ VOICE_SUCCESS: "voice_success",
175
+ VOICE_FAIL: "voice_fail",
176
+ RESPOND_CARD_SUCCESS: "respond_card_success",
177
+ RESPOND_CARD_FAIL: "respond_card_fail",
178
+ RESPOND_WRITE_CARD_SUCCESS: "respond_write_card_success",
179
+ RESPOND_WRITE_CARD_FAIL: "respond_write_card_fail",
180
+ RESPOND_FREE_PLAN: "respond_free_plan",
181
+ RESPOND_WRITE_FREE_PLAN: "respond_write_free_plan",
182
+ SUBMISSION: "assignment_submitted",
183
+ ASSIGNMENT_STARTED: "assignment_started",
184
+ CREATE_ASSIGNMENT: "create_assignment",
185
+ MC_SUCCESS: "multiple_choice_success",
186
+ MC_FAIL: "multiple_choice_fail",
187
+ ACTFL_LEVEL: "actfl_level",
188
+ WIDA_LEVEL: "wida_level"
189
+ };
190
+
191
+ // src/lib/firebase/firebase-analytics/assignment.ts
192
+ var logOpenAssignment = (data = {}) => {
193
+ api.logEvent("open_assignment", data);
194
+ };
195
+ var logOpenActivityPreview = (data = {}) => {
196
+ api.logEvent("open_activity_preview", data);
197
+ };
198
+ var logSubmitAssignment = (data = {}) => {
199
+ var _a, _b, _c;
200
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
201
+ eventType: ANALYTICS_EVENT_TYPES.SUBMISSION,
202
+ ...data
203
+ });
204
+ api.logEvent(ANALYTICS_EVENT_TYPES.SUBMISSION, data);
205
+ };
206
+ var logCreateAssignment = (data = {}) => {
207
+ var _a, _b, _c;
208
+ if (data.courseId) {
209
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
210
+ eventType: ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT,
211
+ ...data
212
+ });
213
+ }
214
+ api.logEvent(ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT, data);
215
+ };
216
+ var logStartAssignment = (data = {}) => {
217
+ var _a, _b, _c;
218
+ if (data.courseId) {
219
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
220
+ eventType: ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED,
221
+ ...data
222
+ });
223
+ }
224
+ api.logEvent(ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED, data);
225
+ };
226
+
227
+ // src/lib/firebase/firebase-analytics/page-analytics.ts
228
+ var logRepeatSuccess = (data = {}) => {
229
+ var _a, _b, _c;
230
+ if (data.courseId) {
231
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
232
+ eventType: ANALYTICS_EVENT_TYPES.VOICE_SUCCESS,
233
+ ...data,
234
+ courseId: data.courseId
235
+ });
236
+ }
237
+ api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_SUCCESS, data);
238
+ };
239
+ var logRepeatFail = (data = {}) => {
240
+ var _a, _b, _c;
241
+ if (data.courseId) {
242
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
243
+ eventType: ANALYTICS_EVENT_TYPES.VOICE_FAIL,
244
+ ...data,
245
+ courseId: data.courseId
246
+ });
247
+ }
248
+ api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_FAIL, data);
249
+ };
250
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entry-points/analytics.ts","../src/lib/firebase/api.ts","../src/lib/firebase/firebase-analytics/grading-standard.ts","../src/constants/analytics.constants.ts","../src/lib/firebase/firebase-analytics/assignment.ts","../src/lib/firebase/firebase-analytics/page-analytics.ts"],"sourcesContent":["export * from '../lib/firebase/firebase-analytics'\n","import { type CallableFunction, type FirestoreHelpers } from '@core/types/firebase.types'\nimport {\n type SetOptions,\n type DocumentData,\n type QueryConstraint,\n type WithFieldValue,\n type Firestore,\n} from 'firebase/firestore'\n\ninterface FirebaseConfig {\n db: Firestore\n helpers: FirestoreHelpers\n httpsCallable: (name: string) => CallableFunction\n logEvent: (name: string, data: any) => void\n}\n\ntype FirebasePath = string\n\nexport class FirebaseAPI {\n private static instance: FirebaseAPI\n private config: FirebaseConfig | null = null\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private constructor() {\n // Private constructor for singleton pattern\n }\n\n static getInstance(): FirebaseAPI {\n if (!FirebaseAPI.instance) {\n FirebaseAPI.instance = new FirebaseAPI()\n }\n\n return FirebaseAPI.instance\n }\n\n initialize(config: FirebaseConfig) {\n this.config = config\n }\n\n get db() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.db\n }\n\n get helpers() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.helpers\n }\n\n get httpsCallable() {\n return this.config?.httpsCallable\n }\n\n logEvent(name: string, data: any) {\n this.config?.logEvent(name, data)\n }\n\n accessQueryConstraints() {\n const { query, orderBy, limit, startAt, startAfter, endAt, endBefore, where, increment } =\n this.helpers\n\n return {\n query,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n }\n }\n\n accessHelpers() {\n const { doc, collection, writeBatch, serverTimestamp, setDoc } = this.helpers\n\n return {\n doc: (path: FirebasePath) => doc(this.db, path),\n collection: (path: FirebasePath) => collection(this.db, path),\n writeBatch: () => writeBatch(this.db),\n serverTimestamp: serverTimestamp,\n setDoc: setDoc,\n }\n }\n\n async getDoc<T>(path: FirebasePath) {\n const { getDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n const docSnap = await getDoc(docRef)\n\n const data = docSnap.exists()\n ? ({\n ...docSnap.data(),\n id: docSnap.id,\n } as T)\n : null\n\n return {\n id: docSnap.id,\n data,\n }\n }\n\n async getDocs<T>(path: FirebasePath, ...queryConstraints: QueryConstraint[]) {\n const { getDocs, query, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const q =\n queryConstraints.length > 0 ? query(collectionRef, ...queryConstraints) : collectionRef\n\n const querySnapshot = await getDocs(q)\n\n const data = querySnapshot.docs.map(doc => ({\n data: doc.data() as T,\n id: doc.id,\n }))\n\n return {\n data: data as unknown as (T & {\n id: string\n })[],\n querySnapshot,\n empty: querySnapshot.empty,\n }\n }\n\n async addDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n ): Promise<{ id: string } & T> {\n const { addDoc, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const docRef = await addDoc(collectionRef, data)\n\n return {\n ...data,\n id: docRef.id,\n }\n }\n\n async setDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n options: SetOptions = {},\n ): Promise<void> {\n const { setDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await setDoc(docRef, data, options)\n }\n\n async updateDoc(path: FirebasePath, data: any): Promise<void> {\n const { updateDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n\n await updateDoc(docRef, data)\n }\n\n async deleteDoc(path: FirebasePath): Promise<void> {\n const { deleteDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await deleteDoc(docRef)\n }\n\n async runTransaction<T>(updateFunction: (transaction: any) => Promise<T>): Promise<T> {\n const { runTransaction } = this.helpers\n\n return runTransaction(this.db, updateFunction)\n }\n\n async runBatch(operations: (() => Promise<void>)[]): Promise<void> {\n const { writeBatch } = this.helpers\n const batch = writeBatch(this.db)\n\n await Promise.all(operations.map(op => op()))\n await batch.commit()\n }\n\n writeBatch() {\n const { writeBatch } = this.helpers\n\n const batch = writeBatch(this.db)\n\n return batch\n }\n}\n\nexport const api = FirebaseAPI.getInstance()\n","import { type GradingStandard } from '@core/services/add-grading-standard'\n\nimport { api } from '../api'\n\nexport const logGradingStandardLog = (data: {\n type: GradingStandard['type']\n level?: GradingStandard['level']\n courseId?: GradingStandard['courseId']\n}) => {\n if (data.courseId && data.type && data.level) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: data.type || 'custom',\n level: data.level,\n courseId: data.courseId,\n })\n }\n api.logEvent('logGradingStandard', data)\n}\n","// Event constants\nexport const ANALYTICS_EVENT_TYPES = {\n VOICE_SUCCESS: 'voice_success',\n VOICE_FAIL: 'voice_fail',\n RESPOND_CARD_SUCCESS: 'respond_card_success',\n RESPOND_CARD_FAIL: 'respond_card_fail',\n RESPOND_WRITE_CARD_SUCCESS: 'respond_write_card_success',\n RESPOND_WRITE_CARD_FAIL: 'respond_write_card_fail',\n RESPOND_FREE_PLAN: 'respond_free_plan',\n RESPOND_WRITE_FREE_PLAN: 'respond_write_free_plan',\n SUBMISSION: 'assignment_submitted',\n ASSIGNMENT_STARTED: 'assignment_started',\n CREATE_ASSIGNMENT: 'create_assignment',\n MC_SUCCESS: 'multiple_choice_success',\n MC_FAIL: 'multiple_choice_fail',\n ACTFL_LEVEL: 'actfl_level',\n WIDA_LEVEL: 'wida_level',\n} as const\n","import { ANALYTICS_EVENT_TYPES } from '@core/constants/analytics.constants'\n\nimport { api } from '../api'\n\nexport const logOpenAssignment = (data = {}) => {\n api.logEvent('open_assignment', data)\n}\n\nexport const logOpenActivityPreview = (data = {}) => {\n api.logEvent('open_activity_preview', data)\n}\n\nexport const logSubmitAssignment = (data = {}) => {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.SUBMISSION,\n ...data,\n })\n api.logEvent(ANALYTICS_EVENT_TYPES.SUBMISSION, data)\n}\n\nexport const logCreateAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT, data)\n}\n\nexport const logStartAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED, data)\n}\n","import { ANALYTICS_EVENT_TYPES } from '@core/constants/analytics.constants'\n\nimport { api } from '../api'\n\nexport const logRepeatSuccess = (\n data: {\n courseId?: string\n [key: string]: any\n } = {},\n) => {\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.VOICE_SUCCESS,\n ...data,\n courseId: data.courseId,\n })\n }\n\n api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_SUCCESS, data)\n}\n\nexport const logRepeatFail = (\n data: {\n courseId?: string\n [key: string]: any\n } = {},\n) => {\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.VOICE_FAIL,\n ...data,\n courseId: data.courseId,\n })\n }\n\n api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_FAIL, data)\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,227 @@
1
+ // src/lib/firebase/api.ts
2
+ var FirebaseAPI = class _FirebaseAPI {
3
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
4
+ constructor() {
5
+ this.config = null;
6
+ }
7
+ static getInstance() {
8
+ if (!_FirebaseAPI.instance) {
9
+ _FirebaseAPI.instance = new _FirebaseAPI();
10
+ }
11
+ return _FirebaseAPI.instance;
12
+ }
13
+ initialize(config) {
14
+ this.config = config;
15
+ }
16
+ get db() {
17
+ if (!this.config) throw new Error("Firebase API not initialized");
18
+ return this.config.db;
19
+ }
20
+ get helpers() {
21
+ if (!this.config) throw new Error("Firebase API not initialized");
22
+ return this.config.helpers;
23
+ }
24
+ get httpsCallable() {
25
+ var _a;
26
+ return (_a = this.config) == null ? void 0 : _a.httpsCallable;
27
+ }
28
+ logEvent(name, data) {
29
+ var _a;
30
+ (_a = this.config) == null ? void 0 : _a.logEvent(name, data);
31
+ }
32
+ accessQueryConstraints() {
33
+ const { query, orderBy, limit, startAt, startAfter, endAt, endBefore, where, increment } = this.helpers;
34
+ return {
35
+ query,
36
+ orderBy,
37
+ limit,
38
+ startAt,
39
+ startAfter,
40
+ endAt,
41
+ endBefore,
42
+ where,
43
+ increment
44
+ };
45
+ }
46
+ accessHelpers() {
47
+ const { doc, collection, writeBatch, serverTimestamp, setDoc } = this.helpers;
48
+ return {
49
+ doc: (path) => doc(this.db, path),
50
+ collection: (path) => collection(this.db, path),
51
+ writeBatch: () => writeBatch(this.db),
52
+ serverTimestamp,
53
+ setDoc
54
+ };
55
+ }
56
+ async getDoc(path) {
57
+ const { getDoc, doc } = this.helpers;
58
+ const docRef = doc(this.db, path);
59
+ const docSnap = await getDoc(docRef);
60
+ const data = docSnap.exists() ? {
61
+ ...docSnap.data(),
62
+ id: docSnap.id
63
+ } : null;
64
+ return {
65
+ id: docSnap.id,
66
+ data
67
+ };
68
+ }
69
+ async getDocs(path, ...queryConstraints) {
70
+ const { getDocs, query, collection } = this.helpers;
71
+ const collectionRef = collection(this.db, path);
72
+ const q = queryConstraints.length > 0 ? query(collectionRef, ...queryConstraints) : collectionRef;
73
+ const querySnapshot = await getDocs(q);
74
+ const data = querySnapshot.docs.map((doc) => ({
75
+ data: doc.data(),
76
+ id: doc.id
77
+ }));
78
+ return {
79
+ data,
80
+ querySnapshot,
81
+ empty: querySnapshot.empty
82
+ };
83
+ }
84
+ async addDoc(path, data) {
85
+ const { addDoc, collection } = this.helpers;
86
+ const collectionRef = collection(this.db, path);
87
+ const docRef = await addDoc(collectionRef, data);
88
+ return {
89
+ ...data,
90
+ id: docRef.id
91
+ };
92
+ }
93
+ async setDoc(path, data, options = {}) {
94
+ const { setDoc, doc } = this.helpers;
95
+ const docRef = doc(this.db, path);
96
+ await setDoc(docRef, data, options);
97
+ }
98
+ async updateDoc(path, data) {
99
+ const { updateDoc, doc } = this.helpers;
100
+ const docRef = doc(this.db, path);
101
+ await updateDoc(docRef, data);
102
+ }
103
+ async deleteDoc(path) {
104
+ const { deleteDoc, doc } = this.helpers;
105
+ const docRef = doc(this.db, path);
106
+ await deleteDoc(docRef);
107
+ }
108
+ async runTransaction(updateFunction) {
109
+ const { runTransaction } = this.helpers;
110
+ return runTransaction(this.db, updateFunction);
111
+ }
112
+ async runBatch(operations) {
113
+ const { writeBatch } = this.helpers;
114
+ const batch = writeBatch(this.db);
115
+ await Promise.all(operations.map((op) => op()));
116
+ await batch.commit();
117
+ }
118
+ writeBatch() {
119
+ const { writeBatch } = this.helpers;
120
+ const batch = writeBatch(this.db);
121
+ return batch;
122
+ }
123
+ };
124
+ var api = FirebaseAPI.getInstance();
125
+
126
+ // src/lib/firebase/firebase-analytics/grading-standard.ts
127
+ var logGradingStandardLog = (data) => {
128
+ var _a, _b, _c;
129
+ if (data.courseId && data.type && data.level) {
130
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
131
+ eventType: data.type || "custom",
132
+ level: data.level,
133
+ courseId: data.courseId
134
+ });
135
+ }
136
+ api.logEvent("logGradingStandard", data);
137
+ };
138
+
139
+ // src/constants/analytics.constants.ts
140
+ var ANALYTICS_EVENT_TYPES = {
141
+ VOICE_SUCCESS: "voice_success",
142
+ VOICE_FAIL: "voice_fail",
143
+ RESPOND_CARD_SUCCESS: "respond_card_success",
144
+ RESPOND_CARD_FAIL: "respond_card_fail",
145
+ RESPOND_WRITE_CARD_SUCCESS: "respond_write_card_success",
146
+ RESPOND_WRITE_CARD_FAIL: "respond_write_card_fail",
147
+ RESPOND_FREE_PLAN: "respond_free_plan",
148
+ RESPOND_WRITE_FREE_PLAN: "respond_write_free_plan",
149
+ SUBMISSION: "assignment_submitted",
150
+ ASSIGNMENT_STARTED: "assignment_started",
151
+ CREATE_ASSIGNMENT: "create_assignment",
152
+ MC_SUCCESS: "multiple_choice_success",
153
+ MC_FAIL: "multiple_choice_fail",
154
+ ACTFL_LEVEL: "actfl_level",
155
+ WIDA_LEVEL: "wida_level"
156
+ };
157
+
158
+ // src/lib/firebase/firebase-analytics/assignment.ts
159
+ var logOpenAssignment = (data = {}) => {
160
+ api.logEvent("open_assignment", data);
161
+ };
162
+ var logOpenActivityPreview = (data = {}) => {
163
+ api.logEvent("open_activity_preview", data);
164
+ };
165
+ var logSubmitAssignment = (data = {}) => {
166
+ var _a, _b, _c;
167
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
168
+ eventType: ANALYTICS_EVENT_TYPES.SUBMISSION,
169
+ ...data
170
+ });
171
+ api.logEvent(ANALYTICS_EVENT_TYPES.SUBMISSION, data);
172
+ };
173
+ var logCreateAssignment = (data = {}) => {
174
+ var _a, _b, _c;
175
+ if (data.courseId) {
176
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
177
+ eventType: ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT,
178
+ ...data
179
+ });
180
+ }
181
+ api.logEvent(ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT, data);
182
+ };
183
+ var logStartAssignment = (data = {}) => {
184
+ var _a, _b, _c;
185
+ if (data.courseId) {
186
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
187
+ eventType: ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED,
188
+ ...data
189
+ });
190
+ }
191
+ api.logEvent(ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED, data);
192
+ };
193
+
194
+ // src/lib/firebase/firebase-analytics/page-analytics.ts
195
+ var logRepeatSuccess = (data = {}) => {
196
+ var _a, _b, _c;
197
+ if (data.courseId) {
198
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
199
+ eventType: ANALYTICS_EVENT_TYPES.VOICE_SUCCESS,
200
+ ...data,
201
+ courseId: data.courseId
202
+ });
203
+ }
204
+ api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_SUCCESS, data);
205
+ };
206
+ var logRepeatFail = (data = {}) => {
207
+ var _a, _b, _c;
208
+ if (data.courseId) {
209
+ (_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "handleCouresAnalyticsEvent")) == null ? void 0 : _c({
210
+ eventType: ANALYTICS_EVENT_TYPES.VOICE_FAIL,
211
+ ...data,
212
+ courseId: data.courseId
213
+ });
214
+ }
215
+ api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_FAIL, data);
216
+ };
217
+ export {
218
+ logCreateAssignment,
219
+ logGradingStandardLog,
220
+ logOpenActivityPreview,
221
+ logOpenAssignment,
222
+ logRepeatFail,
223
+ logRepeatSuccess,
224
+ logStartAssignment,
225
+ logSubmitAssignment
226
+ };
227
+ //# sourceMappingURL=analytics.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/firebase/api.ts","../src/lib/firebase/firebase-analytics/grading-standard.ts","../src/constants/analytics.constants.ts","../src/lib/firebase/firebase-analytics/assignment.ts","../src/lib/firebase/firebase-analytics/page-analytics.ts"],"sourcesContent":["import { type CallableFunction, type FirestoreHelpers } from '@core/types/firebase.types'\nimport {\n type SetOptions,\n type DocumentData,\n type QueryConstraint,\n type WithFieldValue,\n type Firestore,\n} from 'firebase/firestore'\n\ninterface FirebaseConfig {\n db: Firestore\n helpers: FirestoreHelpers\n httpsCallable: (name: string) => CallableFunction\n logEvent: (name: string, data: any) => void\n}\n\ntype FirebasePath = string\n\nexport class FirebaseAPI {\n private static instance: FirebaseAPI\n private config: FirebaseConfig | null = null\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private constructor() {\n // Private constructor for singleton pattern\n }\n\n static getInstance(): FirebaseAPI {\n if (!FirebaseAPI.instance) {\n FirebaseAPI.instance = new FirebaseAPI()\n }\n\n return FirebaseAPI.instance\n }\n\n initialize(config: FirebaseConfig) {\n this.config = config\n }\n\n get db() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.db\n }\n\n get helpers() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.helpers\n }\n\n get httpsCallable() {\n return this.config?.httpsCallable\n }\n\n logEvent(name: string, data: any) {\n this.config?.logEvent(name, data)\n }\n\n accessQueryConstraints() {\n const { query, orderBy, limit, startAt, startAfter, endAt, endBefore, where, increment } =\n this.helpers\n\n return {\n query,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n }\n }\n\n accessHelpers() {\n const { doc, collection, writeBatch, serverTimestamp, setDoc } = this.helpers\n\n return {\n doc: (path: FirebasePath) => doc(this.db, path),\n collection: (path: FirebasePath) => collection(this.db, path),\n writeBatch: () => writeBatch(this.db),\n serverTimestamp: serverTimestamp,\n setDoc: setDoc,\n }\n }\n\n async getDoc<T>(path: FirebasePath) {\n const { getDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n const docSnap = await getDoc(docRef)\n\n const data = docSnap.exists()\n ? ({\n ...docSnap.data(),\n id: docSnap.id,\n } as T)\n : null\n\n return {\n id: docSnap.id,\n data,\n }\n }\n\n async getDocs<T>(path: FirebasePath, ...queryConstraints: QueryConstraint[]) {\n const { getDocs, query, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const q =\n queryConstraints.length > 0 ? query(collectionRef, ...queryConstraints) : collectionRef\n\n const querySnapshot = await getDocs(q)\n\n const data = querySnapshot.docs.map(doc => ({\n data: doc.data() as T,\n id: doc.id,\n }))\n\n return {\n data: data as unknown as (T & {\n id: string\n })[],\n querySnapshot,\n empty: querySnapshot.empty,\n }\n }\n\n async addDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n ): Promise<{ id: string } & T> {\n const { addDoc, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const docRef = await addDoc(collectionRef, data)\n\n return {\n ...data,\n id: docRef.id,\n }\n }\n\n async setDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n options: SetOptions = {},\n ): Promise<void> {\n const { setDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await setDoc(docRef, data, options)\n }\n\n async updateDoc(path: FirebasePath, data: any): Promise<void> {\n const { updateDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n\n await updateDoc(docRef, data)\n }\n\n async deleteDoc(path: FirebasePath): Promise<void> {\n const { deleteDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await deleteDoc(docRef)\n }\n\n async runTransaction<T>(updateFunction: (transaction: any) => Promise<T>): Promise<T> {\n const { runTransaction } = this.helpers\n\n return runTransaction(this.db, updateFunction)\n }\n\n async runBatch(operations: (() => Promise<void>)[]): Promise<void> {\n const { writeBatch } = this.helpers\n const batch = writeBatch(this.db)\n\n await Promise.all(operations.map(op => op()))\n await batch.commit()\n }\n\n writeBatch() {\n const { writeBatch } = this.helpers\n\n const batch = writeBatch(this.db)\n\n return batch\n }\n}\n\nexport const api = FirebaseAPI.getInstance()\n","import { type GradingStandard } from '@core/services/add-grading-standard'\n\nimport { api } from '../api'\n\nexport const logGradingStandardLog = (data: {\n type: GradingStandard['type']\n level?: GradingStandard['level']\n courseId?: GradingStandard['courseId']\n}) => {\n if (data.courseId && data.type && data.level) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: data.type || 'custom',\n level: data.level,\n courseId: data.courseId,\n })\n }\n api.logEvent('logGradingStandard', data)\n}\n","// Event constants\nexport const ANALYTICS_EVENT_TYPES = {\n VOICE_SUCCESS: 'voice_success',\n VOICE_FAIL: 'voice_fail',\n RESPOND_CARD_SUCCESS: 'respond_card_success',\n RESPOND_CARD_FAIL: 'respond_card_fail',\n RESPOND_WRITE_CARD_SUCCESS: 'respond_write_card_success',\n RESPOND_WRITE_CARD_FAIL: 'respond_write_card_fail',\n RESPOND_FREE_PLAN: 'respond_free_plan',\n RESPOND_WRITE_FREE_PLAN: 'respond_write_free_plan',\n SUBMISSION: 'assignment_submitted',\n ASSIGNMENT_STARTED: 'assignment_started',\n CREATE_ASSIGNMENT: 'create_assignment',\n MC_SUCCESS: 'multiple_choice_success',\n MC_FAIL: 'multiple_choice_fail',\n ACTFL_LEVEL: 'actfl_level',\n WIDA_LEVEL: 'wida_level',\n} as const\n","import { ANALYTICS_EVENT_TYPES } from '@core/constants/analytics.constants'\n\nimport { api } from '../api'\n\nexport const logOpenAssignment = (data = {}) => {\n api.logEvent('open_assignment', data)\n}\n\nexport const logOpenActivityPreview = (data = {}) => {\n api.logEvent('open_activity_preview', data)\n}\n\nexport const logSubmitAssignment = (data = {}) => {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.SUBMISSION,\n ...data,\n })\n api.logEvent(ANALYTICS_EVENT_TYPES.SUBMISSION, data)\n}\n\nexport const logCreateAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT, data)\n}\n\nexport const logStartAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED, data)\n}\n","import { ANALYTICS_EVENT_TYPES } from '@core/constants/analytics.constants'\n\nimport { api } from '../api'\n\nexport const logRepeatSuccess = (\n data: {\n courseId?: string\n [key: string]: any\n } = {},\n) => {\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.VOICE_SUCCESS,\n ...data,\n courseId: data.courseId,\n })\n }\n\n api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_SUCCESS, data)\n}\n\nexport const logRepeatFail = (\n data: {\n courseId?: string\n [key: string]: any\n } = {},\n) => {\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.VOICE_FAIL,\n ...data,\n courseId: data.courseId,\n })\n }\n\n api.logEvent(ANALYTICS_EVENT_TYPES.VOICE_FAIL, data)\n}\n"],"mappings":";AAkBO,IAAM,cAAN,MAAM,aAAY;AAAA;AAAA,EAKf,cAAc;AAHtB,SAAQ,SAAgC;AAAA,EAKxC;AAAA,EAEA,OAAO,cAA2B;AAChC,QAAI,CAAC,aAAY,UAAU;AACzB,mBAAY,WAAW,IAAI,aAAY;AAAA,IACzC;AAEA,WAAO,aAAY;AAAA,EACrB;AAAA,EAEA,WAAW,QAAwB;AACjC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,KAAK;AACP,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,8BAA8B;AAEhE,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,UAAU;AACZ,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,8BAA8B;AAEhE,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,gBAAgB;AAnDtB;AAoDI,YAAO,UAAK,WAAL,mBAAa;AAAA,EACtB;AAAA,EAEA,SAAS,MAAc,MAAW;AAvDpC;AAwDI,eAAK,WAAL,mBAAa,SAAS,MAAM;AAAA,EAC9B;AAAA,EAEA,yBAAyB;AACvB,UAAM,EAAE,OAAO,SAAS,OAAO,SAAS,YAAY,OAAO,WAAW,OAAO,UAAU,IACrF,KAAK;AAEP,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBAAgB;AACd,UAAM,EAAE,KAAK,YAAY,YAAY,iBAAiB,OAAO,IAAI,KAAK;AAEtE,WAAO;AAAA,MACL,KAAK,CAAC,SAAuB,IAAI,KAAK,IAAI,IAAI;AAAA,MAC9C,YAAY,CAAC,SAAuB,WAAW,KAAK,IAAI,IAAI;AAAA,MAC5D,YAAY,MAAM,WAAW,KAAK,EAAE;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAU,MAAoB;AAClC,UAAM,EAAE,QAAQ,IAAI,IAAI,KAAK;AAE7B,UAAM,SAAS,IAAI,KAAK,IAAI,IAAI;AAChC,UAAM,UAAU,MAAM,OAAO,MAAM;AAEnC,UAAM,OAAO,QAAQ,OAAO,IACvB;AAAA,MACC,GAAG,QAAQ,KAAK;AAAA,MAChB,IAAI,QAAQ;AAAA,IACd,IACA;AAEJ,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,QAAW,SAAuB,kBAAqC;AAC3E,UAAM,EAAE,SAAS,OAAO,WAAW,IAAI,KAAK;AAC5C,UAAM,gBAAgB,WAAW,KAAK,IAAI,IAAI;AAC9C,UAAM,IACJ,iBAAiB,SAAS,IAAI,MAAM,eAAe,GAAG,gBAAgB,IAAI;AAE5E,UAAM,gBAAgB,MAAM,QAAQ,CAAC;AAErC,UAAM,OAAO,cAAc,KAAK,IAAI,UAAQ;AAAA,MAC1C,MAAM,IAAI,KAAK;AAAA,MACf,IAAI,IAAI;AAAA,IACV,EAAE;AAEF,WAAO;AAAA,MACL;AAAA,MAGA;AAAA,MACA,OAAO,cAAc;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,MACA,MAC6B;AAC7B,UAAM,EAAE,QAAQ,WAAW,IAAI,KAAK;AACpC,UAAM,gBAAgB,WAAW,KAAK,IAAI,IAAI;AAC9C,UAAM,SAAS,MAAM,OAAO,eAAe,IAAI;AAE/C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,IAAI,OAAO;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,MACA,MACA,UAAsB,CAAC,GACR;AACf,UAAM,EAAE,QAAQ,IAAI,IAAI,KAAK;AAC7B,UAAM,SAAS,IAAI,KAAK,IAAI,IAAI;AAEhC,UAAM,OAAO,QAAQ,MAAM,OAAO;AAAA,EACpC;AAAA,EAEA,MAAM,UAAU,MAAoB,MAA0B;AAC5D,UAAM,EAAE,WAAW,IAAI,IAAI,KAAK;AAEhC,UAAM,SAAS,IAAI,KAAK,IAAI,IAAI;AAEhC,UAAM,UAAU,QAAQ,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,UAAU,MAAmC;AACjD,UAAM,EAAE,WAAW,IAAI,IAAI,KAAK;AAChC,UAAM,SAAS,IAAI,KAAK,IAAI,IAAI;AAEhC,UAAM,UAAU,MAAM;AAAA,EACxB;AAAA,EAEA,MAAM,eAAkB,gBAA8D;AACpF,UAAM,EAAE,eAAe,IAAI,KAAK;AAEhC,WAAO,eAAe,KAAK,IAAI,cAAc;AAAA,EAC/C;AAAA,EAEA,MAAM,SAAS,YAAoD;AACjE,UAAM,EAAE,WAAW,IAAI,KAAK;AAC5B,UAAM,QAAQ,WAAW,KAAK,EAAE;AAEhC,UAAM,QAAQ,IAAI,WAAW,IAAI,QAAM,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,OAAO;AAAA,EACrB;AAAA,EAEA,aAAa;AACX,UAAM,EAAE,WAAW,IAAI,KAAK;AAE5B,UAAM,QAAQ,WAAW,KAAK,EAAE;AAEhC,WAAO;AAAA,EACT;AACF;AAEO,IAAM,MAAM,YAAY,YAAY;;;AC5LpC,IAAM,wBAAwB,CAAC,SAIhC;AARN;AASE,MAAI,KAAK,YAAY,KAAK,QAAQ,KAAK,OAAO;AAC5C,2BAAI,kBAAJ,4BAAoB,kCAApB,mBAAoD;AAAA,MAClD,WAAW,KAAK,QAAQ;AAAA,MACxB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AACA,MAAI,SAAS,sBAAsB,IAAI;AACzC;;;AChBO,IAAM,wBAAwB;AAAA,EACnC,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,YAAY;AAAA,EACZ,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AACd;;;ACbO,IAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM;AAC9C,MAAI,SAAS,mBAAmB,IAAI;AACtC;AAEO,IAAM,yBAAyB,CAAC,OAAO,CAAC,MAAM;AACnD,MAAI,SAAS,yBAAyB,IAAI;AAC5C;AAEO,IAAM,sBAAsB,CAAC,OAAO,CAAC,MAAM;AAZlD;AAaE,yBAAI,kBAAJ,4BAAoB,kCAApB,mBAAoD;AAAA,IAClD,WAAW,sBAAsB;AAAA,IACjC,GAAG;AAAA,EACL;AACA,MAAI,SAAS,sBAAsB,YAAY,IAAI;AACrD;AAEO,IAAM,sBAAsB,CAAC,OAAO,CAAC,MAAM;AApBlD;AAsBE,MAAI,KAAK,UAAU;AACjB,2BAAI,kBAAJ,4BAAoB,kCAApB,mBAAoD;AAAA,MAClD,WAAW,sBAAsB;AAAA,MACjC,GAAG;AAAA,IACL;AAAA,EACF;AACA,MAAI,SAAS,sBAAsB,mBAAmB,IAAI;AAC5D;AAEO,IAAM,qBAAqB,CAAC,OAAO,CAAC,MAAM;AA/BjD;AAiCE,MAAI,KAAK,UAAU;AACjB,2BAAI,kBAAJ,4BAAoB,kCAApB,mBAAoD;AAAA,MAClD,WAAW,sBAAsB;AAAA,MACjC,GAAG;AAAA,IACL;AAAA,EACF;AACA,MAAI,SAAS,sBAAsB,oBAAoB,IAAI;AAC7D;;;ACpCO,IAAM,mBAAmB,CAC9B,OAGI,CAAC,MACF;AATL;AAUE,MAAI,KAAK,UAAU;AACjB,2BAAI,kBAAJ,4BAAoB,kCAApB,mBAAoD;AAAA,MAClD,WAAW,sBAAsB;AAAA,MACjC,GAAG;AAAA,MACH,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,SAAS,sBAAsB,eAAe,IAAI;AACxD;AAEO,IAAM,gBAAgB,CAC3B,OAGI,CAAC,MACF;AA1BL;AA2BE,MAAI,KAAK,UAAU;AACjB,2BAAI,kBAAJ,4BAAoB,kCAApB,mBAAoD;AAAA,MAClD,WAAW,sBAAsB;AAAA,MACjC,GAAG;AAAA,MACH,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,SAAS,sBAAsB,YAAY,IAAI;AACrD;","names":[]}