@studious-lms/server 1.2.44 → 1.2.46
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/.env.example +45 -0
- package/.env.test.example +37 -0
- package/README.md +34 -7
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +12110 -0
- package/coverage/coverage-final.json +44 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +221 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/server/index.html +116 -0
- package/coverage/server/src/exportType.ts.html +109 -0
- package/coverage/server/src/index.html +161 -0
- package/coverage/server/src/index.ts.html +1702 -0
- package/coverage/server/src/instrument.ts.html +130 -0
- package/coverage/server/src/lib/config/env.ts.html +448 -0
- package/coverage/server/src/lib/config/index.html +116 -0
- package/coverage/server/src/lib/fileUpload.ts.html +1138 -0
- package/coverage/server/src/lib/googleCloudStorage.ts.html +334 -0
- package/coverage/server/src/lib/index.html +206 -0
- package/coverage/server/src/lib/jsonConversion.ts.html +2323 -0
- package/coverage/server/src/lib/jsonStyles.ts.html +193 -0
- package/coverage/server/src/lib/notificationHandler.ts.html +193 -0
- package/coverage/server/src/lib/pusher.ts.html +121 -0
- package/coverage/server/src/lib/thumbnailGenerator.ts.html +592 -0
- package/coverage/server/src/middleware/auth.ts.html +646 -0
- package/coverage/server/src/middleware/index.html +146 -0
- package/coverage/server/src/middleware/logging.ts.html +244 -0
- package/coverage/server/src/middleware/security.ts.html +271 -0
- package/coverage/server/src/routers/_app.ts.html +232 -0
- package/coverage/server/src/routers/agenda.ts.html +319 -0
- package/coverage/server/src/routers/announcement.ts.html +3481 -0
- package/coverage/server/src/routers/assignment.ts.html +7633 -0
- package/coverage/server/src/routers/attendance.ts.html +1030 -0
- package/coverage/server/src/routers/auth.ts.html +1081 -0
- package/coverage/server/src/routers/class.ts.html +3535 -0
- package/coverage/server/src/routers/comment.ts.html +991 -0
- package/coverage/server/src/routers/conversation.ts.html +982 -0
- package/coverage/server/src/routers/event.ts.html +1609 -0
- package/coverage/server/src/routers/file.ts.html +1144 -0
- package/coverage/server/src/routers/folder.ts.html +2797 -0
- package/coverage/server/src/routers/index.html +386 -0
- package/coverage/server/src/routers/labChat.ts.html +3073 -0
- package/coverage/server/src/routers/marketing.ts.html +340 -0
- package/coverage/server/src/routers/message.ts.html +1912 -0
- package/coverage/server/src/routers/notifications.ts.html +364 -0
- package/coverage/server/src/routers/section.ts.html +1120 -0
- package/coverage/server/src/routers/user.ts.html +862 -0
- package/coverage/server/src/routers/worksheet.ts.html +1729 -0
- package/coverage/server/src/trpc.ts.html +397 -0
- package/coverage/server/src/types/index.html +116 -0
- package/coverage/server/src/types/trpc.ts.html +127 -0
- package/coverage/server/src/utils/aiUser.ts.html +280 -0
- package/coverage/server/src/utils/email.ts.html +121 -0
- package/coverage/server/src/utils/generateInviteCode.ts.html +106 -0
- package/coverage/server/src/utils/index.html +206 -0
- package/coverage/server/src/utils/inference.ts.html +709 -0
- package/coverage/server/src/utils/logger.ts.html +664 -0
- package/coverage/server/src/utils/prismaErrorHandler.ts.html +907 -0
- package/coverage/server/src/utils/prismaWrapper.ts.html +355 -0
- package/coverage/server/vitest.config.ts.html +196 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -52
- package/dist/index.js.map +1 -1
- package/dist/instrument.js +15 -8
- package/dist/instrument.js.map +1 -1
- package/dist/lib/config/env.d.ts +169 -0
- package/dist/lib/config/env.d.ts.map +1 -0
- package/dist/lib/config/env.js +115 -0
- package/dist/lib/config/env.js.map +1 -0
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +5 -4
- package/dist/lib/fileUpload.js.map +1 -1
- package/dist/lib/googleCloudStorage.d.ts.map +1 -1
- package/dist/lib/googleCloudStorage.js +7 -8
- package/dist/lib/googleCloudStorage.js.map +1 -1
- package/dist/lib/jsonConversion.d.ts.map +1 -1
- package/dist/lib/jsonConversion.js +14 -16
- package/dist/lib/jsonConversion.js.map +1 -1
- package/dist/lib/notificationHandler.d.ts +2 -2
- package/dist/lib/prisma.d.ts +2 -2
- package/dist/lib/prisma.d.ts.map +1 -1
- package/dist/lib/prisma.js +22 -3
- package/dist/lib/prisma.js.map +1 -1
- package/dist/lib/pusher.d.ts.map +1 -1
- package/dist/lib/pusher.js +8 -7
- package/dist/lib/pusher.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +6 -5
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/security.d.ts +5 -0
- package/dist/middleware/security.d.ts.map +1 -0
- package/dist/middleware/security.js +77 -0
- package/dist/middleware/security.js.map +1 -0
- package/dist/routers/_app.d.ts +304 -98
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +4 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/agenda.js +12 -9
- package/dist/routers/agenda.js.map +1 -1
- package/dist/routers/announcement.d.ts +8 -0
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +6 -4
- package/dist/routers/announcement.js.map +1 -1
- package/dist/routers/assignment.d.ts +7 -4
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +35 -18
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/attendance.d.ts +1 -0
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +4 -4
- package/dist/routers/attendance.js.map +1 -1
- package/dist/routers/auth.d.ts +20 -0
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +132 -15
- package/dist/routers/auth.js.map +1 -1
- package/dist/routers/class.d.ts +10 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +49 -5
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/comment.d.ts +7 -0
- package/dist/routers/comment.d.ts.map +1 -1
- package/dist/routers/comment.js +9 -2
- package/dist/routers/comment.js.map +1 -1
- package/dist/routers/conversation.d.ts +1 -0
- package/dist/routers/conversation.d.ts.map +1 -1
- package/dist/routers/conversation.js +46 -31
- package/dist/routers/conversation.js.map +1 -1
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +30 -7
- package/dist/routers/file.js.map +1 -1
- package/dist/routers/labChat.d.ts +1 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/labChat.js +2 -3
- package/dist/routers/labChat.js.map +1 -1
- package/dist/routers/marketing.d.ts +1 -1
- package/dist/routers/newtonChat.d.ts +55 -0
- package/dist/routers/newtonChat.d.ts.map +1 -0
- package/dist/routers/newtonChat.js +438 -0
- package/dist/routers/newtonChat.js.map +1 -0
- package/dist/routers/notifications.d.ts +4 -4
- package/dist/routers/section.d.ts +9 -4
- package/dist/routers/section.d.ts.map +1 -1
- package/dist/routers/section.js +8 -8
- package/dist/routers/section.js.map +1 -1
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +5 -4
- package/dist/routers/user.js.map +1 -1
- package/dist/routers/worksheet.d.ts +30 -36
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +11 -33
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/seedDatabase.d.ts +1 -1
- package/dist/seedDatabase.js +275 -284
- package/dist/seedDatabase.js.map +1 -1
- package/dist/server/pipelines/aiLabChat.d.ts +10 -0
- package/dist/server/pipelines/aiLabChat.d.ts.map +1 -0
- package/dist/server/pipelines/aiLabChat.js +83 -0
- package/dist/server/pipelines/aiLabChat.js.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts +2 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.js +138 -0
- package/dist/server/pipelines/gradeWorksheet.js.map +1 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +2 -2
- package/dist/trpc.js.map +1 -1
- package/dist/utils/email.d.ts +9 -1
- package/dist/utils/email.d.ts.map +1 -1
- package/dist/utils/email.js +20 -5
- package/dist/utils/email.js.map +1 -1
- package/dist/utils/inference.d.ts +3 -0
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +41 -7
- package/dist/utils/inference.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/docker-compose.yml +14 -0
- package/package.json +13 -4
- package/prisma/schema.prisma +32 -5
- package/scripts/test-pre-push.ts +14 -0
- package/src/index.ts +98 -54
- package/src/instrument.ts +13 -6
- package/src/lib/config/env.ts +126 -0
- package/src/lib/fileUpload.ts +3 -2
- package/src/lib/googleCloudStorage.ts +6 -6
- package/src/lib/jsonConversion.ts +12 -14
- package/src/lib/prisma.ts +23 -2
- package/src/lib/pusher.ts +6 -5
- package/src/middleware/auth.ts +4 -3
- package/src/middleware/security.ts +80 -0
- package/src/routers/_app.ts +2 -0
- package/src/routers/agenda.ts +10 -7
- package/src/routers/announcement.ts +4 -2
- package/src/routers/assignment.ts +58 -40
- package/src/routers/attendance.ts +2 -2
- package/src/routers/auth.ts +143 -14
- package/src/routers/class.ts +52 -3
- package/src/routers/comment.ts +7 -0
- package/src/routers/conversation.ts +49 -29
- package/src/routers/file.ts +29 -5
- package/src/routers/labChat.ts +0 -1
- package/src/routers/newtonChat.ts +520 -0
- package/src/routers/section.ts +6 -6
- package/src/routers/user.ts +3 -2
- package/src/routers/worksheet.ts +9 -37
- package/src/seedDatabase.ts +290 -283
- package/src/server/pipelines/aiLabChat.ts +92 -0
- package/src/server/pipelines/gradeWorksheet.ts +152 -0
- package/src/trpc.ts +2 -0
- package/src/utils/email.ts +30 -3
- package/src/utils/inference.ts +50 -5
- package/src/utils/logger.ts +2 -1
- package/tests/announcement.test.ts +164 -0
- package/tests/assignment.test.ts +296 -0
- package/tests/attendance.test.ts +168 -0
- package/tests/auth.test.ts +33 -10
- package/tests/class.test.ts +34 -9
- package/tests/event.test.ts +228 -0
- package/tests/section.test.ts +216 -0
- package/tests/setup.ts +70 -16
- package/tests/user.test.ts +158 -0
- package/vitest.config.ts +26 -0
- package/API_SPECIFICATION.md +0 -1597
- package/BASE64_REMOVAL_SUMMARY.md +0 -164
- package/CHAT_API_SPEC.md +0 -579
- package/LAB_CHAT_API_SPEC.md +0 -518
- package/dist/routers/school.d.ts +0 -208
- package/dist/routers/school.d.ts.map +0 -1
- package/dist/routers/school.js +0 -483
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonConversion.js","sources":["lib/jsonConversion.ts"],"sourceRoot":"/","sourcesContent":["import { PDFDocument, PDFFont, RGB, StandardFonts, last, rgb } from 'pdf-lib'\nimport fontkit from '@pdf-lib/fontkit'\nimport { readFileSync } from 'fs'\nimport { join } from 'path'\nimport { writeFile } from 'fs'\nimport { DocumentBlock, FormatTypes, Fonts } from './jsonStyles.js'\n\nexport async function createPdf(blocks: DocumentBlock[]) {\n console.log('createPdf: Starting PDF creation with', blocks.length, 'blocks');\n try {\n const pdfDoc = await PDFDocument.create()\n console.log('createPdf: PDFDocument created successfully');\n \n // Register fontkit to enable custom font embedding\n pdfDoc.registerFontkit(fontkit)\n \n // Load Unicode-compatible fonts (Noto Sans)\n const fontDir = join(process.cwd(), 'src', 'lib')\n \n let notoSansRegular: PDFFont\n let notoSansBold: PDFFont\n let notoSansItalic: PDFFont\n let courierFont: PDFFont\n \n try {\n // Try to load custom Unicode fonts\n const regularFontBytes = readFileSync(join(fontDir, 'NotoSans-Regular.ttf'))\n const boldFontBytes = readFileSync(join(fontDir, 'NotoSans-Bold.ttf'))\n const italicFontBytes = readFileSync(join(fontDir, 'NotoSans-Italic.ttf'))\n \n notoSansRegular = await pdfDoc.embedFont(regularFontBytes)\n notoSansBold = await pdfDoc.embedFont(boldFontBytes)\n notoSansItalic = await pdfDoc.embedFont(italicFontBytes)\n courierFont = await pdfDoc.embedFont(StandardFonts.Courier) // Keep Courier for code blocks\n \n console.log('createPdf: Unicode fonts loaded successfully');\n } catch (fontError) {\n console.warn('createPdf: Failed to load custom fonts, falling back to standard fonts:', fontError);\n // Fallback to standard fonts if custom fonts fail\n notoSansRegular = await pdfDoc.embedFont(StandardFonts.Helvetica)\n notoSansBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold)\n notoSansItalic = await pdfDoc.embedFont(StandardFonts.HelveticaOblique)\n courierFont = await pdfDoc.embedFont(StandardFonts.Courier)\n }\n\n const defaultFont = notoSansRegular\n const defaultParagraphSpacing = 10;\n const defaultLineHeight = 1.3\n const defaultFontSize = 12\n const defaultIndentWidth = 14\n const defaultPadding = 10\n\n const headingColor = rgb(0.1, 0.1, 0.1)\n const paragraphColor = rgb(0.15, 0.15, 0.15)\n\n const FONTS: Record<number, PDFFont> = {\n [Fonts.TIMES_ROMAN]: notoSansRegular, // Use Noto Sans instead of Times\n [Fonts.COURIER]: courierFont,\n [Fonts.HELVETICA]: notoSansRegular,\n [Fonts.HELVETICA_BOLD]: notoSansBold,\n [Fonts.HELVETICA_ITALIC]: notoSansItalic,\n [Fonts.HELVETICA_BOLD_ITALIC]: notoSansBold, // Use bold for now, could add bold-italic later\n }\n\n const STYLE_PRESETS: Record<number,\n { fontSize: number; lineHeight: number; paragraphSpacing?: number; font?: PDFFont; color?: RGB; background?: RGB }> =\n {\n [FormatTypes.HEADER_1]: { fontSize: 28, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_2]: { fontSize: 22, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_3]: { fontSize: 18, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_4]: { fontSize: 16, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_5]: { fontSize: 14, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_6]: { fontSize: 12, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.QUOTE]: { fontSize: 14, lineHeight: 1.5, color: rgb(0.35, 0.35, 0.35) },\n [FormatTypes.CODE_BLOCK]: { fontSize: 12, lineHeight: 1.6, font: courierFont, color: rgb(0.1, 0.1, 0.1), background: rgb(0.95, 0.95, 0.95) },\n [FormatTypes.PARAGRAPH]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.BULLET]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.NUMBERED]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.TABLE]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.IMAGE]: { fontSize: 12, lineHeight: 1.3 },\n }\n\n const hexToRgb = (hex) => {\n if (hex.length == 7) {\n const r = parseInt(hex.slice(1, 3), 16) / 255.0;\n const g = parseInt(hex.slice(3, 5), 16) / 255.0;\n const b = parseInt(hex.slice(5, 7), 16) / 255.0;\n return rgb(r, g, b);\n } else if (hex.length == 4) {\n const r = parseInt(hex.slice(1, 2), 16) / 15.0;\n const g = parseInt(hex.slice(2, 3), 16) / 15.0;\n const b = parseInt(hex.slice(3, 4), 16) / 15.0;\n return rgb(r, g, b);\n } else { return rgb(0.0, 0.0, 0.0) };\n };\n\n const colorParse = (color) => {\n if (typeof color === 'string') {\n return hexToRgb(color)\n } else {\n return color\n }\n }\n\n // Minimal sanitization - only remove truly problematic invisible characters\n // With Unicode fonts, we can now keep most characters as-is\n const sanitizeText = (text: string): string => {\n return text\n // Only remove invisible/control characters that break PDF generation\n .replace(/\\uFEFF/g, '') // Remove BOM (Byte Order Mark)\n .replace(/\\u200B/g, '') // Remove zero-width space\n .replace(/\\u200C/g, '') // Remove zero-width non-joiner\n .replace(/\\u200D/g, '') // Remove zero-width joiner\n .replace(/\\uFFFD/g, '?') // Replace replacement character with ?\n // Keep ALL visible Unicode characters - Noto Sans supports them!\n }\n\n // Parse markdown and return styled text segments\n interface TextSegment {\n text: string;\n font: PDFFont;\n color: RGB;\n }\n\n const parseMarkdown = (text: string, baseFont: PDFFont, baseColor: RGB): TextSegment[] => {\n const segments: TextSegment[] = [];\n let currentIndex = 0;\n \n // Regex patterns for markdown\n const patterns = [\n { regex: /\\*\\*(.*?)\\*\\*/g, font: notoSansBold }, // **bold**\n { regex: /__(.*?)__/g, font: notoSansBold }, // __bold__\n { regex: /\\*(.*?)\\*/g, font: notoSansItalic }, // *italic*\n { regex: /_(.*?)_/g, font: notoSansItalic }, // _italic_\n { regex: /`(.*?)`/g, font: courierFont, color: rgb(0.2, 0.2, 0.2) }, // `code`\n ];\n\n // Find all markdown matches\n const matches: Array<{start: number, end: number, text: string, font: PDFFont, color?: RGB}> = [];\n \n for (const pattern of patterns) {\n let match;\n pattern.regex.lastIndex = 0; // Reset regex\n while ((match = pattern.regex.exec(text)) !== null) {\n matches.push({\n start: match.index,\n end: match.index + match[0].length,\n text: match[1], // Captured group (content without markdown syntax)\n font: pattern.font,\n color: pattern.color\n });\n }\n }\n\n // Sort matches by start position\n matches.sort((a, b) => a.start - b.start);\n\n // Remove overlapping matches (keep the first one)\n const filteredMatches: Array<{start: number, end: number, text: string, font: PDFFont, color?: RGB}> = [];\n for (const match of matches) {\n const hasOverlap = filteredMatches.some(existing => \n (match.start < existing.end && match.end > existing.start)\n );\n if (!hasOverlap) {\n filteredMatches.push(match);\n }\n }\n\n // Build segments\n for (const match of filteredMatches) {\n // Add text before this match\n if (match.start > currentIndex) {\n const beforeText = text.substring(currentIndex, match.start);\n if (beforeText) {\n segments.push({\n text: sanitizeText(beforeText),\n font: baseFont,\n color: baseColor\n });\n }\n }\n\n // Add the styled match\n segments.push({\n text: sanitizeText(match.text),\n font: match.font,\n color: match.color || baseColor\n });\n\n currentIndex = match.end;\n }\n\n // Add remaining text\n if (currentIndex < text.length) {\n const remainingText = text.substring(currentIndex);\n if (remainingText) {\n segments.push({\n text: sanitizeText(remainingText),\n font: baseFont,\n color: baseColor\n });\n }\n }\n\n // If no markdown was found, return the whole text as one segment\n if (segments.length === 0) {\n segments.push({\n text: sanitizeText(text),\n font: baseFont,\n color: baseColor\n });\n }\n\n return segments;\n }\n\n // Enhanced text wrapping that handles styled segments\n const wrapStyledText = (segments: TextSegment[], fontSize: number, maxWidth: number): Array<{segments: TextSegment[], width: number}> => {\n const lines: Array<{segments: TextSegment[], width: number}> = [];\n let currentLine: TextSegment[] = [];\n let currentWidth = 0;\n\n for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {\n const segment = segments[segmentIndex];\n const words = segment.text.split(/\\s+/).filter(word => word.length > 0);\n \n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const wordWidth = segment.font.widthOfTextAtSize(word, fontSize);\n const spaceWidth = segment.font.widthOfTextAtSize(' ', fontSize);\n \n // Add space before word if:\n // 1. Not the first word in the line AND\n // 2. (Not the first word in the segment OR not the first segment)\n const needSpace = currentLine.length > 0 && (i > 0 || segmentIndex > 0);\n const totalWidth = wordWidth + (needSpace ? spaceWidth : 0);\n\n // Check if we need to wrap to new line\n if (currentWidth + totalWidth > maxWidth && currentLine.length > 0) {\n // Finish current line\n lines.push({ segments: [...currentLine], width: currentWidth });\n currentLine = [];\n currentWidth = 0;\n }\n\n // Add the word to current line\n if (needSpace && currentLine.length > 0) {\n // Try to merge with last segment if same font and color\n const lastSegment = currentLine[currentLine.length - 1];\n if (lastSegment.font === segment.font && lastSegment.color === segment.color) {\n lastSegment.text += ' ' + word;\n currentWidth += spaceWidth + wordWidth;\n } else {\n // Add space + word as new segment\n currentLine.push({ text: ' ' + word, font: segment.font, color: segment.color });\n currentWidth += spaceWidth + wordWidth;\n }\n } else {\n // Add word without space (first word in line or first word overall)\n currentLine.push({ text: word, font: segment.font, color: segment.color });\n currentWidth += wordWidth;\n }\n }\n }\n\n // Add final line if it has content\n if (currentLine.length > 0) {\n lines.push({ segments: currentLine, width: currentWidth });\n }\n\n return lines.length > 0 ? lines : [{ segments: [{ text: '', font: defaultFont, color: rgb(0, 0, 0) }], width: 0 }];\n }\n\n let page = pdfDoc.addPage()\n let { width, height } = page.getSize()\n const { marginTop, marginBottom, marginLeft, marginRight } = { marginTop: 50, marginBottom: 50, marginLeft: 50, marginRight: 50 }\n\n const maxTextWidth = () => width - marginLeft - marginRight\n\n const wrapText = (text: string, font: any, fontSize: number, maxWidth: number): string[] => {\n if (!text) return ['']\n const words = text.split(/\\s+/)\n const lines: string[] = []\n let current = ''\n\n const measure = (t: string) => font.widthOfTextAtSize(t, fontSize)\n\n const pushCurrent = () => {\n if (current.length > 0) {\n lines.push(current)\n current = ''\n }\n }\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i]\n if (current.length === 0) {\n // If a single word is too long, hard-break it\n if (measure(word) > maxWidth) {\n let chunk = ''\n for (const ch of word) {\n const test = chunk + ch\n if (measure(test) > maxWidth && chunk.length > 0) {\n lines.push(chunk)\n chunk = ch\n } else {\n chunk = test\n }\n }\n current = chunk\n } else {\n current = word\n }\n } else {\n const test = current + ' ' + word\n if (measure(test) <= maxWidth) {\n current = test\n } else {\n pushCurrent()\n // start new line with this word; hard-break if needed\n if (measure(word) > maxWidth) {\n let chunk = ''\n for (const ch of word) {\n const t2 = chunk + ch\n if (measure(t2) > maxWidth && chunk.length > 0) {\n lines.push(chunk)\n chunk = ch\n } else {\n chunk = t2\n }\n }\n current = chunk\n } else {\n current = word\n }\n }\n }\n }\n pushCurrent()\n return lines\n }\n\n let y = height - marginTop\n let lastLineHeight = -1\n console.log('createPdf: Starting to process', blocks.length, 'blocks');\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n console.log(`createPdf: Processing block ${i + 1}/${blocks.length}, format: ${block.format}, content type: ${typeof block.content}`);\n try {\n const preset = STYLE_PRESETS[block.format] || { fontSize: defaultFontSize, lineHeight: defaultLineHeight }\n\n const userLineHeight = (block as any).metadata?.lineHeight\n\n const fontSize = (block as any).metadata?.fontSize || preset.fontSize\n const lineHeight = (userLineHeight ? fontSize * userLineHeight : fontSize * preset.lineHeight)\n const paragraphSpacing = (block as any).metadata?.paragraphSpacing || defaultParagraphSpacing\n const indentWidth = (block as any).metadata?.indentWidth || defaultIndentWidth\n\n const paddingX = (block as any).metadata?.paddingX || defaultPadding\n const paddingY = (block as any).metadata?.paddingY || defaultPadding\n\n const font = FONTS[(block as any).metadata?.font] || preset.font || defaultFont // Broken\n const color = colorParse((block as any).metadata?.color || preset.color || rgb(0.0, 0.0, 0.0))\n const background = colorParse((block as any).metadata?.background || preset.background || rgb(1.0, 1.0, 1.0))\n\n if (lastLineHeight >= 0) {\n y -= lineHeight - lastLineHeight\n } else {\n y -= fontSize\n }\n\n const ensureSpace = (needed: number) => {\n if (y - needed < marginBottom) {\n page = pdfDoc.addPage()\n ; ({ width, height } = page.getSize())\n y = height - marginTop - fontSize\n lastLineHeight = -1\n return true\n } else { return false }\n }\n\n const drawParagraph = (text: string) => {\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, maxTextWidth());\n \n for (const line of lines) {\n ensureSpace(lineHeight);\n let currentX = marginLeft;\n \n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n\n const drawHeading = (text: string, align?: 'left' | 'center' | 'right') => {\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, maxTextWidth());\n \n for (const line of lines) {\n ensureSpace(lineHeight);\n let startX = marginLeft;\n \n if (align === 'center') {\n startX = marginLeft + (maxTextWidth() - line.width) / 2;\n } else if (align === 'right') {\n startX = marginLeft + maxTextWidth() - line.width;\n }\n \n let currentX = startX;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n\n const drawBulletList = (items: string[]) => {\n const bulletIndent = indentWidth\n const gap = 8\n const contentWidth = maxTextWidth() - (bulletIndent + gap)\n for (const item of items) {\n // Clean up any bullet symbols that the AI might have added\n const cleanItem = item.replace(/^\\s*[•*-]\\s*/, '').trim();\n const segments = parseMarkdown(cleanItem, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n \n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n ensureSpace(lineHeight);\n \n // Draw bullet only on first line\n if (lineIndex === 0) {\n page.drawText('•', {\n x: marginLeft + gap,\n y: y,\n size: fontSize,\n font: font,\n color: color,\n });\n }\n \n // Draw styled text\n let currentX = marginLeft + bulletIndent + gap;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n }\n\n const drawNumberedList = (items: string[]) => {\n const numberIndent = indentWidth\n const gap = 8\n const contentWidth = maxTextWidth() - (numberIndent + gap)\n let index = 1\n for (const item of items) {\n // Clean up any numbers that the AI might have added\n const cleanItem = item.replace(/^\\s*\\d+\\.\\s*/, '').trim();\n const numLabel = `${index}.`\n const numWidth = font.widthOfTextAtSize(numLabel, fontSize)\n const segments = parseMarkdown(cleanItem, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n \n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n ensureSpace(lineHeight);\n \n // Draw number only on first line\n if (lineIndex === 0) {\n page.drawText(numLabel, {\n x: marginLeft + gap,\n y: y,\n size: fontSize,\n font: font,\n color: color,\n });\n }\n \n // Draw styled text\n let currentX = marginLeft + Math.max(numberIndent, numWidth + 6) + gap;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n index++;\n }\n }\n\n const drawQuote = (text: string) => {\n const ruleWidth = 2\n const ruleGap = 8\n const contentX = marginLeft + ruleWidth + ruleGap\n const contentWidth = maxTextWidth() - (ruleWidth + ruleGap)\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n const totalHeight = lines.length * lineHeight + fontSize\n var remainingHeight = totalHeight\n \n for (const line of lines) {\n let pageAdded = ensureSpace(lineHeight)\n if (pageAdded || remainingHeight == totalHeight) {\n let blockHeight = Math.floor(Math.min(remainingHeight, y - marginBottom) / lineHeight) * lineHeight\n page.drawRectangle({\n x: marginLeft,\n y: y + lineHeight,\n width: ruleWidth,\n height: -blockHeight - lineHeight + fontSize,\n color: color,\n })\n remainingHeight -= blockHeight + lineHeight - fontSize\n }\n \n // Draw styled text\n let currentX = contentX;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n y -= lineHeight - fontSize\n }\n\n const drawCodeBlock = (textLines: string[]) => {\n const codeFont = font\n \n // Detect indentation patterns\n const detectIndentation = (lines: string[]) => {\n let tabCount = 0\n let spaceCount = 0\n let minSpaces = Infinity\n \n for (const line of lines) {\n if (line.trim().length === 0) continue // Skip empty lines\n \n const leadingWhitespace = line.match(/^(\\s*)/)?.[1] || ''\n if (leadingWhitespace.includes('\\t')) {\n tabCount++\n } else if (leadingWhitespace.length > 0) {\n spaceCount++\n minSpaces = Math.min(minSpaces, leadingWhitespace.length)\n }\n }\n \n // Determine indentation strategy\n if (tabCount > spaceCount) {\n return { type: 'tab', width: indentWidth }\n } else if (spaceCount > 0) {\n // Use the most common space count, or default to 4\n const commonSpaces = minSpaces === Infinity ? 4 : minSpaces\n return { type: 'space', width: commonSpaces * (fontSize * 0.6) } // Approximate space width\n } else {\n return { type: 'space', width: fontSize * 2.4 } // Default 4 spaces\n }\n }\n \n const indentInfo = detectIndentation(textLines)\n \n // Process lines with indentation\n const processedLines: { text: string; indentLevel: number; originalLine: string }[] = []\n \n for (const line of textLines) {\n const leadingWhitespace = line.match(/^(\\s*)/)?.[1] || ''\n let indentLevel = 0\n \n if (indentInfo.type === 'tab') {\n indentLevel = leadingWhitespace.split('\\t').length - 1\n } else {\n // Count spaces, grouping by the detected space width\n const spaceWidth = indentInfo.width / (fontSize * 0.6) // Convert back to space count\n indentLevel = Math.floor(leadingWhitespace.length / spaceWidth)\n }\n \n processedLines.push({\n text: line.trim(),\n indentLevel,\n originalLine: line\n })\n }\n \n // Wrap each processed line separately to preserve line breaks and indentation\n const wrappedLines: { text: string; indentLevel: number; isContinuation: boolean }[] = []\n const contentW = maxTextWidth() - paddingX * 2\n \n for (const processedLine of processedLines) {\n if (processedLine.text.length === 0) {\n // Empty line - preserve as empty line\n wrappedLines.push({\n text: '',\n indentLevel: processedLine.indentLevel,\n isContinuation: false\n })\n } else {\n const parts = wrapText(processedLine.text, codeFont, fontSize, contentW)\n for (let i = 0; i < parts.length; i++) {\n wrappedLines.push({\n text: parts[i],\n indentLevel: processedLine.indentLevel,\n isContinuation: i > 0\n })\n }\n }\n }\n \n const totalHeight = wrappedLines.length * lineHeight + paddingY * 2\n var remainingHeight = totalHeight\n y -= paddingY\n \n for (const wrappedLine of wrappedLines) {\n let pageAdded = ensureSpace(lineHeight + paddingY)\n if (pageAdded || remainingHeight == totalHeight) {\n let blockHeight = Math.floor(Math.min(remainingHeight, y - marginBottom - paddingY) / lineHeight) * lineHeight\n page.drawRectangle({\n x: marginLeft,\n y: y + fontSize,\n width: maxTextWidth(),\n height: -blockHeight - paddingY * 2,\n color: background,\n })\n remainingHeight -= blockHeight\n y -= paddingY\n }\n \n // Calculate indentation offset\n const indentOffset = wrappedLine.indentLevel * indentInfo.width\n \n page.drawText(wrappedLine.text, {\n x: marginLeft + paddingX + indentOffset,\n y: y,\n size: fontSize,\n font: codeFont,\n color: color,\n })\n y -= lineHeight\n }\n y -= paddingY\n }\n\n // Render by block format\n switch (block.format) {\n case FormatTypes.HEADER_1:\n case FormatTypes.HEADER_2:\n case FormatTypes.HEADER_3:\n case FormatTypes.HEADER_4:\n case FormatTypes.HEADER_5:\n case FormatTypes.HEADER_6: {\n const align = (block as any).metadata?.align as 'left' | 'center' | 'right' | undefined\n drawHeading(String(block.content), align)\n break\n }\n case FormatTypes.BULLET: {\n const items = Array.isArray(block.content) ? block.content.map(String) : [String(block.content)]\n drawBulletList(items)\n break\n }\n case FormatTypes.NUMBERED: {\n const items = Array.isArray(block.content) ? block.content.map(String) : [String(block.content)]\n drawNumberedList(items)\n break\n }\n case FormatTypes.QUOTE: {\n drawQuote(String(block.content))\n break\n }\n case FormatTypes.CODE_BLOCK: {\n const lines = Array.isArray(block.content) ? block.content.map(String) : String(block.content).split('\\n')\n drawCodeBlock(lines)\n break\n }\n default: {\n if (typeof block.content === 'string') {\n drawParagraph(block.content)\n } else {\n for (const c of block.content) {\n drawParagraph(String(c))\n }\n }\n }\n }\n console.log(`createPdf: Successfully processed block ${i + 1}`);\n y -= paragraphSpacing\n lastLineHeight = lineHeight\n } catch (blockError) {\n console.error(`createPdf: Error processing block ${i + 1}:`, blockError);\n throw blockError;\n }\n }\n\n console.log('createPdf: About to save PDF document');\n const pdfBytes = await pdfDoc.save()\n console.log('createPdf: PDF saved successfully, bytes length:', pdfBytes.length);\n // writeFile('output.pdf', pdfBytes, () => {\n // console.log('PDF created successfully') // Still only saves file, no API yet\n // })\n return pdfBytes\n } catch (error) {\n console.error('createPdf: Error during PDF creation:', error);\n throw error;\n }\n}\n"],"names":[],"mappings":"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","debug_id":"9dcef6bc-81ec-59b1-ba5e-2017ff5b9c66"}
|
|
1
|
+
{"version":3,"file":"jsonConversion.js","sources":["lib/jsonConversion.ts"],"sourceRoot":"/","sourcesContent":["import { PDFDocument, PDFFont, RGB, StandardFonts, last, rgb } from 'pdf-lib'\nimport fontkit from '@pdf-lib/fontkit'\nimport { readFileSync } from 'fs'\nimport { join } from 'path'\nimport { writeFile } from 'fs'\nimport { DocumentBlock, FormatTypes, Fonts } from './jsonStyles.js'\nimport { logger } from '../utils/logger.js'\n\nexport async function createPdf(blocks: DocumentBlock[]) {\n logger.info(`createPdf: Starting PDF creation with ${blocks.length} blocks`);\n try {\n const pdfDoc = await PDFDocument.create()\n logger.info('createPdf: PDFDocument created successfully');\n \n // Register fontkit to enable custom font embedding\n pdfDoc.registerFontkit(fontkit)\n \n // Load Unicode-compatible fonts (Noto Sans)\n const fontDir = join(process.cwd(), 'src', 'lib')\n \n let notoSansRegular: PDFFont\n let notoSansBold: PDFFont\n let notoSansItalic: PDFFont\n let courierFont: PDFFont\n \n try {\n // Try to load custom Unicode fonts\n const regularFontBytes = readFileSync(join(fontDir, 'NotoSans-Regular.ttf'))\n const boldFontBytes = readFileSync(join(fontDir, 'NotoSans-Bold.ttf'))\n const italicFontBytes = readFileSync(join(fontDir, 'NotoSans-Italic.ttf'))\n \n notoSansRegular = await pdfDoc.embedFont(regularFontBytes)\n notoSansBold = await pdfDoc.embedFont(boldFontBytes)\n notoSansItalic = await pdfDoc.embedFont(italicFontBytes)\n courierFont = await pdfDoc.embedFont(StandardFonts.Courier) // Keep Courier for code blocks\n \n logger.info('createPdf: Unicode fonts loaded successfully');\n } catch (fontError) {\n logger.warn(`createPdf: Failed to load custom fonts, falling back to standard fonts: ${fontError}`);\n // Fallback to standard fonts if custom fonts fail\n notoSansRegular = await pdfDoc.embedFont(StandardFonts.Helvetica)\n notoSansBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold)\n notoSansItalic = await pdfDoc.embedFont(StandardFonts.HelveticaOblique)\n courierFont = await pdfDoc.embedFont(StandardFonts.Courier)\n }\n\n const defaultFont = notoSansRegular\n const defaultParagraphSpacing = 10;\n const defaultLineHeight = 1.3\n const defaultFontSize = 12\n const defaultIndentWidth = 14\n const defaultPadding = 10\n\n const headingColor = rgb(0.1, 0.1, 0.1)\n const paragraphColor = rgb(0.15, 0.15, 0.15)\n\n const FONTS: Record<number, PDFFont> = {\n [Fonts.TIMES_ROMAN]: notoSansRegular, // Use Noto Sans instead of Times\n [Fonts.COURIER]: courierFont,\n [Fonts.HELVETICA]: notoSansRegular,\n [Fonts.HELVETICA_BOLD]: notoSansBold,\n [Fonts.HELVETICA_ITALIC]: notoSansItalic,\n [Fonts.HELVETICA_BOLD_ITALIC]: notoSansBold, // Use bold for now, could add bold-italic later\n }\n\n const STYLE_PRESETS: Record<number,\n { fontSize: number; lineHeight: number; paragraphSpacing?: number; font?: PDFFont; color?: RGB; background?: RGB }> =\n {\n [FormatTypes.HEADER_1]: { fontSize: 28, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_2]: { fontSize: 22, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_3]: { fontSize: 18, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_4]: { fontSize: 16, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_5]: { fontSize: 14, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_6]: { fontSize: 12, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.QUOTE]: { fontSize: 14, lineHeight: 1.5, color: rgb(0.35, 0.35, 0.35) },\n [FormatTypes.CODE_BLOCK]: { fontSize: 12, lineHeight: 1.6, font: courierFont, color: rgb(0.1, 0.1, 0.1), background: rgb(0.95, 0.95, 0.95) },\n [FormatTypes.PARAGRAPH]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.BULLET]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.NUMBERED]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.TABLE]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.IMAGE]: { fontSize: 12, lineHeight: 1.3 },\n }\n\n const hexToRgb = (hex) => {\n if (hex.length == 7) {\n const r = parseInt(hex.slice(1, 3), 16) / 255.0;\n const g = parseInt(hex.slice(3, 5), 16) / 255.0;\n const b = parseInt(hex.slice(5, 7), 16) / 255.0;\n return rgb(r, g, b);\n } else if (hex.length == 4) {\n const r = parseInt(hex.slice(1, 2), 16) / 15.0;\n const g = parseInt(hex.slice(2, 3), 16) / 15.0;\n const b = parseInt(hex.slice(3, 4), 16) / 15.0;\n return rgb(r, g, b);\n } else { return rgb(0.0, 0.0, 0.0) };\n };\n\n const colorParse = (color) => {\n if (typeof color === 'string') {\n return hexToRgb(color)\n } else {\n return color\n }\n }\n\n // Minimal sanitization - only remove truly problematic invisible characters\n // With Unicode fonts, we can now keep most characters as-is\n const sanitizeText = (text: string): string => {\n return text\n // Only remove invisible/control characters that break PDF generation\n .replace(/\\uFEFF/g, '') // Remove BOM (Byte Order Mark)\n .replace(/\\u200B/g, '') // Remove zero-width space\n .replace(/\\u200C/g, '') // Remove zero-width non-joiner\n .replace(/\\u200D/g, '') // Remove zero-width joiner\n .replace(/\\uFFFD/g, '?') // Replace replacement character with ?\n // Keep ALL visible Unicode characters - Noto Sans supports them!\n }\n\n // Parse markdown and return styled text segments\n interface TextSegment {\n text: string;\n font: PDFFont;\n color: RGB;\n }\n\n const parseMarkdown = (text: string, baseFont: PDFFont, baseColor: RGB): TextSegment[] => {\n const segments: TextSegment[] = [];\n let currentIndex = 0;\n \n // Regex patterns for markdown\n const patterns = [\n { regex: /\\*\\*(.*?)\\*\\*/g, font: notoSansBold }, // **bold**\n { regex: /__(.*?)__/g, font: notoSansBold }, // __bold__\n { regex: /\\*(.*?)\\*/g, font: notoSansItalic }, // *italic*\n { regex: /_(.*?)_/g, font: notoSansItalic }, // _italic_\n { regex: /`(.*?)`/g, font: courierFont, color: rgb(0.2, 0.2, 0.2) }, // `code`\n ];\n\n // Find all markdown matches\n const matches: Array<{start: number, end: number, text: string, font: PDFFont, color?: RGB}> = [];\n \n for (const pattern of patterns) {\n let match;\n pattern.regex.lastIndex = 0; // Reset regex\n while ((match = pattern.regex.exec(text)) !== null) {\n matches.push({\n start: match.index,\n end: match.index + match[0].length,\n text: match[1], // Captured group (content without markdown syntax)\n font: pattern.font,\n color: pattern.color\n });\n }\n }\n\n // Sort matches by start position\n matches.sort((a, b) => a.start - b.start);\n\n // Remove overlapping matches (keep the first one)\n const filteredMatches: Array<{start: number, end: number, text: string, font: PDFFont, color?: RGB}> = [];\n for (const match of matches) {\n const hasOverlap = filteredMatches.some(existing => \n (match.start < existing.end && match.end > existing.start)\n );\n if (!hasOverlap) {\n filteredMatches.push(match);\n }\n }\n\n // Build segments\n for (const match of filteredMatches) {\n // Add text before this match\n if (match.start > currentIndex) {\n const beforeText = text.substring(currentIndex, match.start);\n if (beforeText) {\n segments.push({\n text: sanitizeText(beforeText),\n font: baseFont,\n color: baseColor\n });\n }\n }\n\n // Add the styled match\n segments.push({\n text: sanitizeText(match.text),\n font: match.font,\n color: match.color || baseColor\n });\n\n currentIndex = match.end;\n }\n\n // Add remaining text\n if (currentIndex < text.length) {\n const remainingText = text.substring(currentIndex);\n if (remainingText) {\n segments.push({\n text: sanitizeText(remainingText),\n font: baseFont,\n color: baseColor\n });\n }\n }\n\n // If no markdown was found, return the whole text as one segment\n if (segments.length === 0) {\n segments.push({\n text: sanitizeText(text),\n font: baseFont,\n color: baseColor\n });\n }\n\n return segments;\n }\n\n // Enhanced text wrapping that handles styled segments\n const wrapStyledText = (segments: TextSegment[], fontSize: number, maxWidth: number): Array<{segments: TextSegment[], width: number}> => {\n const lines: Array<{segments: TextSegment[], width: number}> = [];\n let currentLine: TextSegment[] = [];\n let currentWidth = 0;\n\n for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {\n const segment = segments[segmentIndex];\n const words = segment.text.split(/\\s+/).filter(word => word.length > 0);\n \n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const wordWidth = segment.font.widthOfTextAtSize(word, fontSize);\n const spaceWidth = segment.font.widthOfTextAtSize(' ', fontSize);\n \n // Add space before word if:\n // 1. Not the first word in the line AND\n // 2. (Not the first word in the segment OR not the first segment)\n const needSpace = currentLine.length > 0 && (i > 0 || segmentIndex > 0);\n const totalWidth = wordWidth + (needSpace ? spaceWidth : 0);\n\n // Check if we need to wrap to new line\n if (currentWidth + totalWidth > maxWidth && currentLine.length > 0) {\n // Finish current line\n lines.push({ segments: [...currentLine], width: currentWidth });\n currentLine = [];\n currentWidth = 0;\n }\n\n // Add the word to current line\n if (needSpace && currentLine.length > 0) {\n // Try to merge with last segment if same font and color\n const lastSegment = currentLine[currentLine.length - 1];\n if (lastSegment.font === segment.font && lastSegment.color === segment.color) {\n lastSegment.text += ' ' + word;\n currentWidth += spaceWidth + wordWidth;\n } else {\n // Add space + word as new segment\n currentLine.push({ text: ' ' + word, font: segment.font, color: segment.color });\n currentWidth += spaceWidth + wordWidth;\n }\n } else {\n // Add word without space (first word in line or first word overall)\n currentLine.push({ text: word, font: segment.font, color: segment.color });\n currentWidth += wordWidth;\n }\n }\n }\n\n // Add final line if it has content\n if (currentLine.length > 0) {\n lines.push({ segments: currentLine, width: currentWidth });\n }\n\n return lines.length > 0 ? lines : [{ segments: [{ text: '', font: defaultFont, color: rgb(0, 0, 0) }], width: 0 }];\n }\n\n let page = pdfDoc.addPage()\n let { width, height } = page.getSize()\n const { marginTop, marginBottom, marginLeft, marginRight } = { marginTop: 50, marginBottom: 50, marginLeft: 50, marginRight: 50 }\n\n const maxTextWidth = () => width - marginLeft - marginRight\n\n const wrapText = (text: string, font: any, fontSize: number, maxWidth: number): string[] => {\n if (!text) return ['']\n const words = text.split(/\\s+/)\n const lines: string[] = []\n let current = ''\n\n const measure = (t: string) => font.widthOfTextAtSize(t, fontSize)\n\n const pushCurrent = () => {\n if (current.length > 0) {\n lines.push(current)\n current = ''\n }\n }\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i]\n if (current.length === 0) {\n // If a single word is too long, hard-break it\n if (measure(word) > maxWidth) {\n let chunk = ''\n for (const ch of word) {\n const test = chunk + ch\n if (measure(test) > maxWidth && chunk.length > 0) {\n lines.push(chunk)\n chunk = ch\n } else {\n chunk = test\n }\n }\n current = chunk\n } else {\n current = word\n }\n } else {\n const test = current + ' ' + word\n if (measure(test) <= maxWidth) {\n current = test\n } else {\n pushCurrent()\n // start new line with this word; hard-break if needed\n if (measure(word) > maxWidth) {\n let chunk = ''\n for (const ch of word) {\n const t2 = chunk + ch\n if (measure(t2) > maxWidth && chunk.length > 0) {\n lines.push(chunk)\n chunk = ch\n } else {\n chunk = t2\n }\n }\n current = chunk\n } else {\n current = word\n }\n }\n }\n }\n pushCurrent()\n return lines\n }\n\n let y = height - marginTop\n let lastLineHeight = -1\n logger.info(`createPdf: Starting to process ${blocks.length} blocks`);\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n logger.info(`createPdf: Processing block ${i + 1}/${blocks.length}, format: ${block.format}, content type: ${typeof block.content}`);\n try {\n const preset = STYLE_PRESETS[block.format] || { fontSize: defaultFontSize, lineHeight: defaultLineHeight }\n\n const userLineHeight = (block as any).metadata?.lineHeight\n\n const fontSize = (block as any).metadata?.fontSize || preset.fontSize\n const lineHeight = (userLineHeight ? fontSize * userLineHeight : fontSize * preset.lineHeight)\n const paragraphSpacing = (block as any).metadata?.paragraphSpacing || defaultParagraphSpacing\n const indentWidth = (block as any).metadata?.indentWidth || defaultIndentWidth\n\n const paddingX = (block as any).metadata?.paddingX || defaultPadding\n const paddingY = (block as any).metadata?.paddingY || defaultPadding\n\n const font = FONTS[(block as any).metadata?.font] || preset.font || defaultFont // Broken\n const color = colorParse((block as any).metadata?.color || preset.color || rgb(0.0, 0.0, 0.0))\n const background = colorParse((block as any).metadata?.background || preset.background || rgb(1.0, 1.0, 1.0))\n\n if (lastLineHeight >= 0) {\n y -= lineHeight - lastLineHeight\n } else {\n y -= fontSize\n }\n\n const ensureSpace = (needed: number) => {\n if (y - needed < marginBottom) {\n page = pdfDoc.addPage()\n ; ({ width, height } = page.getSize())\n y = height - marginTop - fontSize\n lastLineHeight = -1\n return true\n } else { return false }\n }\n\n const drawParagraph = (text: string) => {\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, maxTextWidth());\n \n for (const line of lines) {\n ensureSpace(lineHeight);\n let currentX = marginLeft;\n \n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n\n const drawHeading = (text: string, align?: 'left' | 'center' | 'right') => {\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, maxTextWidth());\n \n for (const line of lines) {\n ensureSpace(lineHeight);\n let startX = marginLeft;\n \n if (align === 'center') {\n startX = marginLeft + (maxTextWidth() - line.width) / 2;\n } else if (align === 'right') {\n startX = marginLeft + maxTextWidth() - line.width;\n }\n \n let currentX = startX;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n\n const drawBulletList = (items: string[]) => {\n const bulletIndent = indentWidth\n const gap = 8\n const contentWidth = maxTextWidth() - (bulletIndent + gap)\n for (const item of items) {\n // Clean up any bullet symbols that the AI might have added\n const cleanItem = item.replace(/^\\s*[•*-]\\s*/, '').trim();\n const segments = parseMarkdown(cleanItem, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n \n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n ensureSpace(lineHeight);\n \n // Draw bullet only on first line\n if (lineIndex === 0) {\n page.drawText('•', {\n x: marginLeft + gap,\n y: y,\n size: fontSize,\n font: font,\n color: color,\n });\n }\n \n // Draw styled text\n let currentX = marginLeft + bulletIndent + gap;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n }\n\n const drawNumberedList = (items: string[]) => {\n const numberIndent = indentWidth\n const gap = 8\n const contentWidth = maxTextWidth() - (numberIndent + gap)\n let index = 1\n for (const item of items) {\n // Clean up any numbers that the AI might have added\n const cleanItem = item.replace(/^\\s*\\d+\\.\\s*/, '').trim();\n const numLabel = `${index}.`\n const numWidth = font.widthOfTextAtSize(numLabel, fontSize)\n const segments = parseMarkdown(cleanItem, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n \n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n ensureSpace(lineHeight);\n \n // Draw number only on first line\n if (lineIndex === 0) {\n page.drawText(numLabel, {\n x: marginLeft + gap,\n y: y,\n size: fontSize,\n font: font,\n color: color,\n });\n }\n \n // Draw styled text\n let currentX = marginLeft + Math.max(numberIndent, numWidth + 6) + gap;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n index++;\n }\n }\n\n const drawQuote = (text: string) => {\n const ruleWidth = 2\n const ruleGap = 8\n const contentX = marginLeft + ruleWidth + ruleGap\n const contentWidth = maxTextWidth() - (ruleWidth + ruleGap)\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n const totalHeight = lines.length * lineHeight + fontSize\n var remainingHeight = totalHeight\n \n for (const line of lines) {\n let pageAdded = ensureSpace(lineHeight)\n if (pageAdded || remainingHeight == totalHeight) {\n let blockHeight = Math.floor(Math.min(remainingHeight, y - marginBottom) / lineHeight) * lineHeight\n page.drawRectangle({\n x: marginLeft,\n y: y + lineHeight,\n width: ruleWidth,\n height: -blockHeight - lineHeight + fontSize,\n color: color,\n })\n remainingHeight -= blockHeight + lineHeight - fontSize\n }\n \n // Draw styled text\n let currentX = contentX;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n y -= lineHeight - fontSize\n }\n\n const drawCodeBlock = (textLines: string[]) => {\n const codeFont = font\n \n // Detect indentation patterns\n const detectIndentation = (lines: string[]) => {\n let tabCount = 0\n let spaceCount = 0\n let minSpaces = Infinity\n \n for (const line of lines) {\n if (line.trim().length === 0) continue // Skip empty lines\n \n const leadingWhitespace = line.match(/^(\\s*)/)?.[1] || ''\n if (leadingWhitespace.includes('\\t')) {\n tabCount++\n } else if (leadingWhitespace.length > 0) {\n spaceCount++\n minSpaces = Math.min(minSpaces, leadingWhitespace.length)\n }\n }\n \n // Determine indentation strategy\n if (tabCount > spaceCount) {\n return { type: 'tab', width: indentWidth }\n } else if (spaceCount > 0) {\n // Use the most common space count, or default to 4\n const commonSpaces = minSpaces === Infinity ? 4 : minSpaces\n return { type: 'space', width: commonSpaces * (fontSize * 0.6) } // Approximate space width\n } else {\n return { type: 'space', width: fontSize * 2.4 } // Default 4 spaces\n }\n }\n \n const indentInfo = detectIndentation(textLines)\n \n // Process lines with indentation\n const processedLines: { text: string; indentLevel: number; originalLine: string }[] = []\n \n for (const line of textLines) {\n const leadingWhitespace = line.match(/^(\\s*)/)?.[1] || ''\n let indentLevel = 0\n \n if (indentInfo.type === 'tab') {\n indentLevel = leadingWhitespace.split('\\t').length - 1\n } else {\n // Count spaces, grouping by the detected space width\n const spaceWidth = indentInfo.width / (fontSize * 0.6) // Convert back to space count\n indentLevel = Math.floor(leadingWhitespace.length / spaceWidth)\n }\n \n processedLines.push({\n text: line.trim(),\n indentLevel,\n originalLine: line\n })\n }\n \n // Wrap each processed line separately to preserve line breaks and indentation\n const wrappedLines: { text: string; indentLevel: number; isContinuation: boolean }[] = []\n const contentW = maxTextWidth() - paddingX * 2\n \n for (const processedLine of processedLines) {\n if (processedLine.text.length === 0) {\n // Empty line - preserve as empty line\n wrappedLines.push({\n text: '',\n indentLevel: processedLine.indentLevel,\n isContinuation: false\n })\n } else {\n const parts = wrapText(processedLine.text, codeFont, fontSize, contentW)\n for (let i = 0; i < parts.length; i++) {\n wrappedLines.push({\n text: parts[i],\n indentLevel: processedLine.indentLevel,\n isContinuation: i > 0\n })\n }\n }\n }\n \n const totalHeight = wrappedLines.length * lineHeight + paddingY * 2\n var remainingHeight = totalHeight\n y -= paddingY\n \n for (const wrappedLine of wrappedLines) {\n let pageAdded = ensureSpace(lineHeight + paddingY)\n if (pageAdded || remainingHeight == totalHeight) {\n let blockHeight = Math.floor(Math.min(remainingHeight, y - marginBottom - paddingY) / lineHeight) * lineHeight\n page.drawRectangle({\n x: marginLeft,\n y: y + fontSize,\n width: maxTextWidth(),\n height: -blockHeight - paddingY * 2,\n color: background,\n })\n remainingHeight -= blockHeight\n y -= paddingY\n }\n \n // Calculate indentation offset\n const indentOffset = wrappedLine.indentLevel * indentInfo.width\n \n page.drawText(wrappedLine.text, {\n x: marginLeft + paddingX + indentOffset,\n y: y,\n size: fontSize,\n font: codeFont,\n color: color,\n })\n y -= lineHeight\n }\n y -= paddingY\n }\n\n // Render by block format\n switch (block.format) {\n case FormatTypes.HEADER_1:\n case FormatTypes.HEADER_2:\n case FormatTypes.HEADER_3:\n case FormatTypes.HEADER_4:\n case FormatTypes.HEADER_5:\n case FormatTypes.HEADER_6: {\n const align = (block as any).metadata?.align as 'left' | 'center' | 'right' | undefined\n drawHeading(String(block.content), align)\n break\n }\n case FormatTypes.BULLET: {\n const items = Array.isArray(block.content) ? block.content.map(String) : [String(block.content)]\n drawBulletList(items)\n break\n }\n case FormatTypes.NUMBERED: {\n const items = Array.isArray(block.content) ? block.content.map(String) : [String(block.content)]\n drawNumberedList(items)\n break\n }\n case FormatTypes.QUOTE: {\n drawQuote(String(block.content))\n break\n }\n case FormatTypes.CODE_BLOCK: {\n const lines = Array.isArray(block.content) ? block.content.map(String) : String(block.content).split('\\n')\n drawCodeBlock(lines)\n break\n }\n default: {\n if (typeof block.content === 'string') {\n drawParagraph(block.content)\n } else {\n for (const c of block.content) {\n drawParagraph(String(c))\n }\n }\n }\n }\n logger.info(`createPdf: Successfully processed block ${i + 1}`);\n y -= paragraphSpacing\n lastLineHeight = lineHeight\n } catch (blockError) {\n logger.error(`createPdf: Error processing block ${i + 1}: ${blockError}`);\n throw blockError;\n }\n }\n\n logger.info('createPdf: About to save PDF document');\n const pdfBytes = await pdfDoc.save()\n logger.info(`createPdf: PDF saved successfully, bytes length: ${pdfBytes.length}`);\n return pdfBytes\n } catch (error) {\n logger.error(`createPdf: Error during PDF creation: ${error}`);\n throw error;\n }\n}\n"],"names":[],"mappings":"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","debug_id":"9776dcc6-8195-5fbe-ace3-f75538ae087a"}
|
|
@@ -7,9 +7,9 @@ export declare function sendNotification(receiver: string, data: notificationDat
|
|
|
7
7
|
title: string;
|
|
8
8
|
content: string;
|
|
9
9
|
createdAt: Date;
|
|
10
|
+
read: boolean;
|
|
10
11
|
senderId: string | null;
|
|
11
12
|
receiverId: string;
|
|
12
|
-
read: boolean;
|
|
13
13
|
}>;
|
|
14
14
|
export declare function sendNotifications(receiverIds: Array<string>, data: notificationData): Promise<import(".prisma/client").Prisma.BatchPayload>;
|
|
15
15
|
export declare function markRead(id: string, read?: boolean): Promise<{
|
|
@@ -17,9 +17,9 @@ export declare function markRead(id: string, read?: boolean): Promise<{
|
|
|
17
17
|
title: string;
|
|
18
18
|
content: string;
|
|
19
19
|
createdAt: Date;
|
|
20
|
+
read: boolean;
|
|
20
21
|
senderId: string | null;
|
|
21
22
|
receiverId: string;
|
|
22
|
-
read: boolean;
|
|
23
23
|
}>;
|
|
24
24
|
export {};
|
|
25
25
|
//# sourceMappingURL=notificationHandler.d.ts.map
|
package/dist/lib/prisma.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PrismaClient } from '@prisma/client';
|
|
2
|
-
declare const prismaClientSingleton: () => PrismaClient<import(".prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
|
|
2
|
+
declare const prismaClientSingleton: () => PrismaClient<import(".prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library.js").DefaultArgs>;
|
|
3
3
|
declare global {
|
|
4
4
|
var prisma: undefined | ReturnType<typeof prismaClientSingleton>;
|
|
5
5
|
}
|
|
6
|
-
export declare const prisma: PrismaClient<import(".prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
|
|
6
|
+
export declare const prisma: PrismaClient<import(".prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library.js").DefaultArgs>;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=prisma.d.ts.map
|
package/dist/lib/prisma.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.d.ts","sourceRoot":"/","sources":["lib/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"prisma.d.ts","sourceRoot":"/","sources":["lib/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAc9C,QAAA,MAAM,qBAAqB,yIAO1B,CAAC;AAGF,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;CAClE;AAED,eAAO,MAAM,MAAM,mIAA+C,CAAC"}
|
package/dist/lib/prisma.js
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ccd03fae-35bf-58da-b672-e834ceba3cc9")}catch(e){}}();
|
|
3
3
|
import { PrismaClient } from '@prisma/client';
|
|
4
|
+
import { env } from './config/env.js';
|
|
5
|
+
const getLogLevel = () => {
|
|
6
|
+
switch (env.NODE_ENV) {
|
|
7
|
+
case 'development':
|
|
8
|
+
return ['query', 'error', 'warn'];
|
|
9
|
+
case 'production':
|
|
10
|
+
return ['error'];
|
|
11
|
+
default:
|
|
12
|
+
return ['error'];
|
|
13
|
+
}
|
|
14
|
+
};
|
|
4
15
|
const prismaClientSingleton = () => {
|
|
16
|
+
// return new PrismaClient({
|
|
17
|
+
// log: env.NODE_ENV === 'development'
|
|
18
|
+
// ? ['query', 'error', 'warn']
|
|
19
|
+
// : ['error'],
|
|
20
|
+
// });
|
|
5
21
|
return new PrismaClient();
|
|
6
22
|
};
|
|
7
23
|
export const prisma = globalThis.prisma ?? prismaClientSingleton();
|
|
8
|
-
if (
|
|
24
|
+
if (env.NODE_ENV !== 'production') {
|
|
9
25
|
globalThis.prisma = prisma;
|
|
10
26
|
}
|
|
27
|
+
process.on('beforeExit', async () => {
|
|
28
|
+
await prisma.$disconnect();
|
|
29
|
+
});
|
|
11
30
|
//# sourceMappingURL=prisma.js.map
|
|
12
|
-
//# debugId=
|
|
31
|
+
//# debugId=ccd03fae-35bf-58da-b672-e834ceba3cc9
|
package/dist/lib/prisma.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.js","sources":["lib/prisma.ts"],"sourceRoot":"/","sourcesContent":["import { PrismaClient } from '@prisma/client';\n\nconst prismaClientSingleton = () => {\n return new PrismaClient();\n};\n\n// Prevent multiple instances of Prisma Client in development\ndeclare global {\n var prisma: undefined | ReturnType<typeof prismaClientSingleton>;\n}\n\nexport const prisma = globalThis.prisma ?? prismaClientSingleton();\n\nif (
|
|
1
|
+
{"version":3,"file":"prisma.js","sources":["lib/prisma.ts"],"sourceRoot":"/","sourcesContent":["import { PrismaClient } from '@prisma/client';\nimport { env } from './config/env.js';\n\nconst getLogLevel = () => {\n switch (env.NODE_ENV) {\n case 'development':\n return ['query', 'error', 'warn'];\n case 'production':\n return ['error'];\n default:\n return ['error'];\n }\n}\n\nconst prismaClientSingleton = () => {\n // return new PrismaClient({\n // log: env.NODE_ENV === 'development' \n // ? ['query', 'error', 'warn'] \n // : ['error'],\n // });\n return new PrismaClient();\n};\n\n// Prevent multiple instances of Prisma Client in development\ndeclare global {\n var prisma: undefined | ReturnType<typeof prismaClientSingleton>;\n}\n\nexport const prisma = globalThis.prisma ?? prismaClientSingleton();\n\nif (env.NODE_ENV !== 'production') {\n globalThis.prisma = prisma;\n}\n\nprocess.on('beforeExit', async () => {\n await prisma.$disconnect();\n});"],"names":[],"mappings":";;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,QAAQ,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,KAAK,aAAa;YAChB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACpC,KAAK,YAAY;YACf,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB;YACE,OAAO,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,4BAA4B;IAC5B,yCAAyC;IACzC,oCAAoC;IACpC,mBAAmB;IACnB,MAAM;IACN,OAAO,IAAI,YAAY,EAAE,CAAC;AAC5B,CAAC,CAAC;AAOF,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,qBAAqB,EAAE,CAAC;AAEnE,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;IAClC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;AAC7B,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAClC,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC","debug_id":"ccd03fae-35bf-58da-b672-e834ceba3cc9"}
|
package/dist/lib/pusher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pusher.d.ts","sourceRoot":"/","sources":["lib/pusher.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"pusher.d.ts","sourceRoot":"/","sources":["lib/pusher.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,QAAA,MAAM,MAAM,QAMV,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
package/dist/lib/pusher.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4fc6ef55-beda-5c75-a279-6fedc755b1a6")}catch(e){}}();
|
|
3
3
|
import Pusher from 'pusher';
|
|
4
|
+
import { env } from './config/env.js';
|
|
4
5
|
const pusher = new Pusher({
|
|
5
|
-
appId:
|
|
6
|
-
key:
|
|
7
|
-
secret:
|
|
8
|
-
cluster:
|
|
9
|
-
useTLS:
|
|
6
|
+
appId: env.PUSHER_APP_ID,
|
|
7
|
+
key: env.PUSHER_KEY,
|
|
8
|
+
secret: env.PUSHER_SECRET,
|
|
9
|
+
cluster: env.PUSHER_CLUSTER,
|
|
10
|
+
useTLS: env.NODE_ENV !== 'development',
|
|
10
11
|
});
|
|
11
12
|
export { pusher };
|
|
12
13
|
//# sourceMappingURL=pusher.js.map
|
|
13
|
-
//# debugId=
|
|
14
|
+
//# debugId=4fc6ef55-beda-5c75-a279-6fedc755b1a6
|
package/dist/lib/pusher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pusher.js","sources":["lib/pusher.ts"],"sourceRoot":"/","sourcesContent":["import Pusher from 'pusher';\n\nconst pusher = new Pusher({\n appId:
|
|
1
|
+
{"version":3,"file":"pusher.js","sources":["lib/pusher.ts"],"sourceRoot":"/","sourcesContent":["import Pusher from 'pusher';\nimport { env } from './config/env.js';\n\nconst pusher = new Pusher({\n appId: env.PUSHER_APP_ID,\n key: env.PUSHER_KEY,\n secret: env.PUSHER_SECRET,\n cluster: env.PUSHER_CLUSTER,\n useTLS: env.NODE_ENV !== 'development',\n});\n\nexport { pusher };\n"],"names":[],"mappings":";;AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;IACxB,KAAK,EAAE,GAAG,CAAC,aAAa;IACxB,GAAG,EAAE,GAAG,CAAC,UAAU;IACnB,MAAM,EAAE,GAAG,CAAC,aAAa;IACzB,OAAO,EAAE,GAAG,CAAC,cAAc;IAC3B,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,aAAa;CACvC,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC","debug_id":"4fc6ef55-beda-5c75-a279-6fedc755b1a6"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["middleware/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["middleware/auth.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,GAAI,GAAG,GAAG;;;;;CAwL1C,CAAC"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7e5add7d-c587-57c6-9421-9156e6363492")}catch(e){}}();
|
|
3
3
|
import { TRPCError } from '@trpc/server';
|
|
4
4
|
import { prisma } from '../lib/prisma.js';
|
|
5
|
+
import * as Sentry from "@sentry/node";
|
|
5
6
|
export const createAuthMiddleware = (t) => {
|
|
6
7
|
// Auth middleware
|
|
7
8
|
const isAuthed = t.middleware(async ({ next, ctx }) => {
|
|
@@ -45,10 +46,10 @@ export const createAuthMiddleware = (t) => {
|
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
catch (error) {
|
|
48
|
-
|
|
49
|
+
Sentry.captureException(error);
|
|
49
50
|
throw new TRPCError({
|
|
50
|
-
code: '
|
|
51
|
-
message: '
|
|
51
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
52
|
+
message: 'Internal server error',
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
});
|
|
@@ -166,4 +167,4 @@ export const createAuthMiddleware = (t) => {
|
|
|
166
167
|
};
|
|
167
168
|
};
|
|
168
169
|
//# sourceMappingURL=auth.js.map
|
|
169
|
-
//# debugId=
|
|
170
|
+
//# debugId=7e5add7d-c587-57c6-9421-9156e6363492
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sources":["middleware/auth.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from '@trpc/server';\nimport { prisma } from '../lib/prisma.js';\nimport type { MiddlewareContext } from '../types/trpc.js';\n\nexport const createAuthMiddleware = (t: any) => {\n\n // Auth middleware\n const isAuthed = t.middleware(async ({ next, ctx }: MiddlewareContext) => {\n const startTime = Date.now();\n // Get user from request headers\n const userHeader = ctx.req.headers['x-user'];\n\n if (!userHeader) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Not authenticated - no token found',\n });\n }\n\n try {\n const token = typeof userHeader === 'string' ? userHeader : userHeader[0];\n\n // Find user by session token\n const user = await prisma.user.findFirst({\n where: {\n sessions: {\n some: {\n id: token\n }\n }\n },\n select: {\n id: true,\n username: true,\n // institutionId: true,\n }\n });\n\n if (!user) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Invalid or expired session',\n });\n }\n\n return next({\n ctx: {\n ...ctx,\n user,\n },\n });\n } catch (error) {\n
|
|
1
|
+
{"version":3,"file":"auth.js","sources":["middleware/auth.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from '@trpc/server';\nimport { prisma } from '../lib/prisma.js';\nimport type { MiddlewareContext } from '../types/trpc.js';\nimport * as Sentry from \"@sentry/node\";\n\nexport const createAuthMiddleware = (t: any) => {\n\n // Auth middleware\n const isAuthed = t.middleware(async ({ next, ctx }: MiddlewareContext) => {\n const startTime = Date.now();\n // Get user from request headers\n const userHeader = ctx.req.headers['x-user'];\n\n if (!userHeader) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Not authenticated - no token found',\n });\n }\n\n try {\n const token = typeof userHeader === 'string' ? userHeader : userHeader[0];\n\n // Find user by session token\n const user = await prisma.user.findFirst({\n where: {\n sessions: {\n some: {\n id: token\n }\n }\n },\n select: {\n id: true,\n username: true,\n // institutionId: true,\n }\n });\n\n if (!user) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Invalid or expired session',\n });\n }\n\n return next({\n ctx: {\n ...ctx,\n user,\n },\n });\n } catch (error) {\n Sentry.captureException(error);\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Internal server error',\n });\n }\n });\n\n // Add computed flags middleware\n const addComputedFlags = t.middleware(async ({ next, ctx }: MiddlewareContext) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Not authenticated',\n });\n }\n\n // Get all classes where user is a teacher\n const teacherClasses = await prisma.class.findMany({\n where: {\n teachers: {\n some: {\n id: ctx.user.id\n }\n }\n },\n select: {\n id: true\n }\n });\n\n return next({\n ctx: {\n ...ctx,\n isTeacher: teacherClasses.length > 0,\n teacherClassIds: teacherClasses.map((c: { id: string }) => c.id)\n }\n });\n });\n\n // Student middleware\n const isMemberInClass = t.middleware(async ({ next, ctx, input }: MiddlewareContext) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Not authenticated',\n });\n }\n\n const classId = (input as { classId: string })?.classId;\n\n if (!classId) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'classId is required',\n });\n }\n\n const isMember = await prisma.class.findFirst({\n where: {\n id: classId,\n OR: [\n {\n students: {\n some: {\n id: ctx.user.id\n }\n }\n },\n {\n teachers: {\n some: {\n id: ctx.user.id\n }\n }\n }\n ]\n }\n });\n\n if (!isMember) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Not a member in this class',\n });\n }\n\n return next();\n });\n\n // Teacher middleware\n const isTeacherInClass = t.middleware(async ({ next, ctx, input }: MiddlewareContext) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: 'UNAUTHORIZED',\n message: 'Not authenticated',\n });\n }\n\n const classId = input.classId;\n if (!classId) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'classId is required',\n });\n }\n\n const isTeacher = await prisma.class.findFirst({\n where: {\n id: classId,\n teachers: {\n some: {\n id: ctx.user.id\n }\n }\n }\n });\n\n\n\n if (!isTeacher) {\n throw new TRPCError({\n code: 'FORBIDDEN',\n message: 'Not a teacher in this class',\n });\n }\n\n return next();\n });\n\n return {\n isAuthed,\n addComputedFlags,\n isMemberInClass,\n isTeacherInClass,\n };\n}; "],"names":[],"mappings":"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","debug_id":"7e5add7d-c587-57c6-9421-9156e6363492"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const generalLimiter: import("express-rate-limit").RateLimitRequestHandler;
|
|
2
|
+
export declare const authLimiter: import("express-rate-limit").RateLimitRequestHandler;
|
|
3
|
+
export declare const uploadLimiter: import("express-rate-limit").RateLimitRequestHandler;
|
|
4
|
+
export declare const helmetConfig: (req: import("http").IncomingMessage, res: import("http").ServerResponse, next: (err?: unknown) => void) => void;
|
|
5
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"/","sources":["middleware/security.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,cAAc,sDAWzB,CAAC;AAGH,eAAO,MAAM,WAAW,sDAQtB,CAAC;AAGH,eAAO,MAAM,aAAa,sDAOxB,CAAC;AAGH,eAAO,MAAM,YAAY,sFAwBgoF,CAAC,2BAAxpF,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0f60691e-ceb3-5826-8b1f-3c48b166d0fc")}catch(e){}}();
|
|
3
|
+
import helmet from 'helmet';
|
|
4
|
+
import rateLimit from 'express-rate-limit';
|
|
5
|
+
const isDevelopment = process.env.NODE_ENV === 'development';
|
|
6
|
+
// Custom handler for rate limit errors that returns JSON
|
|
7
|
+
// This format can be intercepted on the frontend with:
|
|
8
|
+
// error.data?.code === 'TOO_MANY_REQUESTS' || error.data?.httpStatus === 429
|
|
9
|
+
const rateLimitHandler = (req, res) => {
|
|
10
|
+
// Return JSON structure that can be intercepted on frontend with:
|
|
11
|
+
// error.data?.code === 'TOO_MANY_REQUESTS' || error.data?.httpStatus === 429
|
|
12
|
+
// When tRPC wraps this, the response body becomes error.data, so we put code/httpStatus at top level
|
|
13
|
+
res.status(429).json({
|
|
14
|
+
code: 'TOO_MANY_REQUESTS',
|
|
15
|
+
message: 'Too many requests, please try again later.',
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
// General API rate limiter - applies to all routes
|
|
19
|
+
export const generalLimiter = rateLimit({
|
|
20
|
+
windowMs: 10 * 60 * 1000, // 10 minutes
|
|
21
|
+
max: 100, // Limit each IP to 100 requests per windowMs
|
|
22
|
+
message: 'Too many requests from this IP, please try again later.',
|
|
23
|
+
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
|
|
24
|
+
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
|
|
25
|
+
handler: rateLimitHandler,
|
|
26
|
+
skip: (req) => {
|
|
27
|
+
// Skip rate limiting for health checks
|
|
28
|
+
return req.path === '/health';
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
// Stricter rate limiter for authentication endpoints
|
|
32
|
+
export const authLimiter = rateLimit({
|
|
33
|
+
windowMs: 5 * 60 * 1000, // 5 minutes
|
|
34
|
+
max: 5, // Limit each IP to 5 login attempts per windowMs
|
|
35
|
+
message: 'Too many authentication attempts, please try again later.',
|
|
36
|
+
standardHeaders: true,
|
|
37
|
+
legacyHeaders: false,
|
|
38
|
+
skipSuccessfulRequests: true, // Don't count successful requests
|
|
39
|
+
handler: rateLimitHandler,
|
|
40
|
+
});
|
|
41
|
+
// File upload rate limiter
|
|
42
|
+
export const uploadLimiter = rateLimit({
|
|
43
|
+
windowMs: 30 * 60 * 1000, // 30 minutes
|
|
44
|
+
max: 50, // Limit each IP to 50 uploads per hour
|
|
45
|
+
message: 'Too many file uploads, please try again later.',
|
|
46
|
+
standardHeaders: true,
|
|
47
|
+
legacyHeaders: false,
|
|
48
|
+
handler: rateLimitHandler,
|
|
49
|
+
});
|
|
50
|
+
// Helmet configuration
|
|
51
|
+
export const helmetConfig = helmet({
|
|
52
|
+
contentSecurityPolicy: {
|
|
53
|
+
directives: {
|
|
54
|
+
defaultSrc: ["'self'"],
|
|
55
|
+
styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles for tRPC panel
|
|
56
|
+
// Allow inline scripts only in development (for tRPC panel)
|
|
57
|
+
// In production, keep strict CSP without unsafe-inline
|
|
58
|
+
scriptSrc: isDevelopment
|
|
59
|
+
? ["'self'", "'unsafe-inline'"]
|
|
60
|
+
: ["'self'"],
|
|
61
|
+
imgSrc: ["'self'", "data:", "https:"], // Allow images from any HTTPS source
|
|
62
|
+
connectSrc: ["'self'", "https://*.sentry.io"], // Allow Sentry connections
|
|
63
|
+
fontSrc: ["'self'", "data:"],
|
|
64
|
+
objectSrc: ["'none'"],
|
|
65
|
+
mediaSrc: ["'self'"],
|
|
66
|
+
frameSrc: ["'none'"],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
crossOriginEmbedderPolicy: false, // Disable if you need to embed resources
|
|
70
|
+
hsts: {
|
|
71
|
+
maxAge: 31536000, // 1 year
|
|
72
|
+
includeSubDomains: true,
|
|
73
|
+
preload: true,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=security.js.map
|
|
77
|
+
//# debugId=0f60691e-ceb3-5826-8b1f-3c48b166d0fc
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sources":["middleware/security.ts"],"sourceRoot":"/","sourcesContent":["import helmet from 'helmet';\nimport rateLimit from 'express-rate-limit';\nimport type { Request, Response } from 'express';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\n// Custom handler for rate limit errors that returns JSON\n// This format can be intercepted on the frontend with:\n// error.data?.code === 'TOO_MANY_REQUESTS' || error.data?.httpStatus === 429\nconst rateLimitHandler = (req: Request, res: Response) => {\n // Return JSON structure that can be intercepted on frontend with:\n // error.data?.code === 'TOO_MANY_REQUESTS' || error.data?.httpStatus === 429\n // When tRPC wraps this, the response body becomes error.data, so we put code/httpStatus at top level\n res.status(429).json({\n code: 'TOO_MANY_REQUESTS',\n message: 'Too many requests, please try again later.',\n });\n};\n\n// General API rate limiter - applies to all routes\nexport const generalLimiter = rateLimit({\n windowMs: 10 * 60 * 1000, // 10 minutes\n max: 100, // Limit each IP to 100 requests per windowMs\n message: 'Too many requests from this IP, please try again later.',\n standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers\n legacyHeaders: false, // Disable the `X-RateLimit-*` headers\n handler: rateLimitHandler,\n skip: (req) => {\n // Skip rate limiting for health checks\n return req.path === '/health';\n },\n});\n\n// Stricter rate limiter for authentication endpoints\nexport const authLimiter = rateLimit({\n windowMs: 5 * 60 * 1000, // 5 minutes\n max: 5, // Limit each IP to 5 login attempts per windowMs\n message: 'Too many authentication attempts, please try again later.',\n standardHeaders: true,\n legacyHeaders: false,\n skipSuccessfulRequests: true, // Don't count successful requests\n handler: rateLimitHandler,\n});\n\n// File upload rate limiter\nexport const uploadLimiter = rateLimit({\n windowMs: 30 * 60 * 1000, // 30 minutes\n max: 50, // Limit each IP to 50 uploads per hour\n message: 'Too many file uploads, please try again later.',\n standardHeaders: true,\n legacyHeaders: false,\n handler: rateLimitHandler,\n});\n\n// Helmet configuration\nexport const helmetConfig = helmet({\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"], // Allow inline styles for tRPC panel\n // Allow inline scripts only in development (for tRPC panel)\n // In production, keep strict CSP without unsafe-inline\n scriptSrc: isDevelopment \n ? [\"'self'\", \"'unsafe-inline'\"] \n : [\"'self'\"],\n imgSrc: [\"'self'\", \"data:\", \"https:\"], // Allow images from any HTTPS source\n connectSrc: [\"'self'\", \"https://*.sentry.io\"], // Allow Sentry connections\n fontSrc: [\"'self'\", \"data:\"],\n objectSrc: [\"'none'\"],\n mediaSrc: [\"'self'\"],\n frameSrc: [\"'none'\"],\n },\n },\n crossOriginEmbedderPolicy: false, // Disable if you need to embed resources\n hsts: {\n maxAge: 31536000, // 1 year\n includeSubDomains: true,\n preload: true,\n },\n});"],"names":[],"mappings":";;AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAG3C,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;AAE7D,yDAAyD;AACzD,uDAAuD;AACvD,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IACvD,kEAAkE;IAClE,6EAA6E;IAC7E,qGAAqG;IACrG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,4CAA4C;KACtD,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,mDAAmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC;IACtC,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACvC,GAAG,EAAE,GAAG,EAAE,6CAA6C;IACvD,OAAO,EAAE,yDAAyD;IAClE,eAAe,EAAE,IAAI,EAAE,sDAAsD;IAC7E,aAAa,EAAE,KAAK,EAAE,sCAAsC;IAC5D,OAAO,EAAE,gBAAgB;IACzB,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;QACZ,uCAAuC;QACvC,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC;IAChC,CAAC;CACF,CAAC,CAAC;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;IACnC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IACrC,GAAG,EAAE,CAAC,EAAE,iDAAiD;IACzD,OAAO,EAAE,2DAA2D;IACpE,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,KAAK;IACpB,sBAAsB,EAAE,IAAI,EAAE,kCAAkC;IAChE,OAAO,EAAE,gBAAgB;CAC1B,CAAC,CAAC;AAEH,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACvC,GAAG,EAAE,EAAE,EAAE,uCAAuC;IAChD,OAAO,EAAE,gDAAgD;IACzD,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,KAAK;IACpB,OAAO,EAAE,gBAAgB;CAC1B,CAAC,CAAC;AAEH,uBAAuB;AACvB,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;IACjC,qBAAqB,EAAE;QACrB,UAAU,EAAE;YACV,UAAU,EAAE,CAAC,QAAQ,CAAC;YACtB,QAAQ,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC,EAAE,qCAAqC;YAC9E,4DAA4D;YAC5D,uDAAuD;YACvD,SAAS,EAAE,aAAa;gBACtB,CAAC,CAAC,CAAC,QAAQ,EAAE,iBAAiB,CAAC;gBAC/B,CAAC,CAAC,CAAC,QAAQ,CAAC;YACd,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,qCAAqC;YAC5E,UAAU,EAAE,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EAAE,2BAA2B;YAC1E,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;YAC5B,SAAS,EAAE,CAAC,QAAQ,CAAC;YACrB,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;IACD,yBAAyB,EAAE,KAAK,EAAE,yCAAyC;IAC3E,IAAI,EAAE;QACJ,MAAM,EAAE,QAAQ,EAAE,SAAS;QAC3B,iBAAiB,EAAE,IAAI;QACvB,OAAO,EAAE,IAAI;KACd;CACF,CAAC,CAAC","debug_id":"0f60691e-ceb3-5826-8b1f-3c48b166d0fc"}
|