{"version":3,"file":"js/application-79872c6b30184efdab38.js","mappings":"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","sources":["webpack://tyb/./app/javascript/store/index.js","webpack://tyb/./app/javascript/bundles/HelloWorld/components/HelloWorld.jsx","webpack://tyb/./app/javascript/startup/routes.jsx","webpack://tyb/./app/javascript/startup/HelloWorldApp.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/ImageSection.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/StoryTellingChat.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/MessageInput.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/UserMessage.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/AssistantMessage.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/Message.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/Spinner.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/LanguageLearningPrompts.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/World.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/ParentMemoryChat.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/Chat.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/ChatList.jsx","webpack://tyb/./app/javascript/bundles/Chat/components/ImageCreation.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/useInfiniteImageLoad.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/ImageGrid.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/ImageMosaic.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/StripeWrapper.jsx","webpack://tyb/./app/javascript/bundles/Words/components/WordList.jsx","webpack://tyb/./app/javascript/bundles/Words/components/WordTest.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/LogrocketWrapper.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/UsernameValidator.jsx","webpack://tyb/./app/javascript/bundles/Shared/components/MemoryForm.jsx","webpack://tyb/./app/javascript/bundles/LearningWorld/components/GameCanvas.jsx","webpack://tyb/./app/javascript/bundles/LearningWorld/components/Instructions.jsx","webpack://tyb/./app/javascript/bundles/LearningWorld/hooks/useGameState.js","webpack://tyb/./app/javascript/bundles/LearningWorld/components/LearningWorld.jsx","webpack://tyb/./app/javascript/bundles/LearningWorld/hooks/useModules.js","webpack://tyb/./app/javascript/bundles/LearningWorld/hooks/useAvatar.js","webpack://tyb/./app/javascript/channels/consumer.js","webpack://tyb/./app/javascript/channels/coin_channel.js","webpack://tyb/./app/javascript/bundles/CoinDisplay/components/CoinDisplay.jsx","webpack://tyb/./app/javascript/packs/application.js","webpack://tyb/./app/javascript/packs/listeners.js"],"sourcesContent":["import { create } from \"zustand\";\n\nexport const useCounterStore = create((set) => ({\n count: 0,\n add: () => set((state) => ({ count: state.count + 1 })),\n subtract: () => set((state) => ({ count: state.count - 1 })),\n}));\n\nexport const useChatStore = create((set) => ({\n chat: null,\n fetch: async () => {\n const response = await fetch(\"https://api.github.com/orgs/nodejs\");\n set({ chat: await response.json() });\n },\n}));\n","import PropTypes from 'prop-types';\nimport React, { useEffect, useState } from 'react';\nimport { FaPlus, FaMinus } from 'react-icons/fa';\nimport { useCounterStore, useChatStore } from '../../../store';\n\nconst HelloWorld = (props) => {\n const [name, setName] = useState(props.name);\n const { count, add, subtract } = useCounterStore((state) => state);\n const chat = useChatStore((state) => state);\n useEffect(() => {\n chat.fetch();\n }, []);\n\n return (\n
\n

github api example:

\n {chat.chat && (\n \n )}\n {chat.chat && chat.chat.login}\n
\n
\n

State management example:

\n
\n subtract()}\n >\n \n Subtract\n \n {count}\n \n \n Add\n \n
\n \n
\n
\n );\n};\n\nHelloWorld.propTypes = {\n name: PropTypes.string.isRequired, // this is passed from the Rails view\n title: PropTypes.string.isRequired, // this is passed from the Rails view\n};\n\nexport default HelloWorld;\n","import React from 'react';\nimport { Route, Routes } from 'react-router-dom';\n\nexport default (\n
\n \n page \"/\"
} />\n page \"/test\"} />\n \n \n);\n","import React from'react'\nimport {\n BrowserRouter,\n Routes,\n Route,\n Link,\n useNavigate\n} from \"react-router-dom\";\nimport routes from './routes.jsx'\nimport {BsArrowLeft} from \"react-icons/bs\";\nimport HelloWorld from '../bundles/HelloWorld/components/HelloWorld.jsx';\n\nconst GoBackSection = () => {\n return
\n \n \n Go back\n \n
\n}\n\nconst RouterApp = (props, railsContext) => {\n return (\n \n \n \n
\n

About Our School

\n

Hello world Component:

\n \n

\n Our school is dedicated to providing a nurturing environment where kids can learn, play, and thrive.\n We believe in a balanced approach to education, combining academic excellence with fun activities.\n

\n
\n
\n

Activities

\n
    \n SPA navigation:\n
  • \n home
  • \n
  • \n about
  • \n
  • \n services
  • \n
  • \n contact
  • \n
\n
\n
\n

Contact Us

\n

\n Have questions? Reach out to us at{' '}\n \n info@schoolapp.com\n \n .\n

\n
\n \n } />\n \n \n

ABOUT SECTION

\n \n } />\n
\n
\n );\n};\n\nexport default RouterApp","import React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\n\nconst ImageSection = ({ imageId, image, formToken, chatId }) => {\n const [imageUrl, setImageUrl] = useState(image);\n const [loading, setLoading] = useState(!image);\n\n useEffect(() => {\n if (!imageUrl) {\n // Function to fetch image using the prompt\n const fetchImage = async () => {\n try {\n setLoading(true);\n const response = await axios.post(\n `/api/v1/chats/${chatId}/generate_image`,\n { chat_image_id: imageId },\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n },\n }\n );\n setImageUrl(response.data.imageUrl);\n } catch (error) {\n console.error(\"Error generating image:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n fetchImage();\n }\n }, [imageUrl, imageId, formToken, chatId]);\n\n return (\n
\n {loading ? (\n
\n ) : (\n \"Story\n )}\n
\n );\n};\n\nexport default ImageSection;\n","import React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\nimport ImageSection from \"./ImageSection\";\n\nconst StoryTellingChat = ({ formToken, onSaveChat, chatId, chatStory }) => {\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [storyParts, setStoryParts] = useState(chatStory?.storyParts || []);\n const [chatStoryId, setChatStoryId] = useState(chatStory?.id || null);\n const [userPrompt, setUserPrompt] = useState(chatStory?.prompt || '');\n const [audioStatus, setAudioStatus] = useState({});\n\n const handleSendStoryPrompt = async (prompt) => {\n setIsSubmitting(true);\n setUserPrompt(prompt);\n try {\n const queryParams = new URLSearchParams({ prompt }).toString();\n\n const response = await axios.post(\n `/api/v1/chats/${chatId}/tell_story?${queryParams}`,\n {},\n {\n headers: {\n \"Authorization\": `Bearer ${formToken}`,\n },\n }\n );\n setChatStoryId(response.data.id);\n const storySegments = response.data.sections;\n setStoryParts(storySegments);\n onSaveChat();\n } catch (error) {\n console.error(\"Error generating story:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const handleGenerateAudio = async (messageId) => {\n setAudioStatus(prev => ({ ...prev, [messageId]: 'generating' }));\n try {\n const response = await axios.post(\n `/api/v1/chat_story_sections/${messageId}/generate_audio`,\n {},\n {\n headers: {\n \"Authorization\": `Bearer ${formToken}`,\n },\n }\n );\n setAudioStatus(prev => ({ ...prev, [messageId]: 'ready' }));\n // Refresh the story parts to get the updated audio URL\n const updatedStoryParts = storyParts.map(part => \n part.id === messageId ? { ...part, audioUrl: response.data.audio_url } : part\n );\n setStoryParts(updatedStoryParts);\n } catch (error) {\n console.error(\"Error generating audio:\", error);\n setAudioStatus(prev => ({ ...prev, [messageId]: 'error' }));\n }\n };\n\n useEffect(() => {\n if (chatStory) {\n setStoryParts(chatStory.storyParts.map(part => ({\n ...part,\n audioUrl: part.audioUrl || null // Ensure audioUrl is set, even if it's null\n })));\n setChatStoryId(chatStory.id);\n setUserPrompt(chatStory.prompt);\n \n // Set initial audio status for parts with existing audio\n const initialAudioStatus = {};\n chatStory.storyParts.forEach(part => {\n initialAudioStatus[part.id] = part.audioUrl ? 'ready' : 'not_generated';\n });\n setAudioStatus(initialAudioStatus);\n }\n }, [chatStory]);\n\n return (\n
\n {!storyParts.length && (\n
\n {\n e.preventDefault();\n const prompt = e.target.prompt.value;\n handleSendStoryPrompt(prompt);\n }}\n className=\"w-full bg-white rounded-lg shadow-md p-6\"\n >\n \n \n \n {isSubmitting ? \"Generating Story...\" : \"Submit\"}\n \n \n
\n )}\n\n {storyParts.length > 0 && (\n
\n
\n

Original Question:

\n

{userPrompt}

\n
\n {storyParts.map((part, index) => (\n
\n

{part.content}

\n
\n {part.audioUrl ? (\n
\n \n
\n ))}\n
\n )}\n
\n );\n};\n\nexport default StoryTellingChat;\n","import React, { useState, useRef, useEffect } from \"react\";\nimport { HiOutlinePaperClip } from \"react-icons/hi2\";\nimport { IoMdCloseCircle } from \"react-icons/io\";\nimport { FaArrowAltCircleUp } from \"react-icons/fa\";\n\nconst MessageInput = ({ handleSubmit, input, setInput, handleFileChange, showWork, messageCount = 0, disabled }) => {\n const [filePreview, setFilePreview] = useState(null);\n const [errorMessage, setErrorMessage] = useState(\"\");\n const [isCameraActive, setIsCameraActive] = useState(false);\n const textareaRef = useRef(null);\n const videoRef = useRef(null);\n const canvasRef = useRef(null);\n\n useEffect(() => {\n if (isCameraActive) {\n startCamera();\n }\n }, [isCameraActive]);\n\n const adjustHeight = () => {\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;\n }\n };\n\n useEffect(() => {\n adjustHeight();\n }, [input]);\n\n const handleFileChangeInternal = (file) => {\n if (file) {\n const fileType = file.type;\n if (fileType === \"image/png\" || fileType === \"image/jpeg\") {\n const reader = new FileReader();\n reader.onloadend = () => {\n setFilePreview(reader.result);\n };\n reader.readAsDataURL(file);\n handleFileChange(file);\n setErrorMessage(\"\");\n } else {\n setErrorMessage(\"Only PNG and JPG files are allowed.\");\n }\n }\n };\n\n const startCamera = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n video: {\n facingMode: { ideal: \"environment\" },\n }\n });\n if (videoRef.current) {\n videoRef.current.srcObject = stream;\n videoRef.current.play();\n }\n } catch (error) {\n console.error(\"Error accessing camera:\", error);\n }\n };\n\n const captureImage = () => {\n if (videoRef.current && canvasRef.current) {\n const canvas = canvasRef.current;\n const video = videoRef.current;\n\n const aspectRatio = 8.5 / 11; // 8.5\" x 11\" paper aspect ratio\n canvas.height = video.videoHeight;\n canvas.width = canvas.height * aspectRatio;\n\n const context = canvas.getContext(\"2d\");\n\n const cropWidth = video.videoHeight * aspectRatio;\n const cropX = (video.videoWidth - cropWidth) / 2;\n\n context.drawImage(video, cropX, 0, cropWidth, video.videoHeight, 0, 0, canvas.width, canvas.height);\n\n canvas.toBlob((blob) => {\n const newCapturedFile = new File([blob], \"captured_image.jpg\", {\n type: \"image/jpeg\",\n });\n setFilePreview(URL.createObjectURL(newCapturedFile));\n handleFileChange(newCapturedFile); // Pass the file to the parent component\n });\n\n const stream = video.srcObject;\n const tracks = stream.getTracks();\n tracks.forEach((track) => track.stop());\n setIsCameraActive(false);\n }\n };\n\n const handleKeyDown = (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit(e);\n setFilePreview(null);\n }\n };\n\n let paperClip = null;\n if (!showWork) {\n paperClip = (\n document.getElementById(\"file-upload\").click()}\n className=\"flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-200\"\n >\n \n \n );\n }\n\n return (\n
\n {isCameraActive && (\n
\n \n \n Capture Image\n \n \n
\n )}\n {filePreview && (\n
\n
\n {\n setFilePreview(null);\n handleFileChange(null);\n }}\n className=\"text-sm text-red-500 absolute right-0 top-[-8px] hover:text-red-700 bg-white rounded-full cursor-pointer\"\n >\n \n \n \n
\n
\n )}\n {!isCameraActive && showWork && messageCount < 1 && (\n setIsCameraActive(true)}\n className=\"w-full mb-4 py-16 px-4 bg-green-500 text-white rounded-lg hover:bg-green-600 flex items-center justify-center\"\n >\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n Click To Show Your Work\n \n
\n \n )}\n {errorMessage &&
{errorMessage}
}\n {\n handleSubmit(e);\n setFilePreview(null);\n }}\n className={`flex items-center p-2 bg-gray-100 rounded ${\n filePreview ? \"rounded-t-none\" : \"rounded\"\n }`}\n >\n {paperClip}\n handleFileChangeInternal(e.target.files[0])}\n className=\"hidden\"\n />\n {\n setInput(e.target.value);\n adjustHeight();\n }}\n placeholder={disabled ? \"Select a subject to start chatting\" : \"Type your message...\"}\n rows={1}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n />\n \n \n \n \n
\n );\n};\n\nexport default MessageInput;\n","import React from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport \"katex/dist/katex.min.css\";\nimport { InlineMath, BlockMath } from \"react-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkMath from \"remark-math\";\nimport rehypeKatex from \"rehype-katex\";\n\nconst UserMessage = ({ message }) => {\n let content = '';\n\n try {\n if (message?.content === null || message?.content === undefined) {\n content = '';\n } else if (typeof message.content === 'object') {\n content = JSON.stringify(message.content);\n } else {\n content = String(message.content);\n }\n } catch (error) {\n console.error('Error processing message content:', error);\n content = '';\n }\n\n return (\n
\n
\n {\n try {\n console.log('UserMessage InlineMath props:', props);\n return ;\n } catch (error) {\n console.error('Error in InlineMath:', error);\n return {props.value || ''};\n }\n },\n math: ({ node, ...props }) => {\n try {\n console.log('UserMessage BlockMath props:', props);\n return ;\n } catch (error) {\n console.error('Error in BlockMath:', error);\n return
{props.value || ''}
;\n }\n }\n }}\n >\n {content}\n \n
\n {message.image_url && (\n
\n \n
\n )}\n
\n );\n};\n\nexport default UserMessage;","import React, { useState } from 'react';\nimport { FaChevronDown, FaChevronUp, FaStar } from 'react-icons/fa';\nimport { HiSpeakerWave, HiOutlineSpeakerWave } from 'react-icons/hi2';\nimport { ImSpinner8 } from 'react-icons/im';\nimport axios from 'axios';\nimport ReactMarkdown from 'react-markdown';\nimport \"katex/dist/katex.min.css\";\nimport { InlineMath, BlockMath } from \"react-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkMath from \"remark-math\";\nimport rehypeKatex from \"rehype-katex\";\n\nconst CollapsibleSection = ({ title, items, isOpen, toggleOpen, onItemClick, isClickable }) => {\n if (!items || items.length === 0) return null;\n\n // Ensure all items are strings\n const stringItems = items.map(item => typeof item === 'string' ? item : String(item || ''));\n\n return (\n
\n \n {isOpen ? : }\n {title} \n \n {isOpen && (\n
\n {stringItems.map((item, index) => (\n isClickable && onItemClick(item)}\n role={isClickable ? \"button\" : \"none\"}\n >\n {isClickable ? (\n item\n ) : (\n ,\n math: ({ node, ...props }) => \n }}\n >\n {item}\n \n )}\n
\n ))}\n
\n )}\n \n );\n};\n\nconst AssistantMessage = ({ message, onFollowUpClick, formToken }) => {\n const [audioStatus, setAudioStatus] = useState('not_generated');\n const [audioUrl, setAudioUrl] = useState(message.audio_url);\n const [showExamples, setShowExamples] = useState(false);\n const [showEquations, setShowEquations] = useState(false);\n const [showFollowUp, setShowFollowUp] = useState(false);\n\n // Only show audio for language learning chats\n const showAudioButton = message.chat_type === 'language_learning';\n\n // Only show map focus for map explorer chats\n const showMapFocus = message.chat_type === 'map_explorer' && message.map_focus;\n\n const handleGenerateAudio = async () => {\n setAudioStatus('generating');\n try {\n const response = await axios.post(\n `/api/v1/chat_messages/${message.id}/generate_audio`,\n {},\n {\n headers: {\n \"Authorization\": `Bearer ${formToken}`,\n },\n }\n );\n setAudioUrl(response.data.audio_url);\n setAudioStatus('ready');\n } catch (error) {\n console.error(\"Error generating audio:\", error);\n setAudioStatus('error');\n }\n };\n\n const renderContent = (content) => {\n try {\n // Ensure content is a string\n const stringContent = typeof content === 'string' ? content : String(content || '');\n\n // Process content to handle various LaTeX formats\n let processedContent = stringContent.replace(\n /\\\\\\\\(\\(|\\)|\\[|\\])/g, // Match \\\\( \\\\) \\\\[ \\\\]\n (match, bracket) => bracket // Replace with just the bracket\n );\n\n processedContent = processedContent.replace(\n /\\(\\\\([^)]+)\\)/g,\n (match, p1) => `$${p1}$`\n );\n\n processedContent = processedContent.replace(\n /\\\\\\\\\\\\\\\\(\\(|\\))\\\\\\\\([^\\\\]+)\\\\\\\\\\\\\\\\(\\(|\\))/g,\n (match, openBracket, content, closeBracket) => `$${content}$`\n );\n\n console.log('Production Debug - processedContent type:', typeof processedContent);\n console.log('Production Debug - processedContent value:', processedContent);\n\n return (\n {\n console.log('Production Debug - inlineMath value type:', typeof value);\n console.log('Production Debug - inlineMath value:', value);\n try {\n if (typeof value !== 'string') {\n console.log('Production Debug - Non-string value in inlineMath:', value);\n return {String(value || '')};\n }\n return ;\n } catch (error) {\n console.error('Production Debug - Error in InlineMath:', error);\n return {String(value || '')};\n }\n },\n // Handle block math expressions with BlockMath component\n math: ({value}) => {\n console.log('Production Debug - math value type:', typeof value);\n console.log('Production Debug - math value:', value);\n try {\n if (typeof value !== 'string') {\n console.log('Production Debug - Non-string value in math:', value);\n return {String(value || '')};\n }\n return ;\n } catch (error) {\n console.error('Production Debug - Error in BlockMath:', error);\n return {String(value || '')};\n }\n }\n }}\n >\n {processedContent}\n \n );\n } catch (error) {\n console.error(\"Error rendering markdown:\", error);\n // Fallback to plain text if markdown parsing fails\n return

{typeof content === 'string' ? content : String(content || '')}

;\n }\n };\n\n return (\n
\n
\n
\n
\n {message.explanation && (\n
\n {renderContent(message.explanation)}\n
\n )}\n
\n {showAudioButton && (\n
\n {audioUrl ? (\n
\n \n
\n ) : (\n \n {audioStatus === 'generating' ? (\n <>\n \n Reading...\n \n ) : (\n <>\n \n Hear it!\n \n )}\n \n )}\n
\n )}\n
\n\n setShowExamples(!showExamples)}\n isClickable={false}\n />\n\n setShowEquations(!showEquations)}\n isClickable={false}\n />\n\n setShowFollowUp(!showFollowUp)}\n onItemClick={onFollowUpClick}\n isClickable={true}\n />\n\n {showMapFocus && (\n
\n

\n Map focused on: {message.map_focus.latitude}, {message.map_focus.longitude}\n

\n
\n )}\n
\n
\n );\n};\n\nexport default AssistantMessage;\n","import React from \"react\";\nimport UserMessage from \"./UserMessage\";\nimport AssistantMessage from \"./AssistantMessage\";\n\nconst Profile = ({ role, user }) => {\n const avatarSrc =\n role === \"assistant\"\n ? \"/tybee-avatar.jpg\"\n : user?.avatar || \"/fallback-avatar.png\";\n\n return (\n \n );\n};\n\nexport const Message = ({ message, user, onFollowUpClick, formToken }) => {\n const isUser = message.role === \"user\";\n\n return (\n
\n
\n \n
\n
\n {isUser ? (\n \n ) : (\n \n )}\n
\n
\n );\n};\n","import React from 'react';\n\nconst Spinner = () => (\n
\n \"Loading...\"\n
\n);\n\nexport default Spinner;","import React from 'react';\nimport PropTypes from 'prop-types';\n\nconst LanguageLearningPrompts = ({ language, mode, onPromptSelect }) => {\n const getPrompts = () => {\n switch (mode.id) {\n case 'conversation':\n return [\n \"Hi! Can we practice having a simple conversation?\",\n \"Could you help me introduce myself?\",\n \"Let's talk about hobbies and interests\",\n ];\n case 'vocabulary':\n return [\n \"Can you teach me some basic words about animals?\",\n \"I'd like to learn words about food and drinks\",\n \"What are some common everyday phrases?\",\n ];\n case 'grammar':\n return [\n \"Can you help me practice present tense?\",\n \"I need help with question words\",\n \"Let's practice basic sentence structure\",\n ];\n case 'pronunciation':\n return [\n \"Can you help me pronounce some basic words?\",\n \"What are the most important sounds in this language?\",\n \"Let's practice saying common phrases\",\n ];\n default:\n return [];\n }\n };\n\n return (\n
\n

\n Suggested ways to start:\n

\n
\n {getPrompts().map((prompt, index) => (\n onPromptSelect(prompt)}\n className=\"w-full text-left p-3 rounded-lg hover:bg-blue-50 border border-gray-200\n transition-colors duration-200\"\n >\n {prompt}\n \n ))}\n
\n
\n );\n};\n\nLanguageLearningPrompts.propTypes = {\n language: PropTypes.shape({\n code: PropTypes.string.isRequired,\n name: PropTypes.string.isRequired,\n }).isRequired,\n mode: PropTypes.shape({\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.string.isRequired,\n }).isRequired,\n onPromptSelect: PropTypes.func.isRequired,\n};\n\nexport default LanguageLearningPrompts;\n","import React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\nimport { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api';\nimport { FaGlobeAmericas } from 'react-icons/fa';\nimport AssistantMessage from './AssistantMessage';\n\nconst World = ({ apiKey, formToken, chat }) => {\n const [map, setMap] = useState(null);\n const [clickedLocation, setClickedLocation] = useState(null);\n const [infoWindowOpen, setInfoWindowOpen] = useState(false);\n const [question, setQuestion] = useState('');\n const [messages, setMessages] = useState(chat?.messages || []);\n const [isLoading, setIsLoading] = useState(false);\n const [suggestions, setSuggestions] = useState([\n \"Tell me about the history of this place\",\n \"What's the local culture like?\",\n \"What are some interesting landmarks here?\",\n \"What's the climate like in this region?\",\n \"What languages do people speak here?\"\n ]);\n\n // Add state for map center\n const [center, setCenter] = useState({\n lat: 20,\n lng: 0\n });\n\n const containerStyle = {\n width: '100%',\n height: '100%',\n position: 'absolute',\n top: 0,\n left: 0\n };\n\n const mapOptions = {\n mapTypeControl: true,\n mapTypeControlOptions: {\n style: window.google?.maps.MapTypeControlStyle.HORIZONTAL_BAR,\n position: window.google?.maps.ControlPosition.TOP_LEFT,\n mapTypeIds: ['roadmap', 'terrain', 'satellite', 'hybrid']\n },\n zoomControl: true,\n zoomControlOptions: {\n position: window.google?.maps.ControlPosition.LEFT_CENTER\n },\n fullscreenControl: true,\n fullscreenControlOptions: {\n position: window.google?.maps.ControlPosition.LEFT_TOP\n },\n streetViewControl: false,\n styles: [\n {\n featureType: \"poi\",\n elementType: \"labels\",\n stylers: [{ visibility: \"off\" }]\n }\n ]\n };\n\n const handleMapClick = (event) => {\n const newLocation = {\n lat: event.latLng.lat(),\n lng: event.latLng.lng()\n };\n setClickedLocation(newLocation);\n setCenter(newLocation); // Update center when clicking\n };\n\n const handleQuestionSubmit = async (e) => {\n e.preventDefault();\n if (!question.trim()) return;\n\n setIsLoading(true);\n setQuestion('');\n \n try {\n const response = await axios.post(`/api/v1/chats/${chat.id}/send_message`, {\n content: question,\n // Only include coordinates if a location was clicked\n ...(clickedLocation && {\n latitude: clickedLocation.lat,\n longitude: clickedLocation.lng\n }),\n authenticity_token: formToken\n });\n\n const message = response.data;\n \n // Update map if location focus is provided\n console.log('message', message);\n if (message.map_focus) {\n const { latitude, longitude, zoom } = message.map_focus;\n const newCenter = {\n lat: parseFloat(latitude),\n lng: parseFloat(longitude)\n };\n \n console.log('Panning to:', { ...newCenter, zoom });\n \n setCenter(newCenter); // Update center state\n setClickedLocation(newCenter); // Update marker\n \n if (map) {\n // Force the map to update its center\n map.panTo(newCenter);\n if (zoom) {\n map.setZoom(parseInt(zoom));\n }\n }\n }\n\n setMessages(prev => [...prev, message]);\n } catch (error) {\n console.error('Error:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSuggestionClick = (suggestion) => {\n setQuestion(suggestion);\n };\n\n return (\n
\n {/* Map Section - Takes up remaining space */}\n
\n \n \n {clickedLocation && (\n \n )}\n \n \n
\n\n {/* Chat Section - Fixed width */}\n
\n
\n
\n \n

World Explorer Chat

\n
\n

\n Click anywhere on the map to ask questions about that location!\n

\n
\n\n {/* Messages */}\n
\n {messages.map((message, index) => (\n
\n {message.role === 'user' ? (\n
\n {message.latitude && (\n <>\n

Location:

\n

\n Lat: {Number(message.latitude).toFixed(4)}, Lng: {Number(message.longitude).toFixed(4)}\n

\n \n )}\n

{message.content}

\n
\n ) : (\n \n )}\n
\n ))}\n {isLoading && (\n
\n
\n
\n )}\n
\n\n {/* Input Section */}\n
\n
\n setQuestion(e.target.value)}\n placeholder={clickedLocation \n ? \"Ask about this location or type any geography question...\"\n : \"Ask any geography question or click the map to ask about a specific location!\"}\n rows={3}\n className=\"w-full p-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n
\n {suggestions.map((suggestion, index) => (\n setQuestion(suggestion)}\n className=\"text-xs bg-blue-50 text-blue-700 px-2 py-1 rounded-full hover:bg-blue-100\"\n >\n {suggestion}\n \n ))}\n
\n \n {isLoading ? 'Asking Ty...' : 'Ask Ty!'}\n \n \n
\n
\n
\n );\n};\n\nexport default World;\n\n","import React, { useState, useEffect, useRef } from \"react\";\nimport axios from \"axios\";\nimport { Message } from \"./Message\";\nimport Spinner from \"./Spinner\";\n\nconst ParentMemoryChat = ({ chat, formToken, childId, onSaveMemory }) => {\n const [messages, setMessages] = useState(chat.messages || []);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [showMemoryForm, setShowMemoryForm] = useState(false);\n const [memoryData, setMemoryData] = useState(\"\");\n const [memoryType, setMemoryType] = useState(\"anything\");\n const messagesEndRef = useRef(null);\n\n const memoryTypes = [\n { value: \"anything\", label: \"General\" },\n { value: \"math\", label: \"Math\" },\n { value: \"science\", label: \"Science\" },\n { value: \"history\", label: \"History\" },\n { value: \"geography\", label: \"Geography\" },\n { value: \"language_arts\", label: \"Language Arts\" }\n ];\n\n useEffect(() => {\n scrollToBottom();\n }, [messages]);\n\n const scrollToBottom = () => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n };\n\n const handleSubmit = async (e) => {\n e.preventDefault();\n if (!input.trim()) return;\n\n const userMessage = {\n role: \"user\",\n content: input\n };\n\n setMessages([...messages, userMessage]);\n setInput(\"\");\n setIsLoading(true);\n\n try {\n const response = await axios.post(\n `/api/v1/chats/${chat.id}/send_message`,\n {\n content: input,\n child_id: childId\n },\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n }\n );\n\n const assistantMessage = {\n role: \"assistant\",\n id: response.data.id,\n content: response.data.content,\n examples: response.data.examples || [],\n follow_up: response.data.follow_up || [],\n };\n\n setMessages((prevMessages) => [...prevMessages, assistantMessage]);\n } catch (error) {\n console.error(\"Error sending message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSaveMemoryClick = () => {\n setShowMemoryForm(true);\n // Pre-populate with the last assistant message examples if available\n const lastAssistantMessage = [...messages].reverse().find(m => m.role === \"assistant\");\n if (lastAssistantMessage && lastAssistantMessage.examples && lastAssistantMessage.examples.length > 0) {\n setMemoryData(lastAssistantMessage.examples[0]);\n }\n };\n\n const handleSaveMemory = async () => {\n if (!memoryData.trim()) return;\n\n const result = await onSaveMemory(memoryData, memoryType);\n \n if (result.success) {\n setShowMemoryForm(false);\n setMemoryData(\"\");\n \n // Add a system message confirming the save\n setMessages([\n ...messages, \n {\n role: \"system\",\n content: `Memory saved successfully! This information will help personalize the learning experience.`\n }\n ]);\n } else {\n // Handle error\n console.error(\"Failed to save memory:\", result.errors);\n }\n };\n\n const handleFollowUpClick = (question) => {\n setInput(question);\n };\n\n return (\n
\n
\n

Creating Learning Memories

\n

\n Chat with our AI to create personalized learning memories for your child. \n These memories help our tutors provide a more tailored learning experience.\n

\n
\n\n
\n
\n {messages.map((message, index) => (\n \n ))}\n {isLoading && (\n
\n \n
\n )}\n
\n
\n
\n\n {showMemoryForm && (\n
\n

Save Learning Memory

\n \n
\n \n setMemoryType(e.target.value)}\n className=\"w-full rounded-lg border-gray-300 focus:ring-yellow-500 focus:border-yellow-500\"\n >\n {memoryTypes.map((type) => (\n \n ))}\n \n
\n \n
\n \n setMemoryData(e.target.value)}\n rows={4}\n className=\"w-full rounded-lg border-gray-300 focus:ring-yellow-500 focus:border-yellow-500\"\n placeholder=\"Enter the memory details...\"\n />\n
\n \n
\n setShowMemoryForm(false)}\n className=\"px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-800 rounded-lg\"\n >\n Cancel\n \n \n Save Memory\n \n
\n
\n )}\n\n
\n setInput(e.target.value)}\n className=\"flex-grow rounded-lg border-gray-300 focus:ring-yellow-500 focus:border-yellow-500\"\n placeholder=\"Type your message...\"\n />\n \n Send\n \n \n Save Memory\n \n \n\n
\n \n View All Learning Memories\n \n
\n
\n );\n};\n\nexport default ParentMemoryChat; ","import PropTypes from \"prop-types\";\nimport React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\nimport StoryTellingChat from \"./StoryTellingChat\";\nimport MessageInput from \"./MessageInput\";\nimport { Message } from \"./Message\";\nimport Spinner from \"./Spinner\";\nimport LanguageLearningPrompts from './LanguageLearningPrompts';\nimport World from './World';\nimport ParentMemoryChat from './ParentMemoryChat';\n\nconst Chat = (props) => {\n const [messages, setMessages] = useState(props.chat.messages);\n const [input, setInput] = useState(\"\");\n const [imageFile, setImageFile] = useState(null);\n const [isStorySubmitted, setIsStorySubmitted] = useState(\n props.chat.chatType === \"story_telling\" && !!props.chat.chatStory\n );\n const [isLoading, setIsLoading] = useState(false);\n const [subject, setSubject] = useState(null);\n const [targetLanguage, setTargetLanguage] = useState(null);\n const [learningMode, setLearningMode] = useState(null);\n\n const handleFileChange = (file) => {\n setImageFile(file);\n };\n\n const handleSubmit = async (e) => {\n e.preventDefault();\n\n let uploadedImageURL = null;\n let uploadedImageId = null;\n\n if (imageFile) {\n const formData = new FormData();\n formData.append(\"chat_image[role]\", \"user\");\n formData.append(\"chat_image[image]\", imageFile);\n\n try {\n const response = await axios.post(\n `/chats/${props.chat.id}/chat_images`,\n formData,\n {\n headers: {\n Authorization: `Bearer ${props.formToken}`,\n \"Content-Type\": \"multipart/form-data\",\n Accept: \"application/json\",\n },\n }\n );\n uploadedImageURL = response.data.imageURL;\n uploadedImageId = response.data.imageId;\n } catch (error) {\n console.error(\"Image upload failed:\", error);\n return; // Prevent sending the message if image upload fails\n }\n }\n\n const userMessage = {\n role: \"user\",\n content: input,\n image_url: uploadedImageURL,\n image_id: uploadedImageId,\n };\n\n setMessages([...messages, userMessage]);\n setInput(\"\");\n setImageFile(null);\n setIsLoading(true);\n\n try {\n const response = await axios.post(\n `/api/v1/chats/${props.chat.id}/send_message`,\n {\n content: input,\n image_id: uploadedImageId,\n subject: subject || \"anything\",\n ...(props.chat.chatType === 'language_learning' && {\n language: targetLanguage?.code\n })\n },\n {\n headers: {\n Authorization: `Bearer ${props.formToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n }\n );\n\n const assistantMessage = {\n role: \"assistant\",\n id: response.data.id,\n audioUrl: response.data.audio_url,\n explanation: response.data.explanation,\n examples: response.data.examples || [],\n equations: response.data.equations || [],\n follow_up: response.data.follow_up || '',\n map_focus: response.data.map_focus || null,\n };\n\n setMessages((prevMessages) => [...prevMessages, assistantMessage]);\n } catch (error) {\n console.error(\"Error sending message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const regularSubjects = [\"Math\", \"Science\", \"History\", \"Geography\", \"Language Arts\", \"Anything\"];\n\n const languageModes = [\n { id: 'conversation', label: 'Have a Conversation', icon: '💭' },\n { id: 'vocabulary', label: 'Learn New Words', icon: '📚' },\n { id: 'grammar', label: 'Practice Grammar', icon: '✏️' },\n { id: 'pronunciation', label: 'Pronunciation Help', icon: '🗣️' },\n ];\n\n const languages = [\n { code: 'es', name: 'Spanish' },\n { code: 'fr', name: 'French' },\n { code: 'de', name: 'German' },\n { code: 'it', name: 'Italian' },\n { code: 'pt', name: 'Portuguese' },\n { code: 'nl', name: 'Dutch' },\n ];\n\n const isNewChat = messages.length === 0;\n\n const handleFollowUpClick = (question) => {\n setInput(question);\n };\n\n const handleSaveMemory = async (memoryData, memoryType) => {\n try {\n const response = await axios.post(\n `/user_ai_memories/create_from_chat`,\n {\n memory_data: memoryData,\n memory_type: memoryType,\n user_id: props.childId // This will be passed from the controller\n },\n {\n headers: {\n Authorization: `Bearer ${props.formToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n }\n );\n\n return response.data;\n } catch (error) {\n console.error(\"Error saving memory:\", error);\n return { success: false, error: \"Failed to save memory\" };\n }\n };\n\n return (\n
\n {props.chat.chatType === 'parent_memory' ? (\n \n ) : props.chat.chatType === 'map_explorer' ? (\n \n ) : (\n
\n {isNewChat && props.chat.chatType === 'language_learning' ? (\n
\n {!targetLanguage && (\n
\n

What language would you like to learn?

\n
\n {languages.map((lang) => (\n setTargetLanguage(lang)}\n className=\"p-4 text-lg rounded-lg border-2 hover:border-blue-500 hover:bg-blue-50 transition-colors\n flex items-center justify-center space-x-2\"\n >\n {lang.name}\n \n ))}\n
\n
\n )}\n\n {targetLanguage && !learningMode && (\n
\n

What would you like to do?

\n
\n {languageModes.map((mode) => (\n setLearningMode(mode)}\n className=\"p-6 text-lg rounded-lg border-2 hover:border-blue-500 hover:bg-blue-50 transition-colors\n flex items-center justify-center space-x-3\"\n >\n {mode.icon}\n {mode.label}\n \n ))}\n
\n
\n )}\n\n {targetLanguage && learningMode && (\n setInput(prompt)}\n />\n )}\n
\n ) : isNewChat && !isStorySubmitted && props.chat.chatType !== 'language_learning' ? (\n
\n

Choose a subject:

\n
\n {regularSubjects.map((sub) => (\n setSubject(sub)}\n className={`px-4 py-2 rounded ${\n subject === sub\n ? \"bg-blue-500 text-white\"\n : \"bg-gray-200 text-gray-800\"\n }`}\n >\n {sub}\n \n ))}\n
\n
\n ) : null}\n\n
\n {isNewChat && !isStorySubmitted ? (\n
\n {props.chat.chatType === 'language_learning'\n ? (!targetLanguage\n ? \"Choose a language to start learning!\"\n : !learningMode\n ? \"Select what you'd like to practice!\"\n : \"Pick a prompt to start chatting or type your own!\")\n : (subject\n ? \"Type your message to start the chat!\"\n : \"Select a subject and start your chat!\")}\n
\n ) : (\n messages.map((message, index) => (\n \n ))\n )}\n {isLoading && (\n
\n \n
\n )}\n
\n\n {!props.readOnly &&\n props.chat.chatType !== \"story_telling\" &&\n !isStorySubmitted && (\n \n )}\n\n {props.chat.chatType === \"story_telling\" && (\n setIsStorySubmitted(true)}\n chatId={props.chat.id}\n chatStory={props.chat.chatStory}\n />\n )}\n\n {props.chat.chatType !== 'map_explorer' && !isNewChat && !isStorySubmitted && (\n \n )}\n
\n )}\n
\n );\n};\n\nChat.propTypes = {\n chatKey: PropTypes.number,\n name: PropTypes.string,\n chat: PropTypes.shape({\n id: PropTypes.number.isRequired,\n chatType: PropTypes.string.isRequired,\n messages: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.number.isRequired,\n role: PropTypes.string.isRequired,\n content: PropTypes.string,\n image_url: PropTypes.string,\n })\n ).isRequired,\n chatStory: PropTypes.object,\n }).isRequired\n};\n\nexport default Chat;\n","import PropTypes from \"prop-types\";\nimport React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\nimport StoryTellingChat from \"./StoryTellingChat\";\nimport MessageInput from \"./MessageInput\";\nimport { Message } from \"./Message\";\n\nconst Chat = (props) => {\n const [input, setInput] = useState(\"\");\n const [imageURL, setImageURL] = useState(null);\n const [imageId, setImageId] = useState(null);\n const [eventSource, setEventSource] = useState(null);\n const [isStorySubmitted, setIsStorySubmitted] = useState(\n props.chat.chatType === \"story_telling\" && !!props.chat.chatStory.story\n );\n\n const handleSend = async (e) => {\n e.preventDefault();\n\n const userMessage = {\n role: \"user\",\n content: input,\n image_url: imageURL,\n image_id: imageId,\n };\n\n setMessages([...messages, userMessage]);\n setInput(\"\");\n if (eventSource) {\n eventSource.close();\n }\n\n const queryParams = new URLSearchParams({\n content: input,\n image_id: imageId,\n }).toString();\n const newEventSource = new EventSource(\n `/api/v1/chats/${props.chat.id}/send_message?${queryParams}`\n );\n setEventSource(newEventSource);\n setImageURL(null);\n let assistantMessage = { role: \"assistant\", content: \"\" };\n setMessages((prevMessages) => [...prevMessages, assistantMessage]);\n\n newEventSource.onmessage = (event) => {\n const newContent = event.data;\n setMessages((prevMessages) => {\n const updatedMessages = [...prevMessages];\n const lastMessageIndex = updatedMessages.length - 1;\n\n updatedMessages[lastMessageIndex] = {\n ...assistantMessage,\n content: newContent,\n };\n\n return updatedMessages;\n });\n };\n\n newEventSource.onerror = (error) => {\n console.error(\"EventSource failed:\", error);\n newEventSource.close();\n setEventSource(null);\n };\n };\n\n const handleFileChange = async (e) => {\n const file = e.target.files[0];\n const formData = new FormData();\n formData.append(\"chat_image[role]\", \"user\");\n formData.append(\"chat_image[image]\", file);\n\n try {\n const response = await axios.post(\n `/chats/${props.chat.id}/chat_images`,\n formData,\n {\n headers: {\n Authorization: `Bearer ${props.formToken}`,\n \"Content-Type\": \"multipart/form-data\",\n Accept: \"application/json\",\n },\n }\n );\n setImageURL(response.data.imageURL);\n setImageId(response.data.imageId);\n } catch (error) {\n console.error(\"Image upload failed:\", error);\n }\n };\n\n useEffect(() => {\n return () => {\n if (eventSource) {\n eventSource.close();\n }\n };\n }, [eventSource]);\n\n return (\n
\n {props.chat.chatType === \"story_telling\" ? (\n setIsStorySubmitted(true)} \n chatId={props.chat.id}\n chatStory={props.chat.chatStory} \n />\n ) : (\n
\n {messages.map((message, messageIndex) => (\n \n ))}\n
\n )}\n {!props.readOnly &&\n props.chat.chatType !== \"story_telling\" &&\n !isStorySubmitted ? (\n \n ) : null}\n
\n );\n};\n\nChat.propTypes = {\n chatKey: PropTypes.number,\n name: PropTypes.string,\n chat: PropTypes.shape({\n id: PropTypes.number.isRequired,\n chatType: PropTypes.string.isRequired,\n messages: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.number.isRequired,\n role: PropTypes.string.isRequired,\n content: PropTypes.string.isRequired,\n image_url: PropTypes.string,\n })\n ).isRequired,\n chatStory: PropTypes.shape({\n id: PropTypes.number.isRequired,\n story: PropTypes.string, // It can be null initially\n images: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.number.isRequired,\n role: PropTypes.string,\n imageUrl: PropTypes.string.isRequired,\n imagePrompt: PropTypes.string.isRequired,\n })\n ).isRequired,\n prompt: PropTypes.string.isRequired,\n }),\n }).isRequired,\n};\n\nexport default Chat;\n","import React, { useState } from 'react';\nimport axios from 'axios';\nimport Spinner from './Spinner';\n\nconst ImageCreationComponent = ({ chat, formToken, user }) => {\n const [prompt, setPrompt] = useState('');\n const [style, setStyle] = useState('cartoon');\n const [difficulty, setDifficulty] = useState('beginner');\n const [layout, setLayout] = useState('1:1');\n const [generatedImage, setGeneratedImage] = useState(null);\n const [loading, setLoading] = useState(false);\n const [avatarSet, setAvatarSet] = useState(false);\n const [backgroundSet, setBackgroundSet] = useState(false);\n const [chatImageId, setChatImageId] = useState(null);\n const [isPublic, setIsPublic] = useState(false);\n\n const isColoringPage = chat.chatType === 'coloring_page';\n const isAvatar = chat.chatType === 'avatar_creation';\n\n const createImage = async () => {\n setLoading(true);\n\n try {\n const options = isColoringPage\n ? { difficulty }\n : { style, layout: isAvatar ? '1:1' : layout };\n\n const response = await axios.post(\n `/api/v1/chats/${chat.id}/create_image_from_prompt`,\n {\n message: prompt,\n options,\n },\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n },\n }\n );\n\n setGeneratedImage(response.data.imageUrl);\n setChatImageId(response.data.id);\n setIsPublic(response.data.public);\n } catch (error) {\n console.error(\"Error creating image:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n const setAsAvatar = async () => {\n try {\n const payload = { user: { avatar_id: chatImageId } };\n await axios.patch(\n `/api/v1/users/${user.id}.json`,\n payload,\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n setAvatarSet(true);\n } catch (error) {\n console.error(\"Error setting avatar:\", error);\n }\n };\n\n const setAsBackground = async () => {\n try {\n const payload = { user: { background_id: chatImageId } };\n await axios.patch(\n `/api/v1/users/${user.id}.json`,\n payload,\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n setBackgroundSet(true);\n } catch (error) {\n console.error(\"Error setting background:\", error);\n }\n };\n\n const toggleShareOnTYB = async () => {\n try {\n const response = await axios.patch(\n `/api/v1/chat_images/${chatImageId}.json`,\n { chat_image: { public: !isPublic } },\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n 'Content-Type': 'application/json'\n },\n }\n );\n setIsPublic(response.data.chat_image.public);\n } catch (error) {\n console.error(\"Error toggling image visibility:\", error);\n }\n };\n\n const downloadImage = () => {\n const link = document.createElement('a');\n link.href = generatedImage;\n link.download = 'tyb_generated_image.png';\n link.click();\n };\n\n return (\n
\n

\n {isColoringPage ? 'Create a Coloring Page' : isAvatar ? 'Create Your Avatar' : 'Create Your Image'}\n

\n\n
\n {/* Left Column: Image Options or Loading Spinner */}\n
\n {loading ? (\n
\n \n
\n ) : !generatedImage ? (\n
\n
\n \n setPrompt(e.target.value)}\n placeholder=\"Enter your image prompt here...\"\n className=\"border border-gray-400 p-2 w-full rounded-lg focus:outline-none focus:border-blue-400\"\n rows=\"4\"\n />\n
\n\n {isColoringPage && (\n
\n \n setDifficulty(e.target.value)}\n className=\"border border-gray-400 p-2 w-full rounded-lg focus:outline-none focus:border-blue-400\"\n >\n \n \n \n \n
\n )}\n\n {!isAvatar && (\n
\n \n setLayout(e.target.value)}\n className=\"border border-gray-400 p-2 w-full rounded-lg focus:outline-none focus:border-blue-400\"\n >\n \n \n \n \n
\n )}\n\n
\n \n setStyle(e.target.value)}\n className=\"border border-gray-400 p-2 w-full rounded-lg focus:outline-none focus:border-blue-400\"\n >\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n\n
\n \n Create Image\n \n
\n
\n ) : null}\n
\n\n {/* Right Column: Display Generated Image or Placeholder */}\n
\n {generatedImage ? (\n
\n

Generated Image

\n \n
\n \n Download Image\n \n {!isAvatar && (\n \n {backgroundSet ? 'Background Set' : 'Set as Background'}\n \n )}\n {isAvatar && (\n \n {avatarSet ? 'Avatar Set' : 'Set as Avatar'}\n \n )}\n \n {isPublic ? 'Hide Image' : 'Share On TYB'}\n \n
\n
\n ) : (\n
\n {loading ? 'Generating your image...' : 'Your image will appear here once generated.'}\n
\n )}\n
\n
\n
\n );\n};\n\nexport default ImageCreationComponent;","import { useState, useEffect, useRef } from 'react';\nimport axios from 'axios';\n\nconst useInfiniteImageLoad = (initialImages, totalCount, formToken) => {\n const [images, setImages] = useState(initialImages);\n const [page, setPage] = useState(2);\n const [loading, setLoading] = useState(false);\n const [hasMore, setHasMore] = useState(initialImages.length < totalCount);\n const observerRef = useRef();\n\n useEffect(() => {\n if (observerRef.current) observerRef.current.disconnect();\n\n const observer = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n if (entry.isIntersecting && hasMore && !loading) {\n loadMoreImages();\n }\n },\n { threshold: 1.0 }\n );\n\n const target = document.getElementById(\"loading-element\");\n if (target) observer.observe(target);\n\n observerRef.current = observer;\n return () => observer.disconnect();\n }, [hasMore, loading]);\n\n const loadMoreImages = async () => {\n if (loading || !hasMore) return;\n\n setLoading(true);\n try {\n const response = await axios.get(\"/chat_images.json\", {\n params: { page },\n headers: {\n Authorization: `Bearer ${formToken}`,\n },\n });\n\n if (response.data.images.length > 0) {\n setImages((prevImages) => [...prevImages, ...response.data.images]);\n setPage((prevPage) => prevPage + 1);\n }\n\n if (!response.data.next_page || images.length >= totalCount) {\n setHasMore(false);\n }\n } catch (error) {\n console.error(\"Error loading more images:\", error);\n setHasMore(false);\n } finally {\n setLoading(false);\n }\n };\n\n return { images, loading, hasMore };\n};\n\nexport default useInfiniteImageLoad;","import React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\nimport useInfiniteImageLoad from \"./useInfiniteImageLoad\";\n\nconst ImageGrid = ({ initialImages, totalCount, formToken, user, editType }) => {\n const { images: hookImages, loading, hasMore } = useInfiniteImageLoad(initialImages, totalCount, formToken);\n const [images, setImages] = useState(initialImages);\n\n useEffect(() => {\n setImages(hookImages);\n }, [hookImages]);\n\n const [completedImageId, setCompletedImageId] = useState(null);\n\n const handleSetAsAction = async (imageId) => {\n const payload = editType === 'avatar' ? { user: { avatar_id: imageId } } : { user: { background_id: imageId } };\n\n try {\n const response = await axios.patch(\n `/api/v1/users/${user.id}.json`,\n payload,\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n setCompletedImageId(imageId);\n // Update the user object in the parent component if necessary\n } catch (error) {\n console.error(`Error setting ${editType}:`, error);\n }\n };\n\n const handleShareImage = async (imageId) => {\n try {\n const response = await axios.patch(\n `/api/v1/chat_images/${imageId}.json`,\n { chat_image: { public: !images.find(img => img.id === imageId).public } },\n {\n headers: {\n Authorization: `Bearer ${formToken}`,\n 'Content-Type': 'application/json'\n },\n }\n );\n \n // Assuming the response.data contains the updated image object\n const updatedImage = response.data.chat_image;\n // Update the images array, preserving existing data and updating only the changed fields\n setImages(prevImages => prevImages.map(img => \n img.id === updatedImage.id ? updatedImage : img\n ));\n } catch (error) {\n console.error(\"Error toggling image visibility:\", error);\n }\n };\n\n const downloadImage = (imageUrl) => {\n const link = document.createElement('a');\n link.href = imageUrl;\n link.download = 'downloaded_image.png';\n link.click();\n };\n\n return (\n
\n
\n {images.map((image) => (\n
\n \n \"User\n \n
\n

Created By {image.createdBy}

\n

{image.created_at}

\n {editType && (\n handleSetAsAction(image.id)}\n className={`mt-2 px-4 py-2 rounded-lg uppercase ${\n completedImageId === image.id ? 'bg-gray-500 cursor-not-allowed' : 'bg-indigo-500 hover:bg-indigo-600'\n } text-white`}\n disabled={completedImageId === image.id}\n >\n {completedImageId === image.id ? `${editType} set` : `set as ${editType}`}\n \n )}\n {user.id === image.createdUser && image.role === 'assistant' && (\n handleShareImage(image.id)}\n className={`mt-2 mr-2 px-4 py-2 rounded-lg ${\n image.public ? 'bg-yellow-500 hover:bg-yellow-600' : 'bg-blue-500 hover:bg-blue-600'\n } text-white`}\n >\n {image.public ? 'Hide Image' : 'Share On TYB'}\n \n )}\n downloadImage(image.imageUrl)}\n className=\"bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 mt-2\"\n >\n Download Image\n \n
\n
\n ))}\n
\n {loading &&

Loading more images...

}\n {!hasMore && }\n {hasMore && (\n
\n Scroll down for more images...\n
\n )}\n
\n );\n};\n\nexport default ImageGrid;\n","import React, { useState, useCallback, useEffect } from 'react';\nimport axios from 'axios';\nimport { useInView } from 'react-intersection-observer';\n\nconst HeartIcon = ({ filled }) => (\n \n \n \n);\n\nconst Lightbox = ({ image, onClose }) => {\n return (\n
\n
\n \"User\n
\n

{image.createdBy}

\n

{image.created_at}

\n
\n
\n
\n );\n};\n\nconst ImagePlaceholder = () => (\n
\n);\n\nconst ImageCell = React.memo(({ image, onClick, onHeartToggle, signedIn }) => {\n const [imageLoaded, setImageLoaded] = useState(false);\n\n if (!image) return ;\n\n return (\n
onClick(image)}>\n
\n \n
\n \"User setImageLoaded(true)}\n loading=\"lazy\"\n />\n {imageLoaded && (\n
\n
\n {`${image.createdBy}'s\n
\n
\n

{image.createdBy}

\n

{image.created_at}

\n
\n {signedIn && (\n
onHeartToggle(e, image.id)}\n >\n \n
\n )}\n
\n {image.likeCount}\n
\n
\n )}\n
\n );\n});\n\nconst ImageMosaic = ({ initialImages, totalCount, formToken, signedIn }) => {\n const [images, setImages] = useState(initialImages || []);\n const [offset, setOffset] = useState(initialImages ? initialImages.length : 0);\n const [loading, setLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [selectedImage, setSelectedImage] = useState(null);\n\n const { ref, inView } = useInView({\n threshold: 0,\n });\n\n const loadMoreImages = useCallback(async () => {\n if (loading || !hasMore) return;\n\n setLoading(true);\n try {\n const response = await axios.get('/public_images.json', {\n params: { offset: offset, per_page: 12 },\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': document.querySelector('meta[name=\"csrf-token\"]').content\n }\n });\n\n const { chat_images, has_more } = response.data;\n \n if (chat_images && chat_images.length > 0) {\n setImages(prevImages => [...prevImages, ...chat_images]);\n setOffset(prevOffset => prevOffset + chat_images.length);\n setHasMore(has_more);\n } else {\n setHasMore(false);\n }\n } catch (error) {\n console.error('Error loading images:', error);\n setHasMore(false);\n } finally {\n setLoading(false);\n }\n }, [loading, hasMore, offset]);\n\n useEffect(() => {\n if (inView) {\n loadMoreImages();\n }\n }, [inView, loadMoreImages]);\n\n const openLightbox = useCallback((image) => {\n setSelectedImage(image);\n }, []);\n\n const closeLightbox = useCallback(() => {\n setSelectedImage(null);\n }, []);\n\n const handleHeartToggle = useCallback(async (e, imageId) => {\n e.stopPropagation();\n try {\n const response = await axios.post(`/api/v1/chat_images/${imageId}/toggle_like`, {}, {\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': document.querySelector('meta[name=\"csrf-token\"]').content\n }\n });\n if (response.status === 200) {\n const updatedImageData = response.data.chat_image;\n setImages(prevImages => prevImages.map(img => \n img.id === imageId ? { ...img, ...updatedImageData } : img\n ));\n }\n } catch (error) {\n console.error('Error toggling heart:', error);\n }\n }, []);\n\n return (\n
\n
\n {images.map(image => (\n \n ))}\n {hasMore && Array.from({ length: 4 }).map((_, index) => (\n \n ))}\n
\n {hasMore && (\n
\n {loading ? 'Loading more images...' : 'Scroll down for more images...'}\n
\n )}\n {selectedImage && }\n
\n );\n};\n\nexport default React.memo(ImageMosaic);","import React, { useState, useEffect } from \"react\";\nimport { Elements } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\n\nconst stripePromise = loadStripe(process.env.STRIPE_PUBLISHABLE_KEY);\n\nconst StripeWrapper = ({ familyId, formToken, initialPriceId }) => {\n const [priceId, setPriceId] = useState(initialPriceId);\n const [clientSecret, setClientSecret] = useState(null);\n\n useEffect(() => {\n async function initializeCheckout() {\n try {\n const promotekitReferral = window.promotekit_referral || null;\n\n const response = await fetch(\"/subscriptions/create.json\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-CSRF-Token\": formToken,\n },\n body: JSON.stringify({\n price_id: priceId,\n family_id: familyId,\n promotekit_referral: promotekitReferral,\n }),\n });\n\n const data = await response.json();\n\n if (data.clientSecret) {\n setClientSecret(data.clientSecret);\n } else {\n console.error(\"No client secret returned from the backend\");\n }\n } catch (error) {\n console.error(\"Error fetching client secret:\", error);\n }\n }\n\n initializeCheckout();\n }, [priceId, familyId, formToken]);\n\n useEffect(() => {\n if (clientSecret && stripePromise) {\n stripePromise.then((stripe) => {\n stripe.initEmbeddedCheckout({\n clientSecret,\n }).then((checkout) => {\n checkout.mount(\"#checkout\");\n }).catch((error) => {\n console.error(\"Error initializing embedded checkout\", error);\n });\n });\n }\n }, [clientSecret]);\n\n const handlePriceChange = (newPriceId) => {\n setPriceId(newPriceId);\n };\n\n return (\n \n
\n
\n {/* Example button for switching price plan */}\n \n\n {/* Example slider for adjusting donation */}\n handlePriceChange(`price_id_based_on_${e.target.value}`)}\n />\n
\n\n
\n
\n
\n );\n};\n\nexport default StripeWrapper;\n","import PropTypes from \"prop-types\";\nimport React, { useState, useEffect } from \"react\";\nimport axios from \"axios\";\nimport Spinner from \"../../Chat/components/Spinner\";\n\nconst WordList = ({ wordList, initialUser }) => {\n const [words, setWords] = useState(wordList.words || []);\n const [newWord, setNewWord] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [user, setUser] = useState(initialUser);\n\n const addWord = async (e) => {\n e.preventDefault();\n if (!newWord.trim() || isLoading || user.wordsRemaining <= 0) return;\n\n setIsLoading(true);\n try {\n const response = await axios.post(`/api/v1/word_lists/${wordList.id}/words`, { word: newWord });\n const addedWord = response.data.word;\n setNewWord(\"\");\n setUser(response.data.user);\n \n // Immediately add the new word to the list\n setWords(prevWords => [...prevWords, addedWord]);\n\n // Fetch the updated word list to ensure consistency\n const updatedWordListResponse = await axios.get(`/api/v1/word_lists/${wordList.id}`);\n setWords(updatedWordListResponse.data.words);\n } catch (error) {\n console.error(\"Error adding word:\", error);\n // TODO: Add error handling UI\n } finally {\n setIsLoading(false);\n }\n };\n\n const deleteWord = async (wordId) => {\n try {\n await axios.delete(`/api/v1/word_lists/${wordList.id}/words/${wordId}`);\n setWords(words.filter(word => word.id !== wordId));\n } catch (error) {\n console.error(\"Error deleting word:\", error);\n // TODO: Add error handling UI\n }\n };\n\n const playSlowAudio = (audioUrl, rate = 0.75) => {\n const audio = new Audio(audioUrl);\n audio.playbackRate = rate;\n audio.play();\n };\n\n return (\n
\n
\n

Language: {wordList.languageName}

\n
\n\n {user.wordsRemaining > 0 ? (\n
\n setNewWord(e.target.value)}\n placeholder=\"Enter a new word\"\n className=\"flex-grow px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\"\n disabled={isLoading}\n />\n \n \n ) : (\n

You have reached the maximum number of words for this week. Please upgrade to add more or wait until next week.

\n )}\n \n {user.freemium && (\n

Words remaining: {user.wordsRemaining}

\n )}\n\n
    \n {words.map((word) => (\n
  • \n
    \n {word.word_text}\n deleteWord(word.id)}\n className=\"px-3 py-1 bg-red-500 text-white rounded-lg hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500\"\n >\n Delete\n \n
    \n
    \n {word.audioWordUrl && (\n
    \n \n
    \n \n playSlowAudio(word.audioWordUrl)}\n className=\"px-3 py-1 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n Play Slow\n \n
    \n
    \n )}\n {word.sentence && (\n

    {word.sentence}

    \n )}\n {word.audioSentenceUrl && (\n
    \n \n
    \n \n playSlowAudio(word.audioSentenceUrl)}\n className=\"px-3 py-1 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n Play Slow\n \n
    \n
    \n )}\n
    \n
  • \n ))}\n
\n
\n );\n};\n\nWordList.propTypes = {\n wordList: PropTypes.shape({\n id: PropTypes.number.isRequired,\n languageName: PropTypes.string.isRequired,\n words: PropTypes.arrayOf(PropTypes.shape({\n id: PropTypes.number.isRequired,\n word_text: PropTypes.string.isRequired,\n // ... other word properties ...\n })),\n }).isRequired,\n initialUser: PropTypes.shape({\n wordsRemaining: PropTypes.number.isRequired,\n freemium: PropTypes.bool.isRequired,\n // ... other user properties ...\n }).isRequired,\n};\n\nexport default WordList;\n","import PropTypes from \"prop-types\";\nimport React, { useState, useEffect } from \"react\";\n\nconst specialCharacters = {\n es: ['á', 'é', 'í', 'ó', 'ú', 'ñ', 'ü', '¿', '¡'],\n fr: ['é', 'è', 'ê', 'ë', 'à', 'â', 'ô', 'û', 'ù', 'ï', 'ç'],\n de: ['ä', 'ö', 'ü', 'ß'],\n it: ['à', 'è', 'é', 'ì', 'ò', 'ù'],\n pt: ['á', 'â', 'ã', 'à', 'ç', 'é', 'ê', 'í', 'ó', 'ô', 'õ', 'ú'],\n nl: ['ij', 'á', 'é', 'í', 'ó', 'ú']\n};\n\nconst WordTest = ({ wordList }) => {\n const [words, setWords] = useState(wordList.words || []);\n const [currentWordIndex, setCurrentWordIndex] = useState(0);\n const [userAnswer, setUserAnswer] = useState(\"\");\n const [showResult, setShowResult] = useState(false);\n const [isCorrect, setIsCorrect] = useState(false);\n const [wrongAnswers, setWrongAnswers] = useState([]);\n const [earnedCoins, setEarnedCoins] = useState(0);\n const [hasSubmitted, setHasSubmitted] = useState(false);\n const [showWrongAnswersSummary, setShowWrongAnswersSummary] = useState(false);\n const [correctAnswers, setCorrectAnswers] = useState([]);\n const [retryMode, setRetryMode] = useState(false);\n\n const currentWord = words[currentWordIndex];\n const languageCode = wordList.language.toLowerCase();\n\n const handleSpecialCharacter = (char) => {\n setUserAnswer(prevAnswer => prevAnswer + char);\n };\n\n const handleSubmit = async (e) => {\n e.preventDefault();\n if (hasSubmitted) return;\n\n const correct = userAnswer.toLowerCase().trim() === currentWord.word_text.toLowerCase().trim();\n setIsCorrect(correct);\n setShowResult(true);\n setHasSubmitted(true);\n\n if (correct) {\n setCorrectAnswers(prev => [...prev, currentWord]);\n try {\n const response = await fetch('/api/v1/user_rewards/add_coin', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': document.querySelector('[name=\"csrf-token\"]')?.content,\n }\n });\n \n if (response.ok) {\n setEarnedCoins(prev => prev + 1);\n }\n } catch (error) {\n console.error('Error adding coin:', error);\n }\n } else {\n setWrongAnswers(prev => [...prev, {\n word: currentWord,\n userAnswer: userAnswer\n }]);\n }\n };\n\n const nextWord = () => {\n const isLastWord = currentWordIndex === words.length - 1;\n \n if (isLastWord && wrongAnswers.length > 0) {\n setShowWrongAnswersSummary(true);\n } else {\n setCurrentWordIndex((prevIndex) => (prevIndex + 1) % words.length);\n setUserAnswer(\"\");\n setShowResult(false);\n setHasSubmitted(false);\n }\n };\n\n const playAudio = (audioUrl, rate = 1) => {\n const audio = new Audio(audioUrl);\n audio.playbackRate = rate;\n audio.play();\n };\n\n const resetFullTest = () => {\n setWords(wordList.words || []);\n setCurrentWordIndex(0);\n setUserAnswer(\"\");\n setShowResult(false);\n setIsCorrect(false);\n setWrongAnswers([]);\n setCorrectAnswers([]);\n setEarnedCoins(0);\n setHasSubmitted(false);\n setShowWrongAnswersSummary(false);\n setRetryMode(false);\n };\n\n const retryWrongAnswers = () => {\n setWords(wrongAnswers.map(wa => wa.word));\n setCurrentWordIndex(0);\n setUserAnswer(\"\");\n setShowResult(false);\n setIsCorrect(false);\n setWrongAnswers([]);\n setHasSubmitted(false);\n setShowWrongAnswersSummary(false);\n setRetryMode(true);\n };\n\n if (showWrongAnswersSummary) {\n return (\n
\n
\n

Test Complete!

\n

\n You got {earnedCoins} out of {retryMode ? wrongAnswers.length : words.length} words correct!\n

\n\n
\n

Words You Got Right:

\n
\n {correctAnswers.map((correct, index) => (\n
\n

{correct.word_text}

\n

Context: {correct.sentence}

\n playAudio(correct.audioWordUrl)}\n className=\"mt-2 px-3 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600\"\n >\n Listen\n \n
\n ))}\n
\n
\n\n {wrongAnswers.length > 0 && (\n
\n

Words to Review:

\n
\n {wrongAnswers.map((wrong, index) => (\n
\n

Correct: {wrong.word.word_text}

\n

Your answer: {wrong.userAnswer}

\n

Context: {wrong.word.sentence}

\n playAudio(wrong.word.audioWordUrl)}\n className=\"mt-2 px-3 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600\"\n >\n Listen Again\n \n
\n ))}\n
\n
\n )}\n\n
\n \n Retry Incorrect Words\n \n \n Start New Test\n \n
\n
\n
\n );\n }\n\n return (\n
\n
\n

Language: {wordList.languageName}

\n

Word: {currentWordIndex + 1} / {words.length}

\n
\n\n
\n
\n playAudio(currentWord.audioWordUrl)}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n Say Word\n \n playAudio(currentWord.audioWordUrl, 0.75)}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n Say Word Slowly\n \n
\n
\n playAudio(currentWord.audioSentenceUrl)}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n Say Sentence\n \n playAudio(currentWord.audioSentenceUrl, 0.5)}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n Say Sentence Slowly\n \n
\n {currentWord.sentence && (\n

\n {currentWord.sentence.replace(new RegExp(currentWord.word_text, 'gi'), '______')}\n

\n )}\n
\n\n
\n setUserAnswer(e.target.value)}\n placeholder=\"Enter the word\"\n disabled={hasSubmitted}\n className=\"px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 disabled:text-gray-500\"\n />\n {specialCharacters[languageCode] && (\n
\n {specialCharacters[languageCode].map((char, index) => (\n handleSpecialCharacter(char)}\n disabled={hasSubmitted}\n className=\"px-3 py-1 bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-400 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {char}\n \n ))}\n
\n )}\n \n \n\n {showResult && (\n
\n

\n {isCorrect ? 'Correct!' : `Incorrect. The correct word is: ${currentWord.word_text}`}\n

\n \n {currentWordIndex === words.length - 1 ? 'Finish Test' : 'Next Word'}\n \n
\n )}\n
\n );\n};\n\nWordTest.propTypes = {\n wordList: PropTypes.shape({\n id: PropTypes.number.isRequired,\n language: PropTypes.string.isRequired,\n words: PropTypes.arrayOf(PropTypes.shape({\n id: PropTypes.number.isRequired,\n word_text: PropTypes.string.isRequired,\n sentence: PropTypes.string.isRequired,\n audioWordUrl: PropTypes.string.isRequired,\n audioSentenceUrl: PropTypes.string.isRequired,\n })),\n }).isRequired,\n};\n\nexport default WordTest;\n","import React, { useEffect } from 'react';\nimport LogRocket from 'logrocket';\n\nconst LogrocketWrapper = ({ user }) => {\n useEffect(() => {\n if (!window.LogRocketInitialized) {\n LogRocket.init('sgko6z/tyb');\n window.LogRocketInitialized = true;\n }\n \n if (user) {\n LogRocket.identify(user.id, {\n name: user.fullname,\n email: user.email\n });\n }\n }, [user]);\n\n return null;\n};\n\nexport default LogrocketWrapper;\n","import React, { useState, useEffect } from 'react'\n\nconst UsernameValidator = ({ onChange, currentUsername = '' }) => {\n const [username, setUsername] = useState(currentUsername)\n const [status, setStatus] = useState(null)\n const [isChecking, setIsChecking] = useState(false)\n\n useEffect(() => {\n const checkUsername = async () => {\n if (username.length < 3) {\n setStatus({ type: 'warning', message: 'Username must be at least 3 characters' })\n return\n }\n\n setIsChecking(true)\n try {\n const response = await fetch(`/users/check_username?username=${encodeURIComponent(username.toLowerCase())}`)\n const data = await response.json()\n\n if (data.valid) {\n setStatus({ type: 'success', message: 'This username is available! ✨' })\n onChange && onChange(username, true)\n } else {\n setStatus({ type: 'error', message: 'This username is already taken' })\n onChange && onChange(username, false)\n }\n } catch (error) {\n console.error('Error checking username:', error)\n setStatus({ type: 'error', message: 'Error checking username' })\n } finally {\n setIsChecking(false)\n }\n }\n\n const timeoutId = setTimeout(() => {\n if (username) checkUsername()\n }, 500)\n\n return () => clearTimeout(timeoutId)\n }, [username])\n\n const getStatusColor = () => {\n switch (status?.type) {\n case 'success': return 'text-green-600'\n case 'error': return 'text-red-600'\n case 'warning': return 'text-yellow-600'\n default: return ''\n }\n }\n\n return (\n
\n setUsername(e.target.value)}\n placeholder=\"e.g., CuriousLearner22, MathWhiz2024\"\n className=\"rounded-lg border-gray-300 focus:ring-yellow-500 focus:border-yellow-500 w-full text-gray-900\"\n />\n {status && (\n
\n {isChecking ? (\n \n \n \n \n ) : null}\n {status.message}\n
\n )}\n
\n

Username Info:

\n
    \n
  • This will be your display name in the learning world and on the leaderboard
  • \n
  • You can also use this username to sign in to your account
  • \n
  • At least 3 characters long
  • \n
  • Can contain letters, numbers, and underscores
  • \n
  • Cannot contain spaces or special characters
  • \n
  • Will be visible if sharing content
  • \n
\n
\n
\n )\n}\n\nexport default UsernameValidator","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\n\nconst MemoryForm = (props) => {\n const { memoryTypes, initialMemoryType, initialMemoryData, formAction, formMethod, csrfToken, cancelUrl, childName, isEditing } = props;\n const [memoryType, setMemoryType] = useState(initialMemoryType || memoryTypes[0][1]);\n const [memoryData, setMemoryData] = useState(initialMemoryData || '');\n \n const handleMemoryDataChange = (e) => {\n setMemoryData(e.target.value);\n };\n \n const hints = {\n math: \"Describe your child's relationship with math. Are they struggling with specific concepts like fractions or multiplication? Do they excel at certain areas? What approaches help them understand math better?\",\n science: \"Share your child's interests in science. Do they love space, animals, or experiments? Are there specific topics they're curious about or find challenging?\",\n history: \"Note your child's engagement with history. Are they fascinated by certain time periods or historical figures? Do they connect better with history through stories or visual timelines?\",\n language_arts: \"Describe your child's reading and writing abilities. What types of books do they enjoy? Are there specific grammar or vocabulary areas they find difficult?\",\n learning_style: \"How does your child learn best? Do they prefer visual demonstrations, hands-on activities, or verbal explanations? Do they need frequent breaks or prefer to focus for longer periods?\",\n interests: \"What are your child's hobbies, favorite characters, or topics they get excited about? This helps our AI use relevant examples that will engage them.\",\n strengths: \"What subjects or skills does your child excel at? What makes them proud of themselves?\",\n challenges: \"What areas does your child find difficult? Are there specific learning obstacles we should be aware of?\",\n anything: \"Share anything that would help our AI better understand how your child learns and what engages them. This could include interests, learning preferences, or specific needs.\"\n };\n \n const placeholders = {\n math: `For example: ${childName} struggles with fractions but enjoys geometry. They learn math concepts better when using visual aids and real-world examples.`,\n science: `For example: ${childName} is fascinated by dinosaurs and space exploration. They enjoy hands-on experiments but need help understanding scientific terminology.`,\n history: `For example: ${childName} loves learning about ancient Egypt and the Roman Empire. They remember historical events better when presented as stories about people.`,\n language_arts: `For example: ${childName} enjoys reading adventure books but struggles with writing longer essays. They have a strong vocabulary but need help with grammar.`,\n learning_style: `For example: ${childName} is a visual learner who benefits from diagrams and videos. They need frequent breaks during study sessions and prefer learning in a quiet environment.`,\n interests: `For example: ${childName} loves everything about dinosaurs, especially T-Rex and Triceratops. They also enjoy building with Legos and playing Minecraft.`,\n strengths: `For example: ${childName} has a great memory for facts and details. They're particularly good at mental math and creative storytelling.`,\n challenges: `For example: ${childName} finds it difficult to focus for long periods. They struggle with organizing their thoughts when writing and need extra help with spelling.`,\n anything: `For example: ${childName} loves dinosaurs.`\n };\n \n const questions = {\n math: `How does ${childName} feel about math? What concepts do they enjoy or struggle with?`,\n science: `What scientific topics interest ${childName}? How do they prefer to learn about science?`,\n history: `What historical periods or figures fascinate ${childName}? How do they best engage with history?`,\n language_arts: `What are ${childName}'s reading and writing habits? What types of books or writing activities do they enjoy?`,\n learning_style: `How does ${childName} learn most effectively? What environment or teaching approaches work best?`,\n interests: `What topics, activities, or characters does ${childName} get excited about?`,\n strengths: `What subjects or skills does ${childName} excel at? What makes them feel confident?`,\n challenges: `What areas does ${childName} find challenging? How can we better support their learning?`,\n anything: `What would help our AI better understand ${childName}'s unique learning style and interests?`\n };\n \n const handleMemoryTypeChange = (e) => {\n setMemoryType(e.target.value);\n };\n \n return (\n
\n
\n

What would you like to tell us about {childName}?

\n

{questions[memoryType] || questions.anything}

\n
\n \n
\n \n {isEditing && }\n \n
\n
\n \n \n

\n {isEditing ? \n \"Memory category cannot be changed. Delete this memory and create a new one to use a different category.\" : \n \"Select the category that best fits this memory\"}\n

\n
\n \n
\n \n \n
\n \n
\n Suggestion: \n {hints[memoryType] || hints.anything}\n
\n
\n \n
\n \n Cancel\n \n \n
\n
\n
\n );\n};\n\nMemoryForm.propTypes = {\n memoryTypes: PropTypes.array.isRequired,\n initialMemoryType: PropTypes.string,\n initialMemoryData: PropTypes.string,\n formAction: PropTypes.string.isRequired,\n formMethod: PropTypes.string.isRequired,\n csrfToken: PropTypes.string.isRequired,\n cancelUrl: PropTypes.string.isRequired,\n childName: PropTypes.string.isRequired,\n isEditing: PropTypes.bool\n};\n\nMemoryForm.defaultProps = {\n isEditing: false,\n initialMemoryData: \"\"\n};\n\nexport default MemoryForm; ","import React, { useRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\n\n// Constants\nconst CHARACTER_SIZE = 60;\nconst GEM_SIZE = 30;\nconst ENEMY_SIZE = 40;\n\n// Static images\nconst DEFAULT_AVATAR = new Image();\nDEFAULT_AVATAR.src = '/tybee-circle.png';\n\nconst GEM_IMAGE = new Image();\nGEM_IMAGE.src = '/gem.png';\n\nconst GameCanvas = ({\n canvasSize,\n position,\n isMoving,\n wobbleOffset,\n avatarImage,\n modules,\n activeModule,\n getModulePositions,\n gems,\n collectedGems,\n enemies,\n enemySpeedMultiplier,\n isInvulnerable\n}) => {\n const canvasRef = useRef(null);\n\n // Ensure consistent canvas dimensions\n const canvasWidth = 1200;\n const canvasHeight = 700;\n\n // Calculate current multiplier based on collected gems\n const calculateMultiplier = () => {\n if (collectedGems < 10) return 1;\n return 1 + Math.floor(collectedGems / 10);\n };\n\n // Draw the game world\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n // Set canvas dimensions explicitly\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n // Clear the canvas\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Draw background elements (optional)\n // ...\n\n // Draw modules\n const modulePositions = getModulePositions();\n modulePositions.forEach((modulePos, index) => {\n const isRewardsModule = modulePos.isRewards;\n\n // Skip regular modules if we're past the available modules\n if (!isRewardsModule && index >= modules.length) return;\n\n // Skip rewards module for non-authenticated users\n if (isRewardsModule && !avatarImage) return;\n\n // Draw module platform\n ctx.beginPath();\n ctx.arc(modulePos.x, modulePos.y, isRewardsModule ? 40 : 50, 0, Math.PI * 2);\n\n // Different colors for different modules with gradient\n const colors = [\n ['#4299e1', '#3182ce'], // blue\n ['#48bb78', '#38a169'], // green\n ['#ed8936', '#dd6b20'], // orange\n ['#ed64a6', '#d53f8c'], // pink\n ['#667eea', '#5a67d8'], // indigo\n ['#38b2ac', '#319795'], // teal\n ['#f6e05e', '#d69e2e'] // yellow/gold for rewards\n ];\n\n const colorIndex = isRewardsModule ? 6 : (index % 6);\n\n const gradient = ctx.createRadialGradient(\n modulePos.x, modulePos.y, 10,\n modulePos.x, modulePos.y, isRewardsModule ? 40 : 50\n );\n gradient.addColorStop(0, colors[colorIndex][0]);\n gradient.addColorStop(1, colors[colorIndex][1]);\n\n ctx.fillStyle = gradient;\n ctx.fill();\n\n // Glow effect for active module\n if (activeModule === index) {\n ctx.shadowBlur = 15;\n ctx.shadowColor = colors[colorIndex][0];\n }\n\n ctx.lineWidth = activeModule === index ? 4 : 2;\n ctx.strokeStyle = activeModule === index ? '#ffffff' : 'rgba(255, 255, 255, 0.7)';\n ctx.stroke();\n ctx.shadowBlur = 0;\n\n // Draw module text - simplified, cleaner approach\n ctx.fillStyle = '#ffffff';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n if (isRewardsModule) {\n // Draw rewards module label\n ctx.font = 'bold 14px Arial';\n ctx.fillText(\"Rewards\", modulePos.x, modulePos.y);\n\n // Draw a small coin icon\n ctx.font = '16px Arial';\n ctx.fillText(\"🪙\", modulePos.x, modulePos.y - 20);\n } else {\n // Get module title from the modules data\n const moduleTitle = modules[index].title;\n\n // Process the title to fit in the circle\n let displayTitle = moduleTitle;\n\n // If title has multiple words, try to use just the first word if it's too long\n if (moduleTitle.length > 10 && moduleTitle.includes(' ')) {\n const firstWord = moduleTitle.split(' ')[0];\n displayTitle = firstWord.length > 3 ? firstWord : moduleTitle.substring(0, 10);\n }\n // If still too long, truncate\n else if (moduleTitle.length > 10) {\n displayTitle = moduleTitle.substring(0, 8) + '..';\n }\n\n // Draw the module label\n ctx.font = 'bold 16px Arial';\n ctx.fillText(displayTitle, modulePos.x, modulePos.y);\n\n // Add a small icon or indicator for premium modules\n if (modules[index].premium) {\n ctx.font = '12px Arial';\n ctx.fillText('✦', modulePos.x, modulePos.y + 20);\n }\n }\n });\n\n // Draw gems\n gems.forEach(gem => {\n ctx.save();\n ctx.translate(gem.x, gem.y);\n ctx.rotate(gem.rotation);\n\n // Try to draw the jam image\n if (GEM_IMAGE.complete && GEM_IMAGE.naturalHeight !== 0) {\n ctx.drawImage(\n GEM_IMAGE,\n -GEM_SIZE/2,\n -GEM_SIZE/2,\n GEM_SIZE,\n GEM_SIZE\n );\n }\n // Fallback to the original diamond shape if both images fail\n else {\n // Create a diamond/gem shape\n const gemSize = GEM_SIZE / 2;\n ctx.beginPath();\n ctx.moveTo(0, -gemSize);\n ctx.lineTo(gemSize, 0);\n ctx.lineTo(0, gemSize);\n ctx.lineTo(-gemSize, 0);\n ctx.closePath();\n\n // Create a gradient for the gem\n const gemGradient = ctx.createLinearGradient(-gemSize, -gemSize, gemSize, gemSize);\n gemGradient.addColorStop(0, '#9f7aea'); // Purple\n gemGradient.addColorStop(0.5, '#667eea'); // Indigo\n gemGradient.addColorStop(1, '#4299e1'); // Blue\n\n ctx.fillStyle = gemGradient;\n ctx.fill();\n\n // Add a stroke\n ctx.lineWidth = 1;\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';\n ctx.stroke();\n }\n\n // Add a sparkle effect regardless of which rendering method was used\n const sparkleTime = Date.now() / 200;\n if (Math.sin(sparkleTime + gem.id) > 0.7) {\n ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';\n ctx.beginPath();\n ctx.arc(0, 0, 3, 0, Math.PI * 2);\n ctx.fill();\n }\n\n ctx.restore();\n });\n\n // Draw enemies\n enemies.forEach(enemy => {\n if (!enemy.active) return;\n\n ctx.save();\n\n // Draw enemy body\n ctx.beginPath();\n ctx.arc(enemy.x, enemy.y, ENEMY_SIZE/2, 0, Math.PI * 2);\n\n // Create gradient for enemy - color intensity based on speed\n const gradient = ctx.createRadialGradient(\n enemy.x, enemy.y, ENEMY_SIZE/4,\n enemy.x, enemy.y, ENEMY_SIZE/2\n );\n\n // Make enemies glow more intensely as they get faster\n const baseColor = enemy.color;\n const glowIntensity = Math.min(1, (enemySpeedMultiplier - 1) * 2); // 0 to 1 based on speed\n\n // Mix the base color with a brighter color based on speed\n gradient.addColorStop(0, baseColor);\n gradient.addColorStop(1, glowIntensity > 0.3 ? '#ff0000' : '#000');\n\n ctx.fillStyle = gradient;\n ctx.fill();\n\n // Add a glow effect for faster enemies\n if (enemySpeedMultiplier > 1.5) {\n ctx.shadowBlur = 10 * (enemySpeedMultiplier - 1);\n ctx.shadowColor = 'rgba(255, 0, 0, 0.7)';\n ctx.stroke();\n ctx.shadowBlur = 0;\n }\n\n // Draw enemy eyes\n ctx.fillStyle = '#fff';\n\n // Calculate eye positions based on direction to player\n const dx = position.x - enemy.x;\n const dy = position.y - enemy.y;\n const angle = Math.atan2(dy, dx);\n\n const eyeOffsetX = Math.cos(angle) * ENEMY_SIZE/4;\n const eyeOffsetY = Math.sin(angle) * ENEMY_SIZE/4;\n\n // Left eye\n ctx.beginPath();\n ctx.arc(\n enemy.x + eyeOffsetX - Math.sin(angle) * ENEMY_SIZE/5,\n enemy.y + eyeOffsetY + Math.cos(angle) * ENEMY_SIZE/5,\n ENEMY_SIZE/8, 0, Math.PI * 2\n );\n ctx.fill();\n\n // Right eye\n ctx.beginPath();\n ctx.arc(\n enemy.x + eyeOffsetX + Math.sin(angle) * ENEMY_SIZE/5,\n enemy.y + eyeOffsetY - Math.cos(angle) * ENEMY_SIZE/5,\n ENEMY_SIZE/8, 0, Math.PI * 2\n );\n ctx.fill();\n\n ctx.restore();\n });\n\n // Draw character shadow\n const drawX = position.x;\n const drawY = position.y + wobbleOffset;\n\n // Draw oval shadow under character\n ctx.beginPath();\n const shadowWidth = CHARACTER_SIZE/2 * (1 + Math.abs(wobbleOffset/20));\n const shadowHeight = CHARACTER_SIZE/6 * (1 - Math.abs(wobbleOffset/20));\n ctx.ellipse(position.x, position.y + CHARACTER_SIZE/2 - 5, shadowWidth, shadowHeight, 0, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';\n ctx.fill();\n\n // Draw character with invulnerability effect if needed\n if (isInvulnerable) {\n // Flashing shield effect\n const shieldOpacity = 0.3 + Math.sin(Date.now() / 100) * 0.2;\n ctx.beginPath();\n ctx.arc(position.x, position.y, CHARACTER_SIZE/2 + 10, 0, Math.PI * 2);\n ctx.fillStyle = `rgba(100, 149, 237, ${shieldOpacity})`;\n ctx.fill();\n }\n\n // Draw character\n if (avatarImage) {\n // Draw avatar image with circular crop and wobble\n ctx.save();\n ctx.beginPath();\n ctx.arc(drawX, drawY, CHARACTER_SIZE/2, 0, Math.PI * 2);\n ctx.closePath();\n ctx.clip();\n\n ctx.drawImage(\n avatarImage,\n drawX - CHARACTER_SIZE/2,\n drawY - CHARACTER_SIZE/2,\n CHARACTER_SIZE,\n CHARACTER_SIZE\n );\n\n ctx.restore();\n\n // Draw border around avatar\n ctx.beginPath();\n ctx.arc(drawX, drawY, CHARACTER_SIZE/2, 0, Math.PI * 2);\n ctx.lineWidth = 3;\n ctx.strokeStyle = isInvulnerable ? '#4299e1' : '#3867d6';\n ctx.stroke();\n } else {\n // Use the static default avatar if available\n if (DEFAULT_AVATAR.complete && DEFAULT_AVATAR.naturalHeight !== 0) {\n ctx.save();\n ctx.beginPath();\n ctx.arc(drawX, drawY, CHARACTER_SIZE/2, 0, Math.PI * 2);\n ctx.closePath();\n ctx.clip();\n\n ctx.drawImage(\n DEFAULT_AVATAR,\n drawX - CHARACTER_SIZE/2,\n drawY - CHARACTER_SIZE/2,\n CHARACTER_SIZE,\n CHARACTER_SIZE\n );\n\n ctx.restore();\n\n // Draw border around avatar\n ctx.beginPath();\n ctx.arc(drawX, drawY, CHARACTER_SIZE/2, 0, Math.PI * 2);\n ctx.lineWidth = 3;\n ctx.strokeStyle = isInvulnerable ? '#4299e1' : '#3867d6';\n ctx.stroke();\n } else {\n // Fallback to circle if image not loaded\n ctx.beginPath();\n ctx.arc(drawX, drawY, CHARACTER_SIZE/2, 0, Math.PI * 2);\n ctx.fillStyle = isInvulnerable ? '#4299e1' : '#4b7bec';\n ctx.fill();\n ctx.lineWidth = 3;\n ctx.strokeStyle = isInvulnerable ? '#4299e1' : '#3867d6';\n ctx.stroke();\n\n // Draw character face\n ctx.fillStyle = '#ffffff';\n ctx.beginPath();\n ctx.arc(drawX - 10, drawY - 5, 6, 0, Math.PI * 2); // Left eye\n ctx.arc(drawX + 10, drawY - 5, 6, 0, Math.PI * 2); // Right eye\n ctx.fill();\n\n ctx.beginPath();\n ctx.arc(drawX, drawY + 10, 10, 0, Math.PI); // Smile\n ctx.stroke();\n }\n }\n\n // Draw gem counter and multiplier\n ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';\n ctx.fillRect(10, 10, 120, 40);\n\n // Draw gem count\n ctx.fillStyle = '#9f7aea'; // Purple color for gems\n ctx.font = 'bold 20px Arial';\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n ctx.fillText(`Gems: ${collectedGems}`, 20, 30);\n\n // Draw high score in the middle top\n ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';\n ctx.fillRect(canvas.width/2 - 150, 10, 300, 40);\n\n // Get the high score from localStorage or use current score if higher\n const storedHighScore = parseInt(localStorage.getItem('tyb_high_score') || '0');\n const currentHighScore = Math.max(storedHighScore, collectedGems);\n\n // Update localStorage if we have a new high score\n if (collectedGems > storedHighScore) {\n localStorage.setItem('tyb_high_score', collectedGems.toString());\n }\n\n // Draw trophy icon\n ctx.fillStyle = '#f6e05e'; // Gold color for trophy\n ctx.beginPath();\n const trophyX = canvas.width/2 - 70;\n const trophyY = 30;\n // Trophy cup\n ctx.moveTo(trophyX - 8, trophyY - 8);\n ctx.lineTo(trophyX + 8, trophyY - 8);\n ctx.lineTo(trophyX + 6, trophyY);\n ctx.lineTo(trophyX - 6, trophyY);\n ctx.closePath();\n ctx.fill();\n // Trophy base\n ctx.fillRect(trophyX - 3, trophyY, 6, 8);\n ctx.fillRect(trophyX - 6, trophyY + 8, 12, 2);\n\n // Draw high score text\n ctx.fillStyle = '#f6e05e'; // Gold color for high score\n ctx.font = 'bold 20px Arial';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(`High Score: ${currentHighScore}`, canvas.width/2 + 30, 30);\n\n // Draw leaderboard button at bottom left\n ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';\n ctx.fillRect(20, canvas.height - 60, 180, 40);\n\n // Draw trophy icon for leaderboard\n ctx.fillStyle = '#f6e05e'; // Gold color for trophy\n ctx.beginPath();\n const leaderboardTrophyX = 40;\n const leaderboardTrophyY = canvas.height - 40;\n // Trophy cup\n ctx.moveTo(leaderboardTrophyX - 8, leaderboardTrophyY - 8);\n ctx.lineTo(leaderboardTrophyX + 8, leaderboardTrophyY - 8);\n ctx.lineTo(leaderboardTrophyX + 6, leaderboardTrophyY);\n ctx.lineTo(leaderboardTrophyX - 6, leaderboardTrophyY);\n ctx.closePath();\n ctx.fill();\n // Trophy base\n ctx.fillRect(leaderboardTrophyX - 3, leaderboardTrophyY, 6, 8);\n ctx.fillRect(leaderboardTrophyX - 6, leaderboardTrophyY + 8, 12, 2);\n\n // Draw leaderboard text\n ctx.fillStyle = '#9f7aea'; // Purple color for leaderboard\n ctx.font = 'bold 16px Arial';\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n ctx.fillText('View Leaderboard', 60, canvas.height - 40);\n\n // Update click handler for leaderboard\n canvas.onclick = (e) => {\n const rect = canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n // Check if click is within the leaderboard button area\n if (x >= 20 && x <= 200 && y >= canvas.height - 60 && y <= canvas.height - 20) {\n window.location.href = '/game_leaderboard';\n }\n };\n\n // Draw multiplier if applicable\n const multiplier = calculateMultiplier();\n if (multiplier > 1) {\n ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';\n ctx.fillRect(140, 10, 140, 40);\n\n ctx.fillStyle = '#f6e05e'; // Gold color for multiplier\n ctx.font = 'bold 20px Arial';\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n ctx.fillText(`${multiplier}x Coins!`, 150, 30);\n }\n\n }, [canvasSize, position, isMoving, wobbleOffset, avatarImage, modules, activeModule, getModulePositions, gems, collectedGems, enemies, enemySpeedMultiplier, isInvulnerable]);\n\n return (\n \n );\n};\n\nGameCanvas.propTypes = {\n canvasSize: PropTypes.object.isRequired,\n position: PropTypes.object.isRequired,\n isMoving: PropTypes.bool.isRequired,\n wobbleOffset: PropTypes.number.isRequired,\n avatarImage: PropTypes.object,\n modules: PropTypes.array.isRequired,\n activeModule: PropTypes.number,\n getModulePositions: PropTypes.func.isRequired,\n gems: PropTypes.array.isRequired,\n collectedGems: PropTypes.number.isRequired,\n enemies: PropTypes.array,\n enemySpeedMultiplier: PropTypes.number,\n isInvulnerable: PropTypes.bool\n};\n\nGameCanvas.defaultProps = {\n enemies: [],\n enemySpeedMultiplier: 1.0,\n isInvulnerable: false\n};\n\nexport default GameCanvas;","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nconst Instructions = ({ currentUser }) => {\n const [showInstructions, setShowInstructions] = useState(false);\n\n const toggleInstructions = () => {\n setShowInstructions(!showInstructions);\n };\n\n return (\n <>\n {/* Help button */}\n \n \n \n \n \n\n {/* Instructions panel */}\n {showInstructions && (\n
\n
\n

How to Play

\n\n
\n
\n

Movement

\n

Use the arrow keys or WASD to move your character around the world.

\n
\n\n
\n

Learning Modules

\n

Move close to a learning module and press Enter to explore that feature.

\n
\n\n {currentUser ? (\n <>\n
\n

Collect Gems

\n

Collect the sparkling gems to earn coin multipliers:

\n
    \n
  • Every 10 gems = 2x coin multiplier
  • \n
  • Every 20 gems = 3x coin multiplier
  • \n
  • Every 30 gems = 4x coin multiplier
  • \n
  • And so on!
  • \n
\n

Start a chat with gems collected to boost your coin rewards!

\n
\n\n
\n

Watch Out!

\n

Avoid the colored enemies. If they catch you, you'll lose all your collected gems!

\n
\n \n ) : (\n <>\n
\n

Collect Gems

\n

Collect the sparkling gems to earn points and compete for a high score!

\n
\n\n
\n

Watch Out!

\n

Avoid the colored enemies. If they catch you, you'll lose all your collected gems!

\n
\n\n
\n

Sign Up for More!

\n

Create an account to unlock all learning features and save your progress!

\n
\n \n )}\n
\n\n \n Got it!\n \n
\n
\n )}\n \n );\n};\n\nInstructions.propTypes = {\n currentUser: PropTypes.object\n};\n\nexport default Instructions;","import { useState, useEffect, useRef, useCallback } from 'react';\n\n// Constants\nconst SPEED = 5;\nconst CHARACTER_SIZE = 60;\nconst GEM_SIZE = 30;\nconst GEM_SPEED = 2;\nconst GEM_COUNT = 5;\nconst GEM_COLLECTION_DISTANCE = 40;\nconst ENEMY_SIZE = 40;\nconst INITIAL_ENEMY_COUNT = 1; // Start with just one enemy\nconst GEMS_PER_NEW_ENEMY = 5; // Add a new enemy every 5 gems\nconst BASE_ENEMY_SPEED = 1.5;\nconst ENEMY_SPEED_INCREMENT = 0.1; // Speed increase per gem collected\nconst MAX_ENEMY_SPEED = 4.0; // Cap on enemy speed\nconst ENEMY_CATCH_DISTANCE = 50;\nconst ENEMY_RESPAWN_TIME = 3000; // 3 seconds\n\nexport const useGameState = () => {\n const [position, setPosition] = useState({ x: 400, y: 300 });\n const [keys, setKeys] = useState({});\n const [canvasSize, setCanvasSize] = useState({ width: 800, height: 600 });\n const [isMoving, setIsMoving] = useState(false);\n const [wobbleOffset, setWobbleOffset] = useState(0);\n const [gems, setGems] = useState([]);\n const [collectedGems, setCollectedGems] = useState(0);\n const [enemies, setEnemies] = useState([]);\n const [activeEnemyCount, setActiveEnemyCount] = useState(INITIAL_ENEMY_COUNT);\n const [enemySpeedMultiplier, setEnemySpeedMultiplier] = useState(1.0);\n const [isInvulnerable, setIsInvulnerable] = useState(false);\n const lastMoveTimeRef = useRef(0);\n const animationFrameRef = useRef(0);\n\n // Initialize gems and enemies when canvas size changes\n useEffect(() => {\n if (canvasSize.width === 0 || canvasSize.height === 0) return;\n\n // Initialize gems\n const newGems = [];\n for (let i = 0; i < GEM_COUNT; i++) {\n newGems.push({\n id: i,\n x: Math.random() * (canvasSize.width - GEM_SIZE * 2) + GEM_SIZE,\n y: Math.random() * (canvasSize.height - GEM_SIZE * 2) + GEM_SIZE,\n vx: (Math.random() - 0.5) * GEM_SPEED * 2,\n vy: (Math.random() - 0.5) * GEM_SPEED * 2,\n rotation: 0,\n rotationSpeed: (Math.random() * 0.05 + 0.03) * (Math.random() < 0.5 ? -1 : 1) // Faster rotation, random direction\n });\n }\n setGems(newGems);\n\n // Initialize enemies with just the initial count\n const newEnemies = [];\n for (let i = 0; i < INITIAL_ENEMY_COUNT; i++) {\n newEnemies.push(createEnemy(i, canvasSize));\n }\n setEnemies(newEnemies);\n }, [canvasSize]);\n\n // Helper function to create a new enemy\n const createEnemy = (id, canvasSize, isActive = true) => {\n // Place enemies at the edges of the screen\n const edge = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left\n let x, y;\n\n switch (edge) {\n case 0: // top\n x = Math.random() * canvasSize.width;\n y = -ENEMY_SIZE;\n break;\n case 1: // right\n x = canvasSize.width + ENEMY_SIZE;\n y = Math.random() * canvasSize.height;\n break;\n case 2: // bottom\n x = Math.random() * canvasSize.width;\n y = canvasSize.height + ENEMY_SIZE;\n break;\n case 3: // left\n x = -ENEMY_SIZE;\n y = Math.random() * canvasSize.height;\n break;\n }\n\n // Generate a color based on the enemy ID\n const colors = ['#e53e3e', '#dd6b20', '#805ad5', '#38a169', '#3182ce', '#d53f8c', '#9f7aea', '#667eea'];\n const colorIndex = id % colors.length;\n\n return {\n id,\n x,\n y,\n baseSpeed: BASE_ENEMY_SPEED * (0.8 + Math.random() * 0.4), // Slight speed variation\n color: colors[colorIndex],\n active: isActive,\n wiggle: Math.random() * Math.PI * 2 // Random starting phase for wiggle\n };\n };\n\n // Update active enemy count based on collected gems\n useEffect(() => {\n const newActiveCount = INITIAL_ENEMY_COUNT + Math.floor(collectedGems / GEMS_PER_NEW_ENEMY);\n\n if (newActiveCount !== activeEnemyCount) {\n setActiveEnemyCount(newActiveCount);\n\n // Check if we need to add more enemies\n setEnemies(prevEnemies => {\n let updatedEnemies = [...prevEnemies];\n\n // If we need more enemies than we currently have, create new ones\n if (newActiveCount > updatedEnemies.length) {\n const enemiesToAdd = newActiveCount - updatedEnemies.length;\n\n for (let i = 0; i < enemiesToAdd; i++) {\n const newEnemyId = updatedEnemies.length;\n updatedEnemies.push(createEnemy(newEnemyId, canvasSize));\n }\n }\n // Otherwise, activate existing inactive enemies\n else {\n updatedEnemies = updatedEnemies.map((enemy, index) => {\n if (index < newActiveCount && !enemy.active && !isInvulnerable) {\n // Reposition at a random edge\n const newEnemy = createEnemy(enemy.id, canvasSize);\n return {\n ...enemy,\n x: newEnemy.x,\n y: newEnemy.y,\n active: true\n };\n }\n return enemy;\n });\n }\n\n return updatedEnemies;\n });\n }\n }, [collectedGems, activeEnemyCount, canvasSize, isInvulnerable]);\n\n // Handle key down event\n const handleKeyDown = useCallback((e) => {\n if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'w', 'a', 's', 'd'].includes(e.key)) {\n e.preventDefault();\n setKeys((prevKeys) => ({ ...prevKeys, [e.key]: true }));\n setIsMoving(true);\n lastMoveTimeRef.current = Date.now();\n }\n }, []);\n\n // Handle key up event\n const handleKeyUp = useCallback((e) => {\n setKeys((prevKeys) => ({ ...prevKeys, [e.key]: false }));\n\n // Check if any movement keys are still pressed\n setTimeout(() => {\n const anyMovementKeyPressed = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'w', 'a', 's', 'd']\n .some(key => keys[key]);\n\n if (!anyMovementKeyPressed) {\n setIsMoving(false);\n }\n }, 10);\n }, [keys]);\n\n // Handle character movement, gem collection, and enemy movement\n useEffect(() => {\n const gameLoop = setInterval(() => {\n // Update player position\n setPosition((prevPos) => {\n let newX = prevPos.x;\n let newY = prevPos.y;\n let moved = false;\n\n if (keys['ArrowUp'] || keys['w']) {\n newY -= SPEED;\n moved = true;\n }\n if (keys['ArrowDown'] || keys['s']) {\n newY += SPEED;\n moved = true;\n }\n if (keys['ArrowLeft'] || keys['a']) {\n newX -= SPEED;\n moved = true;\n }\n if (keys['ArrowRight'] || keys['d']) {\n newX += SPEED;\n moved = true;\n }\n\n // Update last move time if character moved\n if (moved) {\n lastMoveTimeRef.current = Date.now();\n } else if (Date.now() - lastMoveTimeRef.current > 100) {\n setIsMoving(false);\n }\n\n // Boundary checks\n newX = Math.max(CHARACTER_SIZE/2, Math.min(canvasSize.width - CHARACTER_SIZE/2, newX));\n newY = Math.max(CHARACTER_SIZE/2, Math.min(canvasSize.height - CHARACTER_SIZE/2, newY));\n\n return { x: newX, y: newY };\n });\n\n // Update gems\n setGems(prevGems => {\n let gemsCollected = 0;\n\n const updatedGems = prevGems.map(gem => {\n // Check if player collected this gem\n const dx = position.x - gem.x;\n const dy = position.y - gem.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance < GEM_COLLECTION_DISTANCE) {\n gemsCollected++;\n\n // Increase enemy speed when a gem is collected\n setEnemySpeedMultiplier(prev => {\n const newMultiplier = prev + ENEMY_SPEED_INCREMENT;\n // Cap the speed multiplier to prevent enemies from becoming too fast\n return Math.min(newMultiplier, MAX_ENEMY_SPEED / BASE_ENEMY_SPEED);\n });\n\n // Respawn gem at a random position\n return {\n ...gem,\n x: Math.random() * (canvasSize.width - GEM_SIZE * 2) + GEM_SIZE,\n y: Math.random() * (canvasSize.height - GEM_SIZE * 2) + GEM_SIZE,\n vx: (Math.random() - 0.5) * GEM_SPEED * 2,\n vy: (Math.random() - 0.5) * GEM_SPEED * 2,\n rotation: 0,\n rotationSpeed: (Math.random() * 0.05 + 0.03) * (Math.random() < 0.5 ? -1 : 1) // Faster rotation for respawned gems\n };\n }\n\n // Update gem position\n let newX = gem.x + gem.vx;\n let newY = gem.y + gem.vy;\n let newVx = gem.vx;\n let newVy = gem.vy;\n let newRotation = gem.rotation + gem.rotationSpeed;\n\n // Bounce off walls\n if (newX < GEM_SIZE/2 || newX > canvasSize.width - GEM_SIZE/2) {\n newVx = -newVx;\n newX = Math.max(GEM_SIZE/2, Math.min(canvasSize.width - GEM_SIZE/2, newX));\n }\n if (newY < GEM_SIZE/2 || newY > canvasSize.height - GEM_SIZE/2) {\n newVy = -newVy;\n newY = Math.max(GEM_SIZE/2, Math.min(canvasSize.height - GEM_SIZE/2, newY));\n }\n\n // Add this code to make gems avoid the player\n if (distance < 100 && distance > GEM_COLLECTION_DISTANCE) {\n // Calculate repulsion vector (away from player)\n const repelX = (gem.x - position.x) * 0.01;\n const repelY = (gem.y - position.y) * 0.01;\n\n // Apply repulsion to velocity\n newVx += repelX;\n newVy += repelY;\n\n // Limit max velocity\n const speed = Math.sqrt(newVx * newVx + newVy * newVy);\n if (speed > GEM_SPEED * 2) {\n newVx = (newVx / speed) * GEM_SPEED * 2;\n newVy = (newVy / speed) * GEM_SPEED * 2;\n }\n }\n\n return {\n ...gem,\n x: newX,\n y: newY,\n vx: newVx,\n vy: newVy,\n rotation: newRotation\n };\n });\n\n if (gemsCollected > 0) {\n setCollectedGems(prev => prev + gemsCollected);\n }\n\n return updatedGems;\n });\n\n // Update enemies\n setEnemies(prevEnemies => {\n let playerCaught = false;\n\n const updatedEnemies = prevEnemies.map((enemy, index) => {\n // Skip inactive enemies\n if (!enemy.active) {\n // Check if it's time to respawn\n if (enemy.respawnTime && Date.now() - enemy.respawnTime > ENEMY_RESPAWN_TIME) {\n // Only respawn if this enemy should be active based on current activeEnemyCount\n if (index < activeEnemyCount) {\n // Create a new enemy at a random edge\n const newEnemy = createEnemy(enemy.id, canvasSize);\n return {\n ...enemy,\n x: newEnemy.x,\n y: newEnemy.y,\n active: true,\n respawnTime: null\n };\n }\n }\n return enemy;\n }\n\n // Update enemy position to chase player\n const dx = position.x - enemy.x;\n const dy = position.y - enemy.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Check if enemy caught player\n if (distance < ENEMY_CATCH_DISTANCE && !isInvulnerable) {\n playerCaught = true;\n }\n\n // Move enemy towards player with some wiggle\n const angle = Math.atan2(dy, dx);\n const wiggleAmount = Math.sin(enemy.wiggle) * 0.2;\n const moveAngle = angle + wiggleAmount;\n\n // Calculate current speed with multiplier\n const currentSpeed = enemy.baseSpeed * enemySpeedMultiplier;\n\n // Update wiggle phase\n const newWiggle = enemy.wiggle + 0.1;\n\n return {\n ...enemy,\n x: enemy.x + Math.cos(moveAngle) * currentSpeed,\n y: enemy.y + Math.sin(moveAngle) * currentSpeed,\n wiggle: newWiggle\n };\n });\n\n // If player was caught, reset gems and make player temporarily invulnerable\n if (playerCaught && !isInvulnerable) {\n // Save high score to localStorage\n const storedHighScore = parseInt(localStorage.getItem('tyb_high_score') || '0');\n if (collectedGems > storedHighScore) {\n localStorage.setItem('tyb_high_score', collectedGems.toString());\n }\n\n // Send gem count to server\n fetch('/api/v1/user_rewards/update_gem_count', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': document.querySelector('meta[name=\"csrf-token\"]')?.getAttribute('content')\n },\n body: JSON.stringify({ gem_count: collectedGems })\n })\n .then(response => response.json())\n .then(data => {\n console.log('Gem count saved:', data);\n })\n .catch(error => {\n console.error('Error saving gem count:', error);\n });\n\n setCollectedGems(0);\n setIsInvulnerable(true);\n\n // Reset enemy speed multiplier when caught\n setEnemySpeedMultiplier(1.0);\n\n // Reset active enemy count to initial\n setActiveEnemyCount(INITIAL_ENEMY_COUNT);\n\n // Reset enemies to edges\n const resetEnemies = updatedEnemies.map((enemy, index) => ({\n ...enemy,\n active: index < INITIAL_ENEMY_COUNT ? false : false, // Keep only initial enemies, deactivate the rest\n respawnTime: Date.now()\n }));\n\n // Set timeout to remove invulnerability\n setTimeout(() => {\n setIsInvulnerable(false);\n }, 3000);\n\n return resetEnemies;\n }\n\n return updatedEnemies;\n });\n }, 1000 / 60); // 60 FPS\n\n return () => clearInterval(gameLoop);\n }, [keys, position, canvasSize, isInvulnerable, enemySpeedMultiplier, activeEnemyCount]);\n\n // South Park style wobble animation\n useEffect(() => {\n const wobbleAnimation = () => {\n if (isMoving) {\n setWobbleOffset(prev => {\n // Oscillate between -5 and 5\n const newOffset = prev + 0.5;\n return newOffset > 5 ? -5 : newOffset;\n });\n } else {\n // Reset wobble when not moving\n setWobbleOffset(0);\n }\n\n animationFrameRef.current = requestAnimationFrame(wobbleAnimation);\n };\n\n animationFrameRef.current = requestAnimationFrame(wobbleAnimation);\n\n return () => {\n cancelAnimationFrame(animationFrameRef.current);\n };\n }, [isMoving]);\n\n return {\n position,\n setPosition,\n keys,\n setKeys,\n canvasSize,\n setCanvasSize,\n isMoving,\n setIsMoving,\n wobbleOffset,\n gems,\n collectedGems,\n enemies,\n activeEnemyCount,\n enemySpeedMultiplier,\n isInvulnerable,\n handleKeyDown,\n handleKeyUp\n };\n};","import React, { useState, useEffect, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport GameCanvas from './GameCanvas';\nimport Instructions from './Instructions';\nimport { useGameState } from '../hooks/useGameState';\nimport { useModules } from '../hooks/useModules';\nimport { useAvatar } from '../hooks/useAvatar';\n\nconst LearningWorld = ({ modules = [], currentUser, csrfToken }) => {\n const containerRef = useRef(null);\n const [isMobile, setIsMobile] = useState(false);\n\n // Make currentUser available globally for API calls\n useEffect(() => {\n window.currentUser = currentUser;\n }, [currentUser]);\n\n const {\n canvasSize,\n setCanvasSize,\n position,\n setPosition,\n isMoving,\n wobbleOffset,\n keys,\n setKeys,\n handleKeyDown,\n handleKeyUp,\n gems,\n collectedGems,\n enemies,\n enemySpeedMultiplier,\n isInvulnerable\n } = useGameState();\n\n // Check if device is mobile but don't redirect\n useEffect(() => {\n const checkMobile = () => {\n const isMobileDevice = window.innerWidth < 768 ||\n /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n setIsMobile(isMobileDevice);\n };\n\n checkMobile();\n window.addEventListener('resize', checkMobile);\n return () => window.removeEventListener('resize', checkMobile);\n }, []);\n\n // Make collected gems available to other components\n useEffect(() => {\n window.collectedGems = collectedGems;\n }, [collectedGems]);\n\n const {\n localModules,\n activeModule,\n getModulePositions,\n handleModuleClick\n } = useModules(modules, position, canvasSize, currentUser);\n\n const { avatarImage } = useAvatar(currentUser);\n\n // Update canvas size on mount and window resize\n useEffect(() => {\n const updateCanvasSize = () => {\n if (containerRef.current) {\n // Use a fixed width for consistency between public and authenticated versions\n const width = 1200; // Fixed width for consistency\n const height = 700; // Fixed height for consistency\n setCanvasSize({ width, height });\n setPosition(prev => ({ ...prev, x: width / 2, y: height / 2 }));\n }\n };\n\n setTimeout(updateCanvasSize, 100);\n window.addEventListener('resize', updateCanvasSize);\n return () => window.removeEventListener('resize', updateCanvasSize);\n }, []);\n\n // Set up keyboard listeners\n useEffect(() => {\n window.addEventListener('keydown', handleKeyDown);\n window.addEventListener('keyup', handleKeyUp);\n\n // Add Enter key handler for module activation\n const handleEnterKey = (e) => {\n if (e.key === 'Enter' && activeModule !== null) {\n handleModuleClick();\n }\n };\n\n window.addEventListener('keydown', handleEnterKey);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('keyup', handleKeyUp);\n window.removeEventListener('keydown', handleEnterKey);\n };\n }, [handleKeyDown, handleKeyUp, activeModule, handleModuleClick]);\n\n // If on mobile, show mobile-optimized version\n if (isMobile) {\n return (\n
\n \n\n {/* Mobile Controls */}\n
\n
\n setKeys(prev => ({ ...prev, ArrowLeft: true }))}\n onTouchEnd={() => setKeys(prev => ({ ...prev, ArrowLeft: false }))}\n >\n ←\n \n setKeys(prev => ({ ...prev, ArrowUp: true }))}\n onTouchEnd={() => setKeys(prev => ({ ...prev, ArrowUp: false }))}\n >\n ↑\n \n setKeys(prev => ({ ...prev, ArrowRight: true }))}\n onTouchEnd={() => setKeys(prev => ({ ...prev, ArrowRight: false }))}\n >\n →\n \n
\n setKeys(prev => ({ ...prev, ArrowDown: true }))}\n onTouchEnd={() => setKeys(prev => ({ ...prev, ArrowDown: false }))}\n >\n ↓\n \n
\n
\n \n ✓\n \n
\n\n \n\n {/* Navigation button */}\n \n
\n );\n }\n\n if (!localModules || !Array.isArray(localModules) || localModules.length === 0) {\n return (\n
\n

Learning World

\n

No learning modules available

\n \n
\n );\n }\n\n return (\n \n \n\n \n\n {/* Navigation button */}\n
\n {currentUser ? (\n \n Switch to Classic View\n \n ) : (\n \n Back to Home\n \n )}\n
\n
\n );\n};\n\nLearningWorld.propTypes = {\n modules: PropTypes.array,\n currentUser: PropTypes.object,\n csrfToken: PropTypes.string\n};\n\nexport default LearningWorld;","import { useState, useEffect, useRef } from 'react';\n\nexport const useModules = (modules, position, canvasSize, currentUser) => {\n const [localModules, setLocalModules] = useState([]);\n const [activeModule, setActiveModule] = useState(null);\n const modulesLoaded = useRef(false);\n\n // Try to get modules from debug info if props are empty - only once\n useEffect(() => {\n if (modulesLoaded.current) return;\n\n if (modules && Array.isArray(modules) && modules.length > 0) {\n setLocalModules(modules);\n modulesLoaded.current = true;\n } else {\n console.log(\"Modules array is empty, trying to get data from debug element\");\n const debugElement = document.getElementById('debug-info');\n if (debugElement) {\n try {\n const debugData = JSON.parse(debugElement.textContent);\n console.log(\"Found modules in debug element:\", debugData);\n setLocalModules(debugData);\n modulesLoaded.current = true;\n } catch (e) {\n console.error(\"Error parsing debug data:\", e);\n }\n }\n }\n }, [modules]);\n\n // Calculate module positions based on canvas size\n const getModulePositions = () => {\n if (!localModules || localModules.length === 0) return [];\n\n // Regular learning modules positions\n const positions = [\n { x: canvasSize.width * 0.2, y: canvasSize.height * 0.3 },\n { x: canvasSize.width * 0.5, y: canvasSize.height * 0.2 },\n { x: canvasSize.width * 0.8, y: canvasSize.height * 0.3 },\n { x: canvasSize.width * 0.2, y: canvasSize.height * 0.7 },\n { x: canvasSize.width * 0.5, y: canvasSize.height * 0.8 },\n { x: canvasSize.width * 0.8, y: canvasSize.height * 0.7 },\n ].slice(0, localModules.length);\n\n // Only add rewards module for authenticated users\n if (currentUser) {\n positions.push({ x: canvasSize.width * 0.9, y: canvasSize.height * 0.9, isRewards: true });\n }\n\n return positions;\n };\n\n // Check if near any module\n useEffect(() => {\n if (!localModules || localModules.length === 0) return;\n\n const modulePositions = getModulePositions();\n let nearestModule = null;\n let nearestDistance = Infinity;\n\n modulePositions.forEach((modulePos, index) => {\n const dx = position.x - modulePos.x;\n const dy = position.y - modulePos.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use a smaller interaction radius for the rewards module\n const interactionRadius = modulePos.isRewards ? 80 : 100;\n\n if (distance < interactionRadius && distance < nearestDistance) {\n nearestModule = index;\n nearestDistance = distance;\n }\n });\n\n if (nearestModule !== activeModule) {\n setActiveModule(nearestModule);\n }\n }, [position, localModules, canvasSize, activeModule]);\n\n const handleModuleClick = () => {\n if (activeModule !== null && localModules[activeModule]) {\n const module = localModules[activeModule];\n\n // For non-authenticated users, just navigate to the target URL without gem multipliers\n if (!currentUser) {\n window.location.href = module.path;\n return;\n }\n\n // For authenticated users, include gem multipliers\n const gemCount = window.collectedGems || 0;\n const multiplier = Math.max(1, Math.floor(gemCount / 10) + 1);\n\n // Add the multiplier as a URL parameter\n let targetUrl = module.path;\n const separator = targetUrl.includes('?') ? '&' : '?';\n targetUrl = `${targetUrl}${separator}gem_multiplier=${multiplier}&gems=${gemCount}`;\n\n // Navigate to the module with the multiplier\n window.location.href = targetUrl;\n }\n };\n\n return {\n localModules,\n activeModule,\n setActiveModule,\n getModulePositions,\n handleModuleClick\n };\n};","import { useState, useEffect } from 'react';\n\nexport const useAvatar = (currentUser) => {\n const [avatarImage, setAvatarImage] = useState(null);\n\n // Load avatar image\n useEffect(() => {\n console.log(\"Loading avatar image for user:\", currentUser);\n\n // Default avatar path - use a path that definitely exists in your assets\n const defaultAvatarPath = '/tybee-circle.png';\n\n // Function to load avatar from URL\n const loadAvatarFromUrl = (url) => {\n console.log(\"Attempting to load avatar from:\", url);\n const img = new Image();\n img.src = url;\n\n img.onload = () => {\n console.log(\"Avatar image loaded successfully from:\", url);\n setAvatarImage(img);\n };\n\n img.onerror = (error) => {\n console.error(\"Error loading avatar image from:\", url, error);\n loadDefaultAvatar();\n };\n };\n\n // Function to load the default avatar\n const loadDefaultAvatar = () => {\n console.log(\"Loading default avatar from:\", defaultAvatarPath);\n const defaultImg = new Image();\n defaultImg.src = defaultAvatarPath;\n defaultImg.onload = () => {\n console.log(\"Default avatar loaded successfully\");\n setAvatarImage(defaultImg);\n };\n defaultImg.onerror = (error) => {\n console.error(\"Error loading default avatar:\", error);\n };\n };\n\n // Try to get user from debug info if props are empty\n if (!currentUser || typeof currentUser !== 'object') {\n console.log(\"No current user in props, trying to get from debug element\");\n const userDebugElement = document.getElementById('user-debug-info');\n if (userDebugElement) {\n try {\n const userData = JSON.parse(userDebugElement.textContent);\n console.log(\"Found user in debug element:\", userData);\n\n // Check for avatar URL in the parsed user data\n if (userData && userData.avatar) {\n loadAvatarFromUrl(userData.avatar);\n return;\n }\n } catch (e) {\n console.error(\"Error parsing user debug data:\", e);\n }\n }\n loadDefaultAvatar();\n return;\n }\n\n // If we have a user with an avatar, load it\n if (currentUser.avatar) {\n loadAvatarFromUrl(currentUser.avatar);\n } else {\n loadDefaultAvatar();\n }\n }, [currentUser]);\n\n return { avatarImage };\n};\n","// Action Cable provides the framework to deal with WebSockets in Rails.\n// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.\n\nimport { createConsumer } from \"@rails/actioncable\"\n\nexport default createConsumer()","// NOTE: This file is not being used. We're using a custom event system instead.\n// Keeping this file for reference in case we want to switch to Action Cable in the future.\n\nimport consumer from \"./consumer\"\n\n// This file is not needed for our implementation since we're subscribing directly in the React component\n// But we'll create it for completeness\n\n/*\nconsumer.subscriptions.create(\"CoinChannel\", {\n connected() {\n // Called when the subscription is ready for use on the server\n },\n\n disconnected() {\n // Called when the subscription has been terminated by the server\n },\n\n received(data) {\n // Called when there's incoming data on the websocket for this channel\n }\n});\n*/\n\n// Create a subscription for the coin channel\n// This will be used to receive real-time coin updates\nconst createCoinSubscription = (userId) => {\n console.log('Creating coin subscription for userId:', userId);\n\n // Don't create a subscription if userId is missing\n if (!userId) {\n console.warn('Cannot create coin subscription: userId is missing');\n return { unsubscribe: () => {} }; // Return a dummy object with unsubscribe method\n }\n\n // Convert userId to a number if it's not already\n const parsedUserId = typeof userId === 'number' ? userId : parseInt(userId, 10);\n console.log('Parsed userId:', parsedUserId);\n\n try {\n const subscription = consumer.subscriptions.create(\n {\n channel: \"CoinChannel\",\n user_id: parsedUserId\n },\n {\n connected() {\n // Called when the subscription is ready for use on the server\n console.log(\"Connected to CoinChannel for user\", parsedUserId);\n },\n\n disconnected() {\n // Called when the subscription has been terminated by the server\n console.log(\"Disconnected from CoinChannel\");\n },\n\n received(data) {\n // Called when there's incoming data on the websocket for this channel\n console.log(\"Received coin update:\", data);\n if (data && data.coins !== undefined) {\n // Ensure we're working with numbers\n const coins = typeof data.coins === 'number' ? data.coins : parseInt(data.coins, 10);\n const user_id = typeof data.user_id === 'number' ? data.user_id : parseInt(data.user_id, 10);\n\n console.log('Dispatching coin-update event with:', { userId: user_id, coins });\n\n // Dispatch a custom event that the CoinDisplay component can listen for\n document.dispatchEvent(new CustomEvent('coin-update', {\n detail: {\n userId: user_id,\n coins: coins\n }\n }));\n }\n }\n }\n );\n\n console.log('Subscription created successfully');\n return subscription;\n } catch (error) {\n console.error('Error creating subscription:', error);\n return { unsubscribe: () => {} }; // Return a dummy object with unsubscribe method\n }\n};\n\nexport default createCoinSubscription;","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport createCoinSubscription from '../../../channels/coin_channel';\n\nconst CoinDisplay = (props) => {\n // Log the raw props to see what we're getting\n console.log('CoinDisplay raw props:', props);\n\n // Extract props with defaults\n const initialCoins = props.initialCoins !== undefined ? props.initialCoins : 0;\n const userId = props.userId !== undefined ? props.userId : null;\n\n // Convert initialCoins to a number if it's not already\n const parsedInitialCoins = typeof initialCoins === 'number' ? initialCoins : parseInt(initialCoins || '0', 10);\n\n // Use the parsed value for the initial state\n const [coins, setCoins] = useState(parsedInitialCoins);\n const [animating, setAnimating] = useState(false);\n\n // Log the initial values to help with debugging\n useEffect(() => {\n console.log('CoinDisplay initialized with:', {\n initialCoins,\n parsedInitialCoins,\n userId\n });\n }, [initialCoins, userId]);\n\n useEffect(() => {\n // Only subscribe if we have a valid userId\n if (!userId) {\n console.warn('CoinDisplay: No userId provided, skipping subscription');\n return;\n }\n\n console.log('Creating subscription for user:', userId);\n\n // Subscribe to the coin channel for real-time updates\n const subscription = createCoinSubscription(userId);\n\n // Also listen for the custom event (for backward compatibility)\n const handleCoinUpdate = (event) => {\n const { detail } = event;\n console.log('Coin update event received:', event);\n\n if (detail && detail.userId === userId && detail.coins !== undefined) {\n console.log('Coin update matched for user:', detail);\n\n // Animate the coin change\n setAnimating(true);\n setCoins(parseInt(detail.coins, 10));\n\n // Reset animation after a short delay\n setTimeout(() => {\n setAnimating(false);\n }, 1000);\n }\n };\n\n // Add event listener\n document.addEventListener('coin-update', handleCoinUpdate);\n\n // Clean up\n return () => {\n document.removeEventListener('coin-update', handleCoinUpdate);\n if (subscription && typeof subscription.unsubscribe === 'function') {\n subscription.unsubscribe();\n }\n };\n }, [userId]);\n\n return (\n
\n \"Coin\"\n \n {coins}\n \n
\n );\n};\n\nCoinDisplay.propTypes = {\n initialCoins: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n userId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n};\n\nexport default CoinDisplay;","// app/javascript/packs/application.js\nimport ReactOnRails from \"react-on-rails\";\nimport HelloWorld from \"../bundles/HelloWorld/components/HelloWorld\";\nimport HelloWorldApp from \"../startup/HelloWorldApp\";\nimport Chat from \"../bundles/Chat/components/Chat\";\nimport ChatList from \"../bundles/Chat/components/ChatList\";\nimport StoryTellingChat from \"../bundles/Chat/components/StoryTellingChat\";\nimport ImageSection from \"../bundles/Chat/components/ImageSection\";\nimport ImageCreation from \"../bundles/Chat/components/ImageCreation\";\nimport ImageGrid from \"../bundles/Shared/components/ImageGrid\";\nimport ImageMosaic from \"../bundles/Shared/components/ImageMosaic\";\nimport StripeWrapper from \"../bundles/Shared/components/StripeWrapper\";\nimport Spinner from \"../bundles/Chat/components/Spinner\";\nimport UserMessage from \"../bundles/Chat/components/UserMessage\";\nimport AssistantMessage from \"../bundles/Chat/components/AssistantMessage\";\nimport WordList from \"../bundles/Words/components/WordList\";\nimport WordTest from \"../bundles/Words/components/WordTest\";\nimport Listeners from \"./listeners\";\nimport LogrocketWrapper from \"../bundles/Shared/components/LogrocketWrapper\";\nimport UsernameValidator from '../bundles/Shared/components/UsernameValidator'\nimport MemoryForm from \"../bundles/Shared/components/MemoryForm\";\nimport LearningWorld from \"../bundles/LearningWorld/components/LearningWorld\";\nimport CoinDisplay from '../bundles/CoinDisplay/components/CoinDisplay';\n\nReactOnRails.register({\n HelloWorld,\n HelloWorldApp,\n Chat,\n ChatList,\n StoryTellingChat,\n ImageSection,\n ImageCreation,\n ImageGrid,\n ImageMosaic,\n StripeWrapper,\n Spinner,\n WordList,\n WordTest,\n Listeners,\n UserMessage,\n AssistantMessage,\n LogrocketWrapper,\n UsernameValidator,\n MemoryForm,\n LearningWorld,\n CoinDisplay\n});\n","document.addEventListener('DOMContentLoaded', function () {\n const menuIcon = document.getElementById('mobile-menu');\n const menuButton = document.getElementById('mobile-button');\n if (!menuIcon || !menuButton) return;\n menuButton.addEventListener('click', function () {\n menuIcon.classList.toggle('hidden');\n });\n});"],"names":["useCounterStore","create","set","count","add","state","subtract","useChatStore","chat","fetch","async","response","json","props","name","setName","useState","useEffect","React","className","src","avatar_url","alt","login","type","onClick","FaMinus","color","FaPlus","htmlFor","title","id","value","onChange","e","target","Routes","Route","GoBackSection","Link","to","BsArrowLeft","RouterApp","railsContext","BrowserRouter","path","element","HelloWorld","href","ImageSection","imageId","image","formToken","chatId","imageUrl","setImageUrl","loading","setLoading","axios","post","chat_image_id","headers","Authorization","data","error","console","fetchImage","StoryTellingChat","onSaveChat","chatStory","isSubmitting","setIsSubmitting","storyParts","setStoryParts","chatStoryId","setChatStoryId","userPrompt","setUserPrompt","prompt","audioStatus","setAudioStatus","map","part","audioUrl","initialAudioStatus","forEach","length","onSubmit","preventDefault","queryParams","URLSearchParams","toString","storySegments","sections","handleSendStoryPrompt","rows","placeholder","disabled","index","key","content","controls","prev","messageId","updatedStoryParts","audio_url","handleGenerateAudio","MessageInput","handleSubmit","input","setInput","handleFileChange","showWork","messageCount","filePreview","setFilePreview","errorMessage","setErrorMessage","isCameraActive","setIsCameraActive","textareaRef","useRef","videoRef","canvasRef","startCamera","adjustHeight","current","style","height","scrollHeight","stream","navigator","mediaDevices","getUserMedia","video","facingMode","ideal","srcObject","play","paperClip","document","getElementById","click","HiOutlinePaperClip","size","maxWidth","margin","ref","width","playsInline","captureImage","canvas","aspectRatio","videoHeight","context","getContext","cropWidth","cropX","videoWidth","drawImage","toBlob","blob","newCapturedFile","File","URL","createObjectURL","getTracks","track","stop","display","IoMdCloseCircle","xmlns","xmlnsXlink","version","viewBox","xmlSpace","stroke","fill","transform","d","accept","file","fileType","reader","FileReader","onloadend","result","readAsDataURL","handleFileChangeInternal","files","onKeyDown","shiftKey","FaArrowAltCircleUp","UserMessage","message","undefined","JSON","stringify","String","ReactMarkdown","remarkPlugins","remarkMath","rehypePlugins","rehypeKatex","rehypeRaw","components","inlineMath","node","log","InlineMath","math","BlockMath","image_url","CollapsibleSection","items","isOpen","toggleOpen","onItemClick","isClickable","stringItems","item","FaChevronUp","FaChevronDown","FaStar","role","AssistantMessage","onFollowUpClick","setAudioUrl","showExamples","setShowExamples","showEquations","setShowEquations","showFollowUp","setShowFollowUp","showAudioButton","chat_type","showMapFocus","map_focus","explanation","processedContent","replace","match","bracket","p1","openBracket","closeBracket","renderContent","ImSpinner8","HiSpeakerWave","examples","equations","follow_up","latitude","longitude","Profile","user","avatarSrc","avatar","Message","isUser","Spinner","LanguageLearningPrompts","language","mode","onPromptSelect","getPrompts","World","apiKey","setMap","clickedLocation","setClickedLocation","infoWindowOpen","setInfoWindowOpen","question","setQuestion","messages","setMessages","isLoading","setIsLoading","suggestions","setSuggestions","center","setCenter","lat","lng","mapOptions","mapTypeControl","mapTypeControlOptions","window","google","maps","MapTypeControlStyle","HORIZONTAL_BAR","position","ControlPosition","TOP_LEFT","mapTypeIds","zoomControl","zoomControlOptions","LEFT_CENTER","fullscreenControl","fullscreenControlOptions","LEFT_TOP","streetViewControl","styles","featureType","elementType","stylers","visibility","LoadScript","googleMapsApiKey","GoogleMap","mapContainerStyle","zoom","options","event","newLocation","latLng","onLoad","Marker","FaGlobeAmericas","Number","toFixed","trim","authenticity_token","newCenter","parseFloat","panTo","setZoom","parseInt","suggestion","ParentMemoryChat","childId","onSaveMemory","showMemoryForm","setShowMemoryForm","memoryData","setMemoryData","memoryType","setMemoryType","messagesEndRef","scrollToBottom","scrollIntoView","behavior","handleFollowUpClick","label","success","errors","userMessage","child_id","Accept","assistantMessage","prevMessages","handleSaveMemoryClick","lastAssistantMessage","reverse","find","m","imageFile","setImageFile","isStorySubmitted","setIsStorySubmitted","chatType","subject","setSubject","targetLanguage","setTargetLanguage","learningMode","setLearningMode","isNewChat","memory_data","memory_type","user_id","process","code","lang","icon","sub","maxHeight","readOnly","uploadedImageURL","uploadedImageId","formData","FormData","append","imageURL","image_id","setImageURL","setImageId","eventSource","setEventSource","story","close","messageIndex","handleSend","newEventSource","EventSource","onmessage","newContent","updatedMessages","onerror","ImageCreationComponent","setPrompt","setStyle","difficulty","setDifficulty","layout","setLayout","generatedImage","setGeneratedImage","avatarSet","setAvatarSet","backgroundSet","setBackgroundSet","chatImageId","setChatImageId","isPublic","setIsPublic","isColoringPage","isAvatar","public","downloadImage","link","createElement","download","payload","background_id","patch","avatar_id","chat_image","useInfiniteImageLoad","initialImages","totalCount","images","setImages","page","setPage","hasMore","setHasMore","observerRef","disconnect","observer","IntersectionObserver","entries","isIntersecting","loadMoreImages","threshold","observe","get","params","prevImages","prevPage","next_page","ImageGrid","editType","hookImages","completedImageId","setCompletedImageId","chatUrl","createdBy","created_at","handleSetAsAction","createdUser","updatedImage","img","handleShareImage","HeartIcon","filled","strokeLinecap","strokeLinejoin","strokeWidth","Lightbox","onClose","ImagePlaceholder","ImageCell","onHeartToggle","signedIn","imageLoaded","setImageLoaded","creatorAvatarUrl","isLiked","likeCount","ImageMosaic","offset","setOffset","selectedImage","setSelectedImage","inView","useInView","useCallback","per_page","querySelector","chat_images","has_more","prevOffset","openLightbox","closeLightbox","handleHeartToggle","stopPropagation","status","updatedImageData","Array","from","_","stripePromise","loadStripe","StripeWrapper","familyId","initialPriceId","priceId","setPriceId","clientSecret","setClientSecret","promotekitReferral","promotekit_referral","method","body","price_id","family_id","initializeCheckout","then","stripe","initEmbeddedCheckout","checkout","mount","catch","handlePriceChange","newPriceId","Elements","min","max","step","WordList","wordList","initialUser","words","setWords","newWord","setNewWord","setUser","playSlowAudio","rate","audio","Audio","playbackRate","languageName","wordsRemaining","word","addedWord","prevWords","updatedWordListResponse","freemium","word_text","delete","wordId","filter","deleteWord","audioWordUrl","sentence","audioSentenceUrl","specialCharacters","es","fr","de","it","pt","nl","WordTest","currentWordIndex","setCurrentWordIndex","userAnswer","setUserAnswer","showResult","setShowResult","isCorrect","setIsCorrect","wrongAnswers","setWrongAnswers","earnedCoins","setEarnedCoins","hasSubmitted","setHasSubmitted","showWrongAnswersSummary","setShowWrongAnswersSummary","correctAnswers","setCorrectAnswers","retryMode","setRetryMode","currentWord","languageCode","toLowerCase","playAudio","resetFullTest","retryWrongAnswers","wa","correct","wrong","RegExp","ok","char","prevAnswer","handleSpecialCharacter","nextWord","prevIndex","LogrocketWrapper","LogRocketInitialized","LogRocket","fullname","email","UsernameValidator","currentUsername","username","setUsername","setStatus","isChecking","setIsChecking","timeoutId","setTimeout","encodeURIComponent","valid","checkUsername","clearTimeout","getStatusColor","cx","cy","r","MemoryForm","memoryTypes","initialMemoryType","initialMemoryData","formAction","formMethod","csrfToken","cancelUrl","childName","isEditing","hints","science","history","language_arts","learning_style","interests","strengths","challenges","anything","placeholders","questions","action","defaultProps","CHARACTER_SIZE","ENEMY_SIZE","DEFAULT_AVATAR","Image","GEM_IMAGE","GameCanvas","canvasSize","isMoving","wobbleOffset","avatarImage","modules","activeModule","getModulePositions","gems","collectedGems","enemies","enemySpeedMultiplier","isInvulnerable","ctx","clearRect","modulePos","isRewardsModule","isRewards","beginPath","arc","x","y","Math","PI","colors","colorIndex","gradient","createRadialGradient","addColorStop","fillStyle","shadowBlur","shadowColor","lineWidth","strokeStyle","textAlign","textBaseline","font","fillText","moduleTitle","displayTitle","includes","firstWord","split","substring","premium","gem","save","translate","rotate","rotation","complete","naturalHeight","gemSize","GEM_SIZE","moveTo","lineTo","closePath","gemGradient","createLinearGradient","sparkleTime","Date","now","sin","restore","enemy","active","baseColor","glowIntensity","dx","dy","angle","atan2","eyeOffsetX","cos","eyeOffsetY","drawX","drawY","shadowWidth","abs","shadowHeight","ellipse","shieldOpacity","clip","fillRect","storedHighScore","localStorage","getItem","currentHighScore","setItem","trophyX","trophyY","leaderboardTrophyY","leaderboardTrophyX","onclick","rect","getBoundingClientRect","clientX","left","clientY","top","location","multiplier","floor","Instructions","currentUser","showInstructions","setShowInstructions","toggleInstructions","LearningWorld","containerRef","isMobile","setIsMobile","setCanvasSize","setPosition","keys","setKeys","handleKeyDown","handleKeyUp","useGameState","setIsMoving","setWobbleOffset","setGems","setCollectedGems","setEnemies","activeEnemyCount","setActiveEnemyCount","setEnemySpeedMultiplier","setIsInvulnerable","lastMoveTimeRef","animationFrameRef","newGems","i","push","random","vx","vy","rotationSpeed","newEnemies","createEnemy","isActive","baseSpeed","wiggle","newActiveCount","prevEnemies","updatedEnemies","enemiesToAdd","newEnemyId","newEnemy","prevKeys","some","gameLoop","setInterval","prevPos","newX","newY","moved","prevGems","gemsCollected","updatedGems","distance","sqrt","newMultiplier","newVx","newVy","newRotation","speed","GEM_SPEED","playerCaught","respawnTime","moveAngle","currentSpeed","newWiggle","getAttribute","gem_count","resetEnemies","clearInterval","wobbleAnimation","newOffset","requestAnimationFrame","cancelAnimationFrame","checkMobile","isMobileDevice","innerWidth","test","userAgent","addEventListener","removeEventListener","localModules","handleModuleClick","useModules","setLocalModules","setActiveModule","modulesLoaded","isArray","debugElement","debugData","parse","textContent","positions","slice","modulePositions","nearestModule","nearestDistance","Infinity","module","gemCount","targetUrl","separator","setAvatarImage","defaultAvatarPath","loadAvatarFromUrl","url","onload","loadDefaultAvatar","defaultImg","userDebugElement","userData","useAvatar","updateCanvasSize","handleEnterKey","onTouchStart","ArrowLeft","onTouchEnd","ArrowUp","ArrowRight","ArrowDown","createConsumer","userId","warn","unsubscribe","parsedUserId","subscription","consumer","subscriptions","channel","connected","disconnected","received","coins","dispatchEvent","CustomEvent","detail","initialCoins","parsedInitialCoins","setCoins","animating","setAnimating","createCoinSubscription","handleCoinUpdate","ReactOnRails","HelloWorldApp","Chat","ChatList","ImageCreation","Listeners","CoinDisplay","menuIcon","menuButton","classList","toggle"],"sourceRoot":""}