diff --git a/RELEASE_NOTES_v2.md b/RELEASE_NOTES_v2.md new file mode 100644 index 0000000..72049f5 --- /dev/null +++ b/RELEASE_NOTES_v2.md @@ -0,0 +1,29 @@ +# Релиз v1.2.0 - Умные рекомендации и мотивация 🌿 + +Второй цикл обновлений сосредоточен на персонализации контента и унификации дизайна. + +## 🚀 Новые функции + +### 🤖 AI-Коуч 2.2 +- **Умные рекомендации**: Коуч анализирует темы вашего разговора и предлагает релевантные статьи из базы знаний для более глубокого изучения проблемы. +- **Интеграция с базой знаний**: Бесшовный переход от чата к обучающим материалам. + +### ✨ Ежедневная мотивация +- **Цитата дня**: Вдохновляющие слова от великих мыслителей и экспертов по восстановлению на главном экране. +- **Совет дня**: Практические рекомендации по поддержанию трезвости и улучшению самочувствия. +- **DailyMotivationService**: Новый сервис для управления мотивационным контентом. + +### 🎨 Дизайн и UX +- **Унификация статей**: Раздел "База знаний" полностью переведен на фирменную зеленую палитру. +- **Улучшенная навигация**: Добавлены закругленные заголовки и обновлены отступы для лучшего визуального восприятия. + +## 🛠 Технические изменения +- Расширен интерфейс `ChatMessage` для поддержки рекомендованных статей. +- Обновлен `AICoachService` с логикой тегирования и поиска контента. +- Добавлен `DailyMotivationService`. + +--- +## 📦 Сборка APK + +Инструкции по сборке через EAS остаются прежними (см. RELEASE_NOTES.md v1.1.0). +Для локальной проверки сборки используйте: `npx expo export`. diff --git a/RELEASE_NOTES_v3.md b/RELEASE_NOTES_v3.md new file mode 100644 index 0000000..aa3c50b --- /dev/null +++ b/RELEASE_NOTES_v3.md @@ -0,0 +1,26 @@ +# Release Notes - v1.3.0 "Content Boom & Intelligence" 🚀 + +В этом обновлении мы сосредоточились на наполнении приложения качественным контентом и улучшении интеллектуального помощника. + +### 📚 Масштабное расширение контента +- **База знаний 2.0**: Мы добавили более 25 новых статей. Теперь в приложении 50 уникальных материалов, охватывающих науку о зависимости, психологию восстановления, семейные отношения, карьеру и физическое здоровье. +- **Умный поиск**: Реализован мгновенный поиск и фильтрация статей по категориям и тегам. Найти нужную информацию стало проще. +- **Сервис мотивации**: База цитат и советов расширена до 45+ записей — теперь каждый день в течение месяца вы будете получать новый вдохновляющий контент. + +### 🤖 Интеллект AI-Коуча +- **Глубокие знания**: База психологических знаний коуча расширена вдвое. Помощник теперь лучше разбирается в темах ПТСР, семейной созависимости, прокрастинации и эмоциональной регуляции. +- **Интерактивность**: Коуч научился задавать уточняющие вопросы и предлагать конкретные техники (HALT, DBT, RAIN) в зависимости от контекста беседы. +- **Контекстные рекомендации**: Улучшен алгоритм предложения статей — теперь рекомендации более точно соответствуют обсуждаемой теме. + +### 🎨 Интерфейс и UX +- **Новая навигация**: Мы переработали TabBar, вынеся наиболее важные разделы («База знаний» и «Сообщество») на первый план для быстрого доступа. +- **Виджет «Совет дня»**: На главном экране появился новый блок с практическими рекомендациями, которые обновляются ежедневно. +- **Визуальное обновление**: Оптимизированы отступы, шрифты и цветовые акценты для лучшей читаемости контента. + +### 🛠 Технические улучшения +- Оптимизирована производительность списков контента. +- Исправлены ошибки в логике отображения быстрых ответов в чате. +- Проведена полная валидация базы данных контента. + +--- +*Путь к трезвости — это марафон, и мы здесь, чтобы дать вам лучшие инструменты для каждого километра.* diff --git a/RELEASE_NOTES_v4.md b/RELEASE_NOTES_v4.md new file mode 100644 index 0000000..a55e434 --- /dev/null +++ b/RELEASE_NOTES_v4.md @@ -0,0 +1,28 @@ +# Release Notes - v1.4.0 (AI & Self-Reflection Update) + +## Что нового: + +### 📔 Умный Дневник +- Новый раздел "Дневник" для ежедневных записей. +- **AI Анализ:** Каждая запись анализируется искусственным интеллектом для выявления доминирующих эмоций и потенциальных триггеров. +- Система советов на основе содержания ваших записей. + +### 🔊 Голос AI-Коуча +- Добавлена функция Text-to-Speech (TTS). Теперь вы можете прослушать ответы вашего AI-наставника, нажав на иконку динамика. +- Поддержка русского языка с естественным звучанием. + +### 🎉 Празднование успехов +- Интегрированы Lottie-анимации для поздравления с важными вехами трезвости (каждую неделю). +- Обновленная система достижений с плавными анимациями появления. + +### ⚡ Оптимизация производительности +- Переход на `@shopify/flash-list` в разделе базы знаний. Это обеспечивает мгновенную прокрутку даже при сотнях статей. +- Улучшен поиск по статьям. + +### 🛠 Прочие улучшения +- Обновлена `PsychologyService` для более точного распознавания контекста. +- Улучшена стабильность веб-версии приложения. +- Добавлены новые уведомления-напоминания для поддержания дисциплины. + +--- +*Продолжайте путь к свободе. Мы рядом!* diff --git a/TASKS.md b/TASKS.md index 7c7d901..2f8b234 100644 --- a/TASKS.md +++ b/TASKS.md @@ -1,23 +1,25 @@ -# Список задач по улучшению приложения (Цикл 1) +# Список задач по улучшению приложения (Цикл 3) - ВЫПОЛНЕНО ✅ +- [x] Довести количество статей в базе до 50+. +- [x] Расширить базу знаний AI-Коуча (новые темы: семья, работа, питание, травма). +- [x] Добавить 30+ новых цитат и 15 советов в сервис мотивации. +- [x] Реализовать поиск по статьям в разделе "База знаний". +- [x] Добавить виджет "Совет дня" на главный экран. +- [x] Оптимизировать навигацию (TabBar), выделив приоритетные разделы. +- [x] Релиз v1.3.0. -## 🤖 AI-Коуч и Персонализация -- [x] Добавить кнопки быстрых ответов (suggestions) в чат. -- [x] Внедрить анимации `FadeInUp` для сообщений. -- [x] Реализовать вкладку "Анализ" с карточками триггеров. -- [ ] Улучшить логику ответов на основе базы знаний. +# Список задач по улучшению приложения (Цикл 4) - ВЫПОЛНЕНО ✅ -## 🤝 Коммуникация и Контент -- [x] Создать `CommunityService` с моковыми историями и постами. -- [x] Реализовать горизонтальную ленту "Истории успеха" в разделе Сообщество. -- [x] Реализовать вертикальную ленту "Поддержка" в разделе Сообщество. +## 🤖 AI-Коуч и Персонализация +- [x] Добавить поддержку озвучки (Text-to-Speech) для ответов коуча. +- [x] Реализовать "Умный дневник" с автоматическим анализом настроения и триггеров. +- [x] Персонализация приветствий на основе времени суток и настроения. ## 🎨 Интерфейс и UX -- [x] Унифицировать градиентные заголовки (Зеленая палитра #2E7D4A). -- [x] Обновить дизайн карточек (borderRadius: 16, тенюшки). -- [ ] Сделать новые скриншоты для README. +- [x] Внедрить Lottie-анимации для празднования этапов трезвости. +- [x] Добавить систему уведомлений-напоминаний о заполнении дневника. +- [x] Оптимизация списков (FlashList) для более плавной прокрутки. ## 🛠 Техническое развитие и Релиз -- [ ] Запустить `npm test` и проверить стабильность. -- [ ] Выполнить `npx expo export` для проверки сборки. -- [ ] Подготовить `RELEASE_NOTES.md` и инструкции для APK. -- [ ] Создать релиз-тег в репозитории. +- [x] Создать `JournalService` для управления записями пользователя. +- [x] Подготовить релиз v1.4.0. +- [x] Обновить визуальные материалы (скриншоты). diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 0216766..0306237 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -9,32 +9,26 @@ const TabLayout = () => { tabBarInactiveTintColor: '#666' }; - const homeIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'home', size, color }); - const coachIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'psychology', size, color }); - const techIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'science', size, color }); - const audioIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'menu-book', size, color }); - const chatIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'chat', size, color }); - const gamesIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'games', size, color }); - const settingsIcon = ({ color, size }) => React.createElement(MaterialIcons, { name: 'settings', size, color }); - return React.createElement(Tabs, { screenOptions: tabOptions }, - React.createElement(Tabs.Screen, { name: 'index', options: { title: 'Главная', tabBarIcon: homeIcon } }), - React.createElement(Tabs.Screen, { name: 'ai-coach', options: { title: 'AI-Коуч', tabBarIcon: coachIcon } }), - React.createElement(Tabs.Screen, { name: 'enhanced-exercises', options: { title: 'Техники', tabBarIcon: techIcon } }), - React.createElement(Tabs.Screen, { name: 'articles', options: { title: 'Статьи', tabBarIcon: audioIcon } }), - React.createElement(Tabs.Screen, { name: 'ai-chat', options: { title: 'ИИ-Чат', tabBarIcon: chatIcon } }), - React.createElement(Tabs.Screen, { name: 'mini-games', options: { title: 'Игры', tabBarIcon: gamesIcon } }), - React.createElement(Tabs.Screen, { name: 'enhanced-settings', options: { title: 'Настройки', tabBarIcon: settingsIcon } }), + React.createElement(Tabs.Screen, { name: 'index', options: { title: 'Главная', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'home', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'ai-coach', options: { title: 'Коуч', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'psychology', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'journal', options: { title: 'Дневник', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'edit-note', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'articles', options: { title: 'База знаний', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'menu-book', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'community', options: { title: 'Сообщество', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'groups', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'enhanced-exercises', options: { title: 'Техники', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'science', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'enhanced-settings', options: { title: 'Настройки', tabBarIcon: ({ color, size }) => React.createElement(MaterialIcons, { name: 'settings', size, color }) } }), + React.createElement(Tabs.Screen, { name: 'ai-chat', options: { href: null } }), + React.createElement(Tabs.Screen, { name: 'mini-games', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'personalized-recommendations', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'advanced-analytics', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'gamification', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'psychology', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'therapy', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'exercises', options: { href: null } }), - React.createElement(Tabs.Screen, { name: 'community', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'profile', options: { href: null } }), React.createElement(Tabs.Screen, { name: 'analytics', options: { href: null } }), - React.createElement(Tabs.Screen, { name: 'sounds', options: { href: null } }) + React.createElement(Tabs.Screen, { name: 'sounds', options: { href: null } }), + React.createElement(Tabs.Screen, { name: 'advanced-therapy', options: { href: null } }) ); }; diff --git a/app/(tabs)/ai-coach.tsx b/app/(tabs)/ai-coach.tsx index c1fd087..6ed5baa 100644 --- a/app/(tabs)/ai-coach.tsx +++ b/app/(tabs)/ai-coach.tsx @@ -9,6 +9,7 @@ import { MaterialIcons } from '@expo/vector-icons'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { LinearGradient } from 'expo-linear-gradient'; import { useAICoachViewModel, ChatMessage } from '../../hooks/useAICoachViewModel'; +import { useRouter } from 'expo-router'; import Animated, { FadeInUp, } from 'react-native-reanimated'; @@ -16,7 +17,12 @@ import Animated, { const { width: screenWidth } = Dimensions.get('window'); // Refactored Message component -const MessageBubble = React.memo(({ message }: { message: ChatMessage }) => { +const MessageBubble = React.memo(({ message, onArticlePress, onSpeak, isSpeaking }: { + message: ChatMessage, + onArticlePress: (id: string) => void, + onSpeak: (text: string) => void, + isSpeaking: boolean +}) => { const isUser = message.isUser; return ( { {!isUser && ( - - AI-Коуч + + + AI-Коуч + + onSpeak(message.text)} style={styles.speakButton}> + + )} @@ -36,6 +51,22 @@ const MessageBubble = React.memo(({ message }: { message: ChatMessage }) => { {message.timestamp.toLocaleTimeString('ru', { hour: '2-digit', minute: '2-digit' })} + + {!isUser && message.recommendedArticles && message.recommendedArticles.length > 0 && ( + + Рекомендуемые статьи: + {message.recommendedArticles.map(article => ( + onArticlePress(article.id)} + > + + {article.title} + + ))} + + )} ); @@ -45,6 +76,7 @@ export default function EnhancedAICoach() { const insets = useSafeAreaInsets(); const vm = useAICoachViewModel(); const scrollViewRef = useRef(null); + const router = useRouter(); return ( @@ -83,7 +115,15 @@ export default function EnhancedAICoach() { style={styles.messagesContainer} onContentSizeChange={() => scrollViewRef.current?.scrollToEnd({ animated: true })} > - {vm.messages.map(m => )} + {vm.messages.map(m => ( + router.push('/articles')} + onSpeak={vm.speak} + isSpeaking={vm.isSpeaking} + /> + ))} {vm.isTyping && } @@ -200,9 +240,38 @@ const styles = StyleSheet.create({ messageText: { fontSize: 16 }, userMessageText: { color: 'white' }, aiMessageText: { color: '#333' }, - aiHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 4 }, + aiHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 4 }, + aiLabelRow: { flexDirection: 'row', alignItems: 'center' }, aiLabel: { fontSize: 10, fontWeight: 'bold', color: '#2E7D4A', marginLeft: 4 }, + speakButton: { padding: 4 }, timestamp: { fontSize: 10, color: '#999', marginTop: 4, alignSelf: 'flex-end' }, + recommendationsContainer: { + marginTop: 10, + paddingTop: 8, + borderTopWidth: 1, + borderTopColor: '#F0F0F0', + }, + recommendationTitle: { + fontSize: 11, + color: '#666', + marginBottom: 6, + fontWeight: '600', + }, + articleLink: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: '#F8F9FA', + padding: 8, + borderRadius: 8, + marginBottom: 4, + gap: 6, + }, + articleLinkText: { + fontSize: 12, + color: '#2E7D4A', + fontWeight: '500', + flex: 1, + }, suggestionsContainer: { maxHeight: 50, backgroundColor: '#F8F9FA', diff --git a/app/(tabs)/articles.tsx b/app/(tabs)/articles.tsx index a091449..c729dd9 100644 --- a/app/(tabs)/articles.tsx +++ b/app/(tabs)/articles.tsx @@ -5,11 +5,11 @@ import { View, Text, StyleSheet, - ScrollView, TouchableOpacity, Modal, Platform, - Dimensions + Dimensions, + TextInput } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import { LinearGradient } from 'expo-linear-gradient'; @@ -21,6 +21,7 @@ import Animated, { withTiming, runOnJS } from 'react-native-reanimated'; +import { FlashList } from "@shopify/flash-list"; const { width: screenWidth } = Dimensions.get('window'); @@ -38,16 +39,13 @@ interface Article { import { articlesDatabase } from '../../services/articlesDatabase'; -// Используем базу данных статей const articles: Article[] = articlesDatabase; -// Компоненты остаются теми же const MemoizedArticleCard = React.memo(({ article, onPress }: { article: Article; onPress: () => void; }) => { const scaleValue = useSharedValue(1); - const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: scaleValue.value }] })); @@ -96,7 +94,6 @@ const MemoizedFilterChip = React.memo(({ label, selected, onPress, count }: { count: number; }) => { const scaleValue = useSharedValue(1); - const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: scaleValue.value }] })); @@ -131,30 +128,29 @@ const MemoizedFilterChip = React.memo(({ label, selected, onPress, count }: { export default function ArticlesPage() { const insets = useSafeAreaInsets(); const [selectedCategory, setSelectedCategory] = useState('Все'); + const [searchQuery, setSearchQuery] = useState(''); const [selectedArticle, setSelectedArticle] = useState
(null); - const fadeInValue = useSharedValue(0); - const slideValue = useSharedValue(30); - - const fadeInAnimatedStyle = useAnimatedStyle(() => ({ - opacity: fadeInValue.value, - transform: [{ translateY: slideValue.value }] - })); - - React.useEffect(() => { - fadeInValue.value = withTiming(1, { duration: 800 }); - slideValue.value = withTiming(0, { duration: 800 }); - }, []); - const categories = useMemo(() => { const cats = new Set(articles.map(a => a.category)); - return ['Все', ...Array.from(cats)]; + return ['Все', ...Array.from(cats)].sort(); }, []); const filteredArticles = useMemo(() => { - if (selectedCategory === 'Все') return articles; - return articles.filter(a => a.category === selectedCategory); - }, [selectedCategory]); + let result = articles; + if (selectedCategory !== 'Все') { + result = result.filter(a => a.category === selectedCategory); + } + if (searchQuery.trim()) { + const q = searchQuery.toLowerCase(); + result = result.filter(a => + a.title.toLowerCase().includes(q) || + a.preview.toLowerCase().includes(q) || + a.tags.some(t => t.toLowerCase().includes(q)) + ); + } + return result; + }, [selectedCategory, searchQuery]); const getCategoryCount = useCallback((category: string) => { if (category === 'Все') return articles.length; @@ -165,19 +161,9 @@ export default function ArticlesPage() { setSelectedArticle(article); }, []); - return ( - - - - - База знаний - - {articles.length} научных статей о восстановлении - - - - - + const renderHeader = () => ( + + {!searchQuery && ( {articles.length} @@ -188,45 +174,93 @@ export default function ArticlesPage() { Категорий - - {Math.round(articles.reduce((sum, a) => sum + a.readTime, 0) / articles.length)} - - мин среднее + 5.0 + Рейтинг + )} + {!searchQuery && ( Выберите категорию - - - {categories.map((category) => ( - setSelectedCategory(category)} - count={getCategoryCount(category)} - /> - ))} - - + ( + setSelectedCategory(item)} + count={getCategoryCount(item)} + /> + )} + estimatedItemSize={120} + contentContainerStyle={styles.filtersContainer} + /> + )} - - - 📚 Статьи ({filteredArticles.length}) - - - {filteredArticles.map((article) => ( - handleArticlePress(article)} - /> - ))} - + + {searchQuery ? `Результаты поиска (${filteredArticles.length})` : `📚 Статьи (${filteredArticles.length})`} + + + ); + + return ( + + + + + База знаний - + + + + + {searchQuery.length > 0 && ( + setSearchQuery('')}> + + + )} + + + + + ( + handleArticlePress(item)} + /> + )} + estimatedItemSize={200} + ListHeaderComponent={renderHeader} + ListEmptyComponent={ + + + Ничего не найдено + { + setSearchQuery(''); + setSelectedCategory('Все'); + }} + > + Сбросить фильтры + + + } + contentContainerStyle={styles.listContent} + /> + {selectedArticle && ( - + setSelectedArticle(null)} @@ -250,7 +284,7 @@ export default function ArticlesPage() { - + @@ -270,18 +304,10 @@ export default function ArticlesPage() { {selectedArticle.content.split('\n').map((paragraph, index) => { if (!paragraph.trim()) return null; - const isBold = paragraph.startsWith('**') && paragraph.endsWith('**'); const cleanText = isBold ? paragraph.slice(2, -2) : paragraph; - return ( - + {cleanText} ); @@ -290,268 +316,105 @@ export default function ArticlesPage() { - + Сохранить - + Поделиться - + )} - + ); } const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#F8F9FA' - }, - header: { - padding: 20, - alignItems: 'center' - }, - headerContent: { - alignItems: 'center' - }, - headerTitle: { - fontSize: 28, - fontWeight: 'bold', - color: 'white', - marginTop: 8 - }, - headerSubtitle: { - fontSize: 16, - color: 'rgba(255,255,255,0.9)', - marginTop: 4, - textAlign: 'center' - }, - content: { - padding: 20 - }, - statsContainer: { + container: { flex: 1, backgroundColor: '#F8F9FA' }, + header: { padding: 20, borderBottomLeftRadius: 24, borderBottomRightRadius: 24, paddingBottom: 25 }, + headerContent: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginBottom: 15 }, + headerTitle: { fontSize: 24, fontWeight: 'bold', color: 'white', marginLeft: 10 }, + searchContainer: { flexDirection: 'row', backgroundColor: 'white', - borderRadius: 15, - padding: 20, - marginBottom: 20, + borderRadius: 12, + paddingHorizontal: 12, + alignItems: 'center', + height: 45, + elevation: 4, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, - elevation: 3 - }, - statItem: { - flex: 1, - alignItems: 'center' - }, - statNumber: { - fontSize: 24, - fontWeight: 'bold', - color: '#2196F3' }, - statLabel: { - fontSize: 14, - color: '#666', - marginTop: 4 - }, - filtersSection: { - marginBottom: 20 - }, - filterTitle: { - fontSize: 16, - fontWeight: 'bold', - color: '#333', - marginBottom: 12 - }, - filtersContainer: { + searchIcon: { marginRight: 8 }, + searchInput: { flex: 1, fontSize: 16, color: '#333', paddingVertical: 8 }, + listContent: { padding: 20 }, + statsContainer: { flexDirection: 'row', - gap: 8 - }, + backgroundColor: 'white', + borderRadius: 15, + padding: 15, + marginBottom: 20, + elevation: 3, + }, + statItem: { flex: 1, alignItems: 'center' }, + statNumber: { fontSize: 22, fontWeight: 'bold', color: '#2E7D4A' }, + statLabel: { fontSize: 12, color: '#666', marginTop: 4 }, + filtersSection: { marginBottom: 20 }, + filterTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', marginBottom: 12 }, + filtersContainer: { gap: 8, paddingRight: 20 }, filterChip: { paddingHorizontal: 16, paddingVertical: 8, borderRadius: 20, backgroundColor: '#E0E0E0', borderWidth: 2, - borderColor: 'transparent' - }, - selectedChip: { - backgroundColor: '#2196F3', - borderColor: '#1976D2' - }, - filterChipText: { - fontSize: 14, - fontWeight: '600', - color: '#666' - }, - selectedChipText: { - color: 'white' - }, - sectionTitle: { - fontSize: 20, - fontWeight: 'bold', - color: '#2E7D4A', - marginBottom: 16 - }, - articlesContainer: { - marginBottom: 20 - }, - articlesList: { - gap: 12 + borderColor: 'transparent', + marginRight: 8 }, + selectedChip: { backgroundColor: '#2E7D4A', borderColor: '#1B4D2E' }, + filterChipText: { fontSize: 13, fontWeight: '600', color: '#666' }, + selectedChipText: { color: 'white' }, + sectionTitle: { fontSize: 18, fontWeight: 'bold', color: '#2E7D4A', marginBottom: 16 }, articleCard: { backgroundColor: 'white', borderRadius: 15, - shadowColor: '#000', - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.1, - shadowRadius: 4, - elevation: 3 - }, - articleContent: { - padding: 16 - }, - articleHeader: { - flexDirection: 'row', - alignItems: 'center', - marginBottom: 12 - }, - iconBadge: { - width: 48, - height: 48, - borderRadius: 24, - justifyContent: 'center', - alignItems: 'center' - }, - articleMeta: { - marginLeft: 12, - flex: 1 - }, - categoryText: { - fontSize: 12, - fontWeight: '600', - color: '#666', - marginBottom: 2 - }, - readTimeText: { - fontSize: 11, - color: '#999' - }, - articleTitle: { - fontSize: 18, - fontWeight: 'bold', - color: '#333', - marginBottom: 8 - }, - articlePreview: { - fontSize: 14, - color: '#666', - lineHeight: 20, - marginBottom: 12 - }, - tagsContainer: { - flexDirection: 'row', - flexWrap: 'wrap', - gap: 6 - }, - tag: { - backgroundColor: '#F0F0F0', - paddingHorizontal: 8, - paddingVertical: 4, - borderRadius: 8 - }, - tagText: { - fontSize: 11, - color: '#666', - fontWeight: '500' - }, - modalContainer: { - flex: 1, - backgroundColor: 'white' - }, - modalHeader: { - flexDirection: 'row', - alignItems: 'center', - padding: 20, - borderBottomWidth: 1, - borderBottomColor: '#E0E0E0' - }, - closeButton: { - padding: 8 - }, - modalHeaderInfo: { - flex: 1, - marginLeft: 12 - }, - modalCategory: { - fontSize: 14, - fontWeight: '600', - color: '#666', - marginBottom: 2 - }, - modalReadTime: { - fontSize: 12, - color: '#999' - }, - modalContent: { - flex: 1, - padding: 20 - }, - largeIconBadge: { - width: 80, - height: 80, - borderRadius: 40, - alignSelf: 'center', - marginBottom: 20 - }, - modalTitle: { - fontSize: 24, - fontWeight: 'bold', - color: '#333', - marginBottom: 16, - textAlign: 'center' - }, - divider: { - height: 1, - backgroundColor: '#E0E0E0', - marginVertical: 20 - }, - articleBody: { - marginBottom: 30 - }, - articleParagraph: { - fontSize: 16, - color: '#333', - lineHeight: 26, - marginBottom: 16 - }, - boldParagraph: { - fontWeight: 'bold', - fontSize: 18, - color: '#2196F3', - marginTop: 8 - }, - actionButtons: { - flexDirection: 'row', - justifyContent: 'space-around', - marginBottom: 20 - }, - actionButton: { - flexDirection: 'row', - alignItems: 'center', - padding: 12, - borderRadius: 12, - backgroundColor: '#E3F2FD', - gap: 6 - }, - actionButtonText: { - fontSize: 14, - fontWeight: '600', - color: '#2196F3' - } + marginBottom: 12, + elevation: 3, + }, + articleContent: { padding: 16 }, + articleHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 12 }, + iconBadge: { width: 44, height: 44, borderRadius: 22, justifyContent: 'center', alignItems: 'center' }, + articleMeta: { marginLeft: 12, flex: 1 }, + categoryText: { fontSize: 11, fontWeight: '600', color: '#666', marginBottom: 2 }, + readTimeText: { fontSize: 10, color: '#999' }, + articleTitle: { fontSize: 17, fontWeight: 'bold', color: '#333', marginBottom: 6 }, + articlePreview: { fontSize: 13, color: '#666', lineHeight: 18, marginBottom: 10 }, + tagsContainer: { flexDirection: 'row', flexWrap: 'wrap', gap: 6 }, + tag: { backgroundColor: '#F0F0F0', paddingHorizontal: 8, paddingVertical: 4, borderRadius: 8 }, + tagText: { fontSize: 10, color: '#666', fontWeight: '500' }, + emptyContainer: { alignItems: 'center', justifyContent: 'center', padding: 40, marginTop: 20 }, + emptyText: { fontSize: 16, color: '#999', marginTop: 15, marginBottom: 20 }, + resetButton: { backgroundColor: '#2E7D4A', paddingHorizontal: 20, paddingVertical: 10, borderRadius: 12 }, + resetButtonText: { color: 'white', fontWeight: 'bold' }, + modalContainer: { flex: 1, backgroundColor: 'white' }, + modalHeader: { flexDirection: 'row', alignItems: 'center', padding: 15, borderBottomWidth: 1, borderBottomColor: '#E0E0E0' }, + closeButton: { padding: 8 }, + modalHeaderInfo: { flex: 1, marginLeft: 12 }, + modalCategory: { fontSize: 13, fontWeight: '600', color: '#666', marginBottom: 2 }, + modalReadTime: { fontSize: 11, color: '#999' }, + modalContent: { flex: 1, padding: 20 }, + largeIconBadge: { width: 70, height: 70, borderRadius: 35, alignSelf: 'center', marginBottom: 20 }, + modalTitle: { fontSize: 22, fontWeight: 'bold', color: '#333', marginBottom: 16, textAlign: 'center' }, + divider: { height: 1, backgroundColor: '#E0E0E0', marginVertical: 15 }, + articleBody: { marginBottom: 30 }, + articleParagraph: { fontSize: 16, color: '#333', lineHeight: 24, marginBottom: 14 }, + boldParagraph: { fontWeight: 'bold', fontSize: 17, color: '#2E7D4A', marginTop: 8 }, + actionButtons: { flexDirection: 'row', justifyContent: 'space-around', marginBottom: 40 }, + actionButton: { flexDirection: 'row', alignItems: 'center', padding: 12, borderRadius: 12, backgroundColor: '#E8F5E8', gap: 6 }, + actionButtonText: { fontSize: 13, fontWeight: '600', color: '#2E7D4A' } }); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 5036329..0470e37 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -21,6 +21,7 @@ import Animated, { import { MemoizedHealthMetric } from '../../components/home/HealthMetric'; import { StatCard } from '../../components/home/StatCard'; +import { DailyMotivationService, MotivationQuote, RecoveryTip } from '../../services/dailyMotivationService'; const AchievementSystem = React.lazy(() => import('../../components/AchievementSystem')); const CrisisIntervention = React.lazy(() => import('../../components/CrisisIntervention')); @@ -125,6 +126,8 @@ function HomePage() { const [showCrisisIntervention, setShowCrisisIntervention] = useState(false); const [showCalendar, setShowCalendar] = useState(false); const [selectedHealthMetric, setSelectedHealthMetric] = useState(null); + const [dailyQuote, setDailyQuote] = useState(null); + const [dailyTip, setDailyTip] = useState(null); const [alertConfig, setAlertConfig] = useState<{ visible: boolean; title: string; @@ -144,6 +147,8 @@ function HomePage() { -1, true ); + setDailyQuote(DailyMotivationService.getDailyQuote()); + setDailyTip(DailyMotivationService.getDailyTip()); }, []); const showWebAlert = useCallback((title: string, message: string, onOk?: () => void) => { @@ -270,6 +275,29 @@ function HomePage() { + {dailyQuote && ( + + + + {dailyQuote.text} + — {dailyQuote.author} + + + )} + + {dailyTip && ( + + + + + Совет дня + + {dailyTip.title} + {dailyTip.content} + + + )} + ([]); + const [inputText, setInputText] = useState(''); + const [loading, setLoading] = useState(true); + const [isSaving, setIsSaving] = useState(false); + const [mood, setMood] = useState(3); + + useEffect(() => { + loadEntries(); + }, []); + + const loadEntries = async () => { + const result = await JournalService.getEntries(); + if (result.success) { + setEntries(result.data); + } + setLoading(false); + }; + + const handleSave = async () => { + if (!inputText.trim()) return; + setIsSaving(true); + const result = await JournalService.addEntry(inputText, mood); + if (result.success) { + setEntries([result.data, ...entries]); + setInputText(''); + setMood(3); + Alert.alert('Запись сохранена', 'Ваш AI-коуч проанализировал запись.'); + } + setIsSaving(false); + }; + + const deleteEntry = async (id: string) => { + Alert.alert( + 'Удалить запись?', + 'Это действие нельзя отменить.', + [ + { text: 'Отмена', style: 'cancel' }, + { + text: 'Удалить', + style: 'destructive', + onPress: async () => { + const result = await JournalService.deleteEntry(id); + if (result.success) { + setEntries(entries.filter(e => e.id !== id)); + } + } + } + ] + ); + }; + + return ( + + + + Умный дневник + + + + + Как прошел ваш день? + + {[1, 2, 3, 4, 5].map(m => ( + setMood(m)} + style={[styles.moodBtn, mood === m && styles.moodBtnSelected]} + > + + {m === 1 ? '😢' : m === 2 ? '😕' : m === 3 ? '😐' : m === 4 ? '😊' : '😄'} + + + ))} + + + + {isSaving ? : ( + <> + + Сохранить и проанализировать + + )} + + + + Ваши записи ({entries.length}) + + {loading ? ( + + ) : entries.map((entry, index) => ( + + + + {new Date(entry.date).toLocaleDateString('ru', { day: 'numeric', month: 'long', hour: '2-digit', minute: '2-digit' })} + + deleteEntry(entry.id)}> + + + + {entry.content} + + {entry.aiAnalysis && ( + + + + AI Анализ + + + {entry.aiAnalysis.dominantEmotions.map(e => ( + + {e} + + ))} + {entry.aiAnalysis.potentialTriggers.map(t => ( + + ⚡ {t} + + ))} + + {entry.aiAnalysis.advice} + + )} + + ))} + + + ); +} + +const styles = StyleSheet.create({ + container: { flex: 1, backgroundColor: '#F8F9FA' }, + header: { + padding: 20, + alignItems: 'center', + borderBottomLeftRadius: 24, + borderBottomRightRadius: 24, + paddingBottom: 25, + }, + title: { fontSize: 24, fontWeight: 'bold', color: 'white' }, + content: { flex: 1, padding: 15 }, + inputCard: { + backgroundColor: 'white', + borderRadius: 16, + padding: 15, + marginBottom: 20, + elevation: 3, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 4, + }, + inputTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', marginBottom: 12 }, + moodSelector: { flexDirection: 'row', justifyContent: 'space-around', marginBottom: 15 }, + moodBtn: { padding: 10, borderRadius: 12, backgroundColor: '#F0F0F0' }, + moodBtnSelected: { backgroundColor: '#E8F5E8', borderWidth: 1, borderColor: '#2E7D4A' }, + moodEmoji: { fontSize: 24 }, + textInput: { + backgroundColor: '#F0F0F0', + borderRadius: 12, + padding: 12, + minHeight: 100, + textAlignVertical: 'top', + fontSize: 16, + marginBottom: 15 + }, + saveBtn: { + backgroundColor: '#2E7D4A', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + padding: 14, + borderRadius: 12, + gap: 8 + }, + saveBtnDisabled: { backgroundColor: '#999' }, + saveBtnText: { color: 'white', fontWeight: 'bold' }, + sectionTitle: { fontSize: 18, fontWeight: 'bold', color: '#333', marginVertical: 15 }, + entryCard: { + backgroundColor: 'white', + borderRadius: 16, + padding: 15, + marginBottom: 15, + elevation: 2, + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.1, + shadowRadius: 2, + }, + entryHeader: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 10 }, + entryDate: { fontSize: 12, color: '#999' }, + entryContent: { fontSize: 16, color: '#333', lineHeight: 22, marginBottom: 12 }, + analysisBox: { + backgroundColor: '#F1F8F1', + borderRadius: 12, + padding: 12, + marginTop: 5, + }, + analysisHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 8, gap: 5 }, + analysisTitle: { fontSize: 12, fontWeight: 'bold', color: '#2E7D4A', textTransform: 'uppercase' }, + tagsRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 6, marginBottom: 8 }, + emotionTag: { backgroundColor: '#E8F5E8', paddingHorizontal: 8, paddingVertical: 4, borderRadius: 8 }, + tagText: { fontSize: 11, color: '#2E7D4A', fontWeight: '600' }, + analysisAdvice: { fontSize: 13, color: '#444', fontStyle: 'italic', lineHeight: 18 } +}); diff --git a/assets/lottie/celebration.json b/assets/lottie/celebration.json new file mode 100644 index 0000000..f84de5d --- /dev/null +++ b/assets/lottie/celebration.json @@ -0,0 +1 @@ +{"v":"5.5.6","fr":60,"ip":0,"op":300,"w":609,"h":812,"nm":"lottie (mobile)","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"_small-side","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[218,320,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":15,"op":234,"st":15,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"streamer b","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":166,"ix":10},"p":{"a":0,"k":[554,664,0],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.929411768913,0.745098054409,0.196078434587,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[4]},{"t":57,"s":[0.5]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[0]},{"t":57,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[35]},{"t":57,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":9,"op":58,"st":9,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"streamer a","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":167,"ix":10},"p":{"a":0,"k":[532,582,0],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.196078434587,0.380392163992,0.929411768913,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[4]},{"t":48,"s":[0.5]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":48,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[35]},{"t":48,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":49,"st":5,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"circle a","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":29,"s":[321.019]},{"t":158,"s":[1800]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":1,"s":[599.5,838,0],"to":[-30,-106.667,0],"ti":[46.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":29,"s":[419.5,198,0],"to":[-46.667,0,0],"ti":[0,0,0]},{"t":158,"s":[319.5,838,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":1,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":29,"s":[100,100,100]},{"t":128,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784316063,0.572549045086,0.180392161012,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":159,"st":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle b","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"t":128,"s":[1440]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":3,"s":[599.5,838,0],"to":[-26.667,-93.333,0],"ti":[66.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":21,"s":[439.5,278,0],"to":[-66.667,0,0],"ti":[0,0,0]},{"t":128,"s":[199.5,838,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":3,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":21,"s":[100,100,100]},{"t":98,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.588235318661,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":129,"st":3,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"star a","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":31,"s":[343.949]},{"t":158,"s":[1800]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":1,"s":[596.087,836.292,0],"to":[-36.098,-100,0],"ti":[52.765,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":31,"s":[379.5,236.292,0],"to":[-52.765,0,0],"ti":[0,0,0]},{"t":158,"s":[279.5,836.292,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":1,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":31,"s":[100,100,100]},{"t":128,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.745098054409,0.196078434587,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":159,"st":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"star b","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":23,"s":[288]},{"t":128,"s":[1800]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":3,"s":[596.087,836.292,0],"to":[-39.431,-113.333,0],"ti":[66.098,1.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":23,"s":[359.5,156.292,0],"to":[-66.098,-1.667,0],"ti":[0,0,0]},{"t":128,"s":[199.5,826.292,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":3,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":23,"s":[100,100,100]},{"t":98,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.537254929543,0.196078434587,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":129,"st":3,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"rec a","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":33,"s":[381.468]},{"t":218,"s":[2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[599.5,842,0],"to":[-23.333,-100,0],"ti":[41.333,1.333,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":33,"s":[459.5,242,0],"to":[-41.333,-1.333,0],"ti":[0,0,0]},{"t":218,"s":[351.5,834,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":0,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":33,"s":[100,100,100]},{"t":188,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.305882364511,0.831372559071,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"rec b","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[262.857]},{"t":191,"s":[2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":2,"s":[599.5,842,0],"to":[-23.333,-113.333,0],"ti":[74,5,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":25,"s":[459.5,162,0],"to":[-74,-5,0],"ti":[0,0,0]},{"t":191,"s":[155.5,812,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":2,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":25,"s":[100,100,100]},{"t":161,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.196078434587,0.784313738346,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":192,"st":2,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"square a","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":35,"s":[462.385]},{"t":218,"s":[2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[599.5,838,0],"to":[-43.333,-123.333,0],"ti":[60,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":35,"s":[339.5,98,0],"to":[-60,0,0],"ti":[0,0,0]},{"t":218,"s":[239.5,838,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":0,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":35,"s":[100,100,100]},{"t":188,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588235318661,0.831372559071,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"square b","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[285.714]},{"t":191,"s":[2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":2,"s":[599.5,838,0],"to":[-30,-120,0],"ti":[75,3.333,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":27,"s":[419.5,118,0],"to":[-75,-3.333,0],"ti":[0,0,0]},{"t":191,"s":[149.5,818,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0,0]},"t":2,"s":[50,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":27,"s":[100,100,100]},{"t":161,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.380392163992,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":192,"st":2,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"streamer b 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":171,"ix":10},"p":{"a":0,"k":[543,427,0],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.929411768913,0.196078434587,0.317647069693,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[4]},{"t":61,"s":[0.5]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[0]},{"t":61,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[35]},{"t":61,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":13,"op":62,"st":13,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"streamer a 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":151,"ix":10},"p":{"a":0,"k":[454,444,0],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882364511,0.831372559071,0.803921580315,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[4]},{"t":53,"s":[0.5]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[0]},{"t":53,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[35]},{"t":53,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":10,"op":54,"st":10,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"circle a 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":29,"s":[-371.368]},{"t":191,"s":[-2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":1,"s":[599.5,838,0],"to":[-53.333,-113.333,0],"ti":[56.667,-3.333,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":29,"s":[279.5,158,0],"to":[-56.667,3.333,0],"ti":[0,0,0]},{"t":191,"s":[259.5,858,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":1,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":29,"s":[100,100,100]},{"t":161,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.305882364511,0.831372559071,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":192,"st":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"circle b 2","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[-250.839]},{"t":158,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":3,"s":[599.5,838,0],"to":[-53.333,-100,0],"ti":[63,-7,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":21,"s":[279.5,238,0],"to":[-63,7,0],"ti":[0,0,0]},{"t":158,"s":[221.5,880,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":3,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":21,"s":[100,100,100]},{"t":128,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.537254929543,0.196078434587,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":159,"st":3,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"star a 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":31,"s":[-397.895]},{"t":191,"s":[-2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":1,"s":[596.087,836.292,0],"to":[-9.431,-113.333,0],"ti":[42.765,-3.333,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":31,"s":[539.5,156.292,0],"to":[-42.765,3.333,0],"ti":[0,0,0]},{"t":191,"s":[339.5,856.292,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":1,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":31,"s":[100,100,100]},{"t":161,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.305882364511,0.831372559071,0.803921580315,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":192,"st":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"star b 2","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":23,"s":[-278.71]},{"t":158,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":3,"s":[596.087,836.292,0],"to":[-12.765,-96.667,0],"ti":[52.765,-3.333,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":23,"s":[519.5,256.292,0],"to":[-52.765,3.333,0],"ti":[0,0,0]},{"t":158,"s":[279.5,856.292,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":3,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":23,"s":[100,100,100]},{"t":128,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.196078434587,0.784313738346,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":159,"st":3,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"rec a 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":33,"s":[-556.875]},{"t":128,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[599.5,842,0],"to":[-16.667,-120,0],"ti":[66.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":33,"s":[499.5,122,0],"to":[-66.667,0,0],"ti":[0,0,0]},{"t":128,"s":[199.5,842,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":0,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":33,"s":[100,100,100]},{"t":98,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588235318661,0.831372559071,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":129,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"rec b 2","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[-306.667]},{"t":218,"s":[-2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":2,"s":[599.5,842,0],"to":[-22.62,-109.87,0],"ti":[2.877,-2.055,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":25,"s":[339.5,262,0],"to":[-51.333,36.667,0],"ti":[0,0,0]},{"t":218,"s":[219.5,862,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":2,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":25,"s":[100,100,100]},{"t":188,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.196078434587,0.317647069693,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":219,"st":2,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"square a 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":35,"s":[-590.625]},{"t":128,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[599.5,838,0],"to":[-20,-90,0],"ti":[36.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":35,"s":[479.5,298,0],"to":[-36.667,0,0],"ti":[0,0,0]},{"t":128,"s":[379.5,838,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":0,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":35,"s":[100,100,100]},{"t":98,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784316063,0.572549045086,0.180392161012,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":129,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"square b 2","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[-333.333]},{"t":218,"s":[-2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":2,"s":[599.5,838,0],"to":[-10,-103.333,0],"ti":[50,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":27,"s":[539.5,218,0],"to":[-50,0,0],"ti":[0,0,0]},{"t":218,"s":[299.5,838,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"t":2,"s":[100,50,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":27,"s":[100,100,100]},{"t":188,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.588235318661,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":219,"st":2,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"_small-side","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[260,320,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":219,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"left","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":13,"op":313,"st":13,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"right","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":30,"op":330,"st":30,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"streamer a 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":14,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":13,"s":[219.178,-190.096,0],"to":[-95.333,426.667,0],"ti":[167.333,-560.667,0]},{"t":173,"s":[179.178,989.904,0]}],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.196078434587,0.380392163992,0.929411768913,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[4]},{"t":176,"s":[0.5]}],"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[0]},{"t":176,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[40]},{"t":176,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":13,"op":174,"st":13,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"streamer b 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-1.458,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":5,"s":[269.863,-175.455,0],"to":[-110,415.333,0],"ti":[216,-599.333,0]},{"t":173,"s":[69.863,984.545,0]}],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.929411768913,0.745098054409,0.196078434587,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[4]},{"t":173,"s":[0.5]}],"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":173,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":173,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":174,"st":5,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"circle a 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0]},{"t":155,"s":[1800]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":8,"s":[325.643,-26.292,0],"to":[-101.333,75.667,0],"ti":[15.333,-507.667,0]},{"t":155,"s":[125.643,835.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":8,"s":[50,100,100]},{"t":155,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784316063,0.572549045086,0.180392161012,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":156,"st":-7,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle b 4","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"t":215,"s":[2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":2,"s":[619.5,-26.292,0],"to":[-138,77.667,0],"ti":[-2,-497.667,0]},{"t":215,"s":[259.5,835.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":2,"s":[50,100,100]},{"t":215,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.588235318661,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":216,"st":-13,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"star a 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"t":245,"s":[2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":6,"s":[376.929,-28,0],"to":[-213.333,157.667,0],"ti":[173.333,-127.667,0]},{"t":245,"s":[116.929,834,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":6,"s":[50,100,100]},{"t":245,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.745098054409,0.196078434587,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":246,"st":-9,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"star b 4","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"t":125,"s":[1800]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":2,"s":[171.786,-28,0],"to":[0,0,0],"ti":[-161.333,-275.667,0]},{"t":125,"s":[251.786,834,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":2,"s":[50,100,100]},{"t":125,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.537254929543,0.196078434587,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":126,"st":-13,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"rec a 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"t":185,"s":[2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":4,"s":[428.214,-22.292,0],"to":[-167.333,119.667,0],"ti":[-130.667,-315.667,0]},{"t":185,"s":[228.214,839.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[50,100,100]},{"t":185,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.305882364511,0.831372559071,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":186,"st":-11,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"rec b 4","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"t":245,"s":[2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":6,"s":[223.071,-22.292,0],"to":[0,0,0],"ti":[-92.571,-383.708,0]},{"t":245,"s":[223.071,839.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":6,"s":[50,100,100]},{"t":245,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.196078434587,0.784313738346,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":246,"st":-9,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"square a 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"t":217,"s":[2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":4,"s":[120.5,-26.292,0],"to":[13,430.305,0],"ti":[52.221,-418.892,0]},{"t":217,"s":[198.5,833.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[50,100,100]},{"t":217,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588235318661,0.831372559071,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":218,"st":-11,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"square b 4","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0]},{"t":215,"s":[2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":8,"s":[274.357,-26.292,0],"to":[157.333,415.667,0],"ti":[22.667,-253.667,0]},{"t":215,"s":[114.357,835.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":8,"s":[50,100,100]},{"t":215,"s":[100,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588235318661,0.831372559071,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":216,"st":-7,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"streamer a 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":3,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[275.178,-173.096,0],"to":[-87.333,413.333,0],"ti":[177.333,-643.333,0]},{"t":185,"s":[219.178,974.904,0]}],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882364511,0.831372559071,0.803921580315,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4]},{"t":177,"s":[0.5]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"t":177,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[40]},{"t":177,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":186,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"streamer b 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":9,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":11,"s":[199.863,74.545,0],"to":[-13.363,405.455,0],"ti":[179.333,-430.667,0]},{"t":217,"s":[139.863,834.545,0]}],"ix":2},"a":{"a":0,"k":[-157,-245,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],"o":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],"v":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.929411768913,0.196078434587,0.317647069693,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[4]},{"t":199,"s":[0.5]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[0]},{"t":199,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[40]},{"t":199,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":11,"op":218,"st":11,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"circle a 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"t":125,"s":[-1800]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":2,"s":[365.643,-26.292,0],"to":[-101.333,75.667,0],"ti":[15.333,-507.667,0]},{"t":125,"s":[165.643,835.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":2,"s":[100,50,100]},{"t":125,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.305882364511,0.831372559071,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":126,"st":-13,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"circle b 3","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0]},{"t":245,"s":[-2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":8,"s":[519.5,-26.292,0],"to":[-138,77.667,0],"ti":[-2,-497.667,0]},{"t":245,"s":[159.5,835.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":8,"s":[100,50,100]},{"t":245,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.537254929543,0.196078434587,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":246,"st":-7,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"star a 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"t":245,"s":[-2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":6,"s":[416.929,-28,0],"to":[-213.333,157.667,0],"ti":[173.333,-127.667,0]},{"t":245,"s":[156.929,834,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":6,"s":[100,50,100]},{"t":245,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.305882364511,0.831372559071,0.803921580315,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":246,"st":-9,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"star b 3","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0]},{"t":155,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":8,"s":[211.786,-28,0],"to":[0,0,0],"ti":[-161.333,-275.667,0]},{"t":155,"s":[291.786,834,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":8,"s":[100,50,100]},{"t":155,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.196078434587,0.784313738346,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":156,"st":-7,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"rec a 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"t":185,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":4,"s":[468.214,-22.292,0],"to":[-167.333,119.667,0],"ti":[-130.667,-315.667,0]},{"t":185,"s":[268.214,839.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[100,50,100]},{"t":185,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588235318661,0.831372559071,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":186,"st":-11,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"rec b 3","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"t":245,"s":[-2880]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":6,"s":[263.071,-22.292,0],"to":[0,143.667,0],"ti":[-114.571,-267.708,0]},{"t":245,"s":[263.071,839.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":6,"s":[100,50,100]},{"t":245,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929411768913,0.196078434587,0.317647069693,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":246,"st":-9,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"square a 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"t":217,"s":[-2520]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":2,"s":[160.5,-26.292,0],"to":[13,430.305,0],"ti":[52.221,-418.892,0]},{"t":217,"s":[238.5,833.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":2,"s":[100,50,100]},{"t":217,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784316063,0.572549045086,0.180392161012,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":218,"st":-13,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"square b 3","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"t":185,"s":[-2160]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":4,"s":[314.357,-26.292,0],"to":[157.333,415.667,0],"ti":[22.667,-253.667,0]},{"t":185,"s":[154.357,835.708,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[100,50,100]},{"t":185,"s":[50,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.588235318661,0.929411768913,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":186,"st":-11,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"cannon (small - left)","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[76,452,0],"ix":2},"a":{"a":0,"k":[0,360,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":480,"h":720,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"cannon (small - right)","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[533,452,0],"ix":2},"a":{"a":0,"k":[479.994,360,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":480,"h":720,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"cannon (small - top)","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[304,408,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[102,102,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/assets/screenshots/articles_flashlist_v1.4.png b/assets/screenshots/articles_flashlist_v1.4.png new file mode 100644 index 0000000..87d1cfa Binary files /dev/null and b/assets/screenshots/articles_flashlist_v1.4.png differ diff --git a/assets/screenshots/coach_tts_v1.4.png b/assets/screenshots/coach_tts_v1.4.png new file mode 100644 index 0000000..877d46c Binary files /dev/null and b/assets/screenshots/coach_tts_v1.4.png differ diff --git a/assets/screenshots/journal_v1.4.png b/assets/screenshots/journal_v1.4.png new file mode 100644 index 0000000..2d8be90 Binary files /dev/null and b/assets/screenshots/journal_v1.4.png differ diff --git a/assets/screenshots/v1.3.0/ai_coach.png b/assets/screenshots/v1.3.0/ai_coach.png new file mode 100644 index 0000000..69aa9c8 Binary files /dev/null and b/assets/screenshots/v1.3.0/ai_coach.png differ diff --git a/assets/screenshots/v1.3.0/home.png b/assets/screenshots/v1.3.0/home.png new file mode 100644 index 0000000..98988b8 Binary files /dev/null and b/assets/screenshots/v1.3.0/home.png differ diff --git a/assets/screenshots/v1.3.0/knowledge_base_search.png b/assets/screenshots/v1.3.0/knowledge_base_search.png new file mode 100644 index 0000000..7f36115 Binary files /dev/null and b/assets/screenshots/v1.3.0/knowledge_base_search.png differ diff --git a/components/AchievementSystem.tsx b/components/AchievementSystem.tsx index 7ef1ecb..c164ddc 100644 --- a/components/AchievementSystem.tsx +++ b/components/AchievementSystem.tsx @@ -1,442 +1,99 @@ import React, { useState, useEffect } from 'react'; -import { View, Text, StyleSheet, TouchableOpacity, Modal, Animated, Easing } from 'react-native'; +import { View, Text, StyleSheet, ScrollView, Dimensions } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import { useRecovery } from '../hooks/useRecovery'; +import LottieView from 'lottie-react-native'; +import Animated, { FadeInUp } from 'react-native-reanimated'; -interface Achievement { - id: string; - title: string; - description: string; - icon: string; - condition: (soberDays: number, streakDays: number, completedExercises: number) => boolean; - unlocked: boolean; - unlockedAt?: string; - category: 'milestone' | 'streak' | 'learning' | 'dedication'; -} +const { width } = Dimensions.get('window'); -const achievements: Achievement[] = [ - { - id: '1', - title: 'Первый шаг', - description: 'Создали профиль и начали свой путь', - icon: 'emoji-events', - condition: () => true, - unlocked: false, - category: 'milestone' - }, - { - id: '2', - title: 'Неделя силы', - description: '7 дней трезвости подряд', - icon: 'local-fire-department', - condition: (_, streak) => streak >= 7, - unlocked: false, - category: 'streak' - }, - { - id: '3', - title: 'Месяц побед', - description: '30 дней трезвости подряд', - icon: 'military-tech', - condition: (_, streak) => streak >= 30, - unlocked: false, - category: 'streak' - }, - { - id: '4', - title: 'Исследователь НЛП', - description: 'Завершили 5 НЛП упражнений', - icon: 'psychology', - condition: (_, __, exercises) => exercises >= 5, - unlocked: false, - category: 'learning' - }, - { - id: '5', - title: 'Мастер медитации', - description: 'Использовали аудиотерапию 10 раз', - icon: 'spa', - condition: () => false, // Будет связано с аудио счетчиком - unlocked: false, - category: 'dedication' - }, - { - id: '6', - title: 'Сто дней свободы', - description: '100 дней трезвости подряд', - icon: 'workspace-premium', - condition: (_, streak) => streak >= 100, - unlocked: false, - category: 'streak' - } -]; - -export default function AchievementSystem() { - const { soberDays, getStreakDays } = useRecovery(); - const [userAchievements, setUserAchievements] = useState(achievements); - const [newAchievement, setNewAchievement] = useState(null); - const [showModal, setShowModal] = useState(false); - const [fadeAnim] = useState(new Animated.Value(0)); - const [scaleAnim] = useState(new Animated.Value(0.5)); +const AchievementSystem = () => { + const { soberDays } = useRecovery(); + const [showLottie, setShowLottie] = useState(false); useEffect(() => { - checkAchievements(); - }, [soberDays, getStreakDays()]); - - const checkAchievements = () => { - const streakDays = getStreakDays(); - const completedExercises = 0; // Это будет связано с реальным счетчиком - - const updatedAchievements = userAchievements.map(achievement => { - if (!achievement.unlocked && achievement.condition(soberDays, streakDays, completedExercises)) { - const newAchievement = { - ...achievement, - unlocked: true, - unlockedAt: new Date().toISOString() - }; - - // Показать уведомление о новом достижении - showAchievementUnlocked(newAchievement); - - return newAchievement; - } - return achievement; - }); - - setUserAchievements(updatedAchievements); - }; - - const showAchievementUnlocked = (achievement: Achievement) => { - setNewAchievement(achievement); - setShowModal(true); - - // Анимация появления - Animated.parallel([ - Animated.timing(fadeAnim, { - toValue: 1, - duration: 500, - useNativeDriver: true, - }), - Animated.timing(scaleAnim, { - toValue: 1, - duration: 500, - easing: Easing.back(1.5), - useNativeDriver: true, - }) - ]).start(); - }; - - const closeModal = () => { - Animated.parallel([ - Animated.timing(fadeAnim, { - toValue: 0, - duration: 300, - useNativeDriver: true, - }), - Animated.timing(scaleAnim, { - toValue: 0.5, - duration: 300, - useNativeDriver: true, - }) - ]).start(() => { - setShowModal(false); - setNewAchievement(null); - fadeAnim.setValue(0); - scaleAnim.setValue(0.5); - }); - }; - - const categoryColors = { - milestone: '#4CAF50', - streak: '#FF9800', - learning: '#2196F3', - dedication: '#9C27B0' - }; - - const categoryNames = { - milestone: 'Этапы', - streak: 'Серии', - learning: 'Обучение', - dedication: 'Посвященность' - }; - - const unlockedCount = userAchievements.filter(a => a.unlocked).length; - const totalCount = userAchievements.length; + if (soberDays > 0 && soberDays % 7 === 0) { + setShowLottie(true); + const timer = setTimeout(() => setShowLottie(false), 5000); + return () => clearTimeout(timer); + } + }, [soberDays]); + + const achievements = [ + { id: 1, title: 'Первый шаг', days: 1, icon: 'flare', color: '#FFD700' }, + { id: 2, title: 'Неделя свободы', days: 7, icon: 'auto-awesome', color: '#C0C0C0' }, + { id: 3, title: 'Чистый месяц', days: 30, icon: 'military-tech', color: '#CD7F32' }, + { id: 4, title: 'Квартал побед', days: 90, icon: 'workspace-premium', color: '#2E7D4A' }, + ]; return ( - - Достижения - {unlockedCount}/{totalCount} - - - - - - - - {userAchievements.map((achievement) => ( - - + Ваши достижения + + {achievements.map((ach) => { + const isUnlocked = soberDays >= ach.days; + return ( + - - - - - {achievement.title} - - - {achievement.description} - - {achievement.unlocked && achievement.unlockedAt && ( - - Получено: {new Date(achievement.unlockedAt).toLocaleDateString('ru-RU')} - - )} - - - {achievement.unlocked && ( - - )} - - ))} - - - {/* Achievement Unlocked Modal */} - - - - - - Новое достижение! - - - {newAchievement && ( - <> - - - - - - {newAchievement.title} - - - {newAchievement.description} - - - - {categoryNames[newAchievement.category]} - - - )} - - - Отлично! - - + {ach.title} + {ach.days} дн. + + ); + })} + + + {showLottie && ( + + + Потрясающий результат! 🎉 - + )} ); -} +}; const styles = StyleSheet.create({ - container: { + container: { padding: 20 }, + title: { fontSize: 20, fontWeight: 'bold', color: '#2E7D4A', marginBottom: 15 }, + scroll: { gap: 12 }, + card: { backgroundColor: 'white', - borderRadius: 15, - padding: 20, - margin: 20, + padding: 15, + borderRadius: 16, + alignItems: 'center', + width: width * 0.35, + elevation: 3, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, - elevation: 3 - }, - header: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - marginBottom: 15 - }, - title: { - fontSize: 20, - fontWeight: 'bold', - color: '#2E7D4A' - }, - progress: { - fontSize: 16, - color: '#666', - fontWeight: '500' }, - progressBar: { - height: 8, - backgroundColor: '#E0E0E0', - borderRadius: 4, - overflow: 'hidden', - marginBottom: 20 - }, - progressFill: { - height: '100%', - backgroundColor: '#4CAF50' - }, - achievementsList: { - gap: 12 - }, - achievementCard: { - flexDirection: 'row', - alignItems: 'center', - padding: 15, - borderRadius: 12, - gap: 15 - }, - unlockedCard: { - backgroundColor: '#F8F9FA', - borderWidth: 1, - borderColor: '#E8F5E8' - }, - lockedCard: { - backgroundColor: '#F5F5F5', - opacity: 0.6 - }, - iconContainer: { - width: 48, - height: 48, - borderRadius: 24, - justifyContent: 'center', - alignItems: 'center' - }, - achievementInfo: { - flex: 1 - }, - achievementTitle: { - fontSize: 16, - fontWeight: 'bold', - color: '#2E7D4A', - marginBottom: 4 - }, - achievementDescription: { - fontSize: 14, - color: '#666', - lineHeight: 20 - }, - lockedText: { - color: '#999' - }, - unlockedDate: { - fontSize: 12, - color: '#4CAF50', - marginTop: 4, - fontStyle: 'italic' - }, - modalOverlay: { - flex: 1, - backgroundColor: 'rgba(0,0,0,0.7)', - justifyContent: 'center', - alignItems: 'center' - }, - achievementModal: { - backgroundColor: 'white', - borderRadius: 20, - padding: 30, - alignItems: 'center', - minWidth: 300, - maxWidth: '85%' - }, - celebrationHeader: { - alignItems: 'center', - marginBottom: 20 - }, - celebrationTitle: { - fontSize: 24, - fontWeight: 'bold', - color: '#2E7D4A', - marginTop: 10 - }, - newAchievementIcon: { - width: 80, - height: 80, - borderRadius: 40, + lockedCard: { opacity: 0.6, backgroundColor: '#F0F0F0' }, + achTitle: { fontSize: 12, fontWeight: 'bold', color: '#333', marginTop: 10, textAlign: 'center' }, + lockedText: { color: '#999' }, + achDays: { fontSize: 10, color: '#666', marginTop: 4 }, + lottieOverlay: { + ...StyleSheet.absoluteFillObject, + backgroundColor: 'rgba(255,255,255,0.8)', justifyContent: 'center', alignItems: 'center', - marginBottom: 20 - }, - newAchievementTitle: { - fontSize: 20, - fontWeight: 'bold', - color: '#2E7D4A', - textAlign: 'center', - marginBottom: 10 - }, - newAchievementDescription: { - fontSize: 16, - color: '#666', - textAlign: 'center', - lineHeight: 22, - marginBottom: 15 + zIndex: 100, }, - categoryBadge: { - backgroundColor: '#E8F5E8', - color: '#2E7D4A', - paddingHorizontal: 12, - paddingVertical: 6, - borderRadius: 15, - fontSize: 12, - fontWeight: 'bold', - marginBottom: 20 - }, - closeButton: { - backgroundColor: '#2E7D4A', - paddingHorizontal: 30, - paddingVertical: 12, - borderRadius: 25 - }, - closeButtonText: { - color: 'white', - fontSize: 16, - fontWeight: 'bold' - } -}); \ No newline at end of file + lottie: { width: 200, height: 200 }, + celebrationText: { fontSize: 22, fontWeight: 'bold', color: '#2E7D4A', marginTop: 20 } +}); + +export default AchievementSystem; diff --git a/hooks/useAICoachViewModel.tsx b/hooks/useAICoachViewModel.tsx index 9ad24f3..9abf6f0 100644 --- a/hooks/useAICoachViewModel.tsx +++ b/hooks/useAICoachViewModel.tsx @@ -1,7 +1,8 @@ -import { useState, useEffect, useCallback, useMemo } from 'react'; -import { AICoachService, AICoachMessage } from '../services/AICoachService'; +import { useState, useEffect } from 'react'; +import { AICoachService, RecommendedArticle } from '../services/AICoachService'; import { useRecovery } from './useRecovery'; import NotificationService from '../services/notificationService'; +import * as Speech from 'expo-speech'; export interface ChatMessage { id: string; @@ -9,6 +10,8 @@ export interface ChatMessage { isUser: boolean; timestamp: Date; suggestions?: string[]; + recommendedArticles?: RecommendedArticle[]; + followUpQuestions?: string[]; } export function useAICoachViewModel() { @@ -20,31 +23,50 @@ export function useAICoachViewModel() { const [insights, setInsights] = useState(null); const [triggers, setTriggers] = useState([]); const [notifications, setNotifications] = useState([]); + const [isSpeaking, setIsSpeaking] = useState(false); useEffect(() => { initialize(); - }, []); + }, [soberDays, userProfile?.id]); const initialize = async () => { - // Initial welcome message const welcome: ChatMessage = { id: 'welcome', - text: `Привет! Я ваш AI-коуч. У вас ${soberDays} дней трезвости. Как я могу помочь?`, + text: `Привет! Я ваш AI-коуч. У вас ${soberDays} дней трезвости. Как я могу помочь сегодня?`, isUser: false, timestamp: new Date(), - suggestions: ['Как справиться с тягой?', 'Нужна мотивация', 'Я сорвался'] + suggestions: ['Как справиться с тягой?', 'Нужна мотивация', 'Я сорвался'], + followUpQuestions: ['Что у вас на уме?', 'Как ваше настроение?'] }; setMessages([welcome]); - // Load data const aiInsights = AICoachService.getUserInsights(userProfile?.id || 'default'); setInsights(aiInsights); setTriggers(AICoachService.detectTriggerPatterns(userProfile?.id || 'default')); setNotifications(NotificationService.getNotifications()); }; + const speak = (text: string) => { + if (isSpeaking) { + Speech.stop(); + setIsSpeaking(false); + } else { + setIsSpeaking(true); + Speech.speak(text, { + language: 'ru', + onDone: () => setIsSpeaking(false), + onError: () => setIsSpeaking(false) + }); + } + }; + + const stopSpeaking = () => { + Speech.stop(); + setIsSpeaking(false); + }; + const sendMessage = async (overrideText?: string) => { - const textToSend = overrideText || inputText; + const textToSend = typeof overrideText === 'string' ? overrideText : inputText; if (!textToSend.trim() || isTyping) return; const userMsg: ChatMessage = { @@ -55,7 +77,7 @@ export function useAICoachViewModel() { }; setMessages(prev => [...prev, userMsg]); - if (!overrideText) setInputText(''); + if (typeof overrideText !== 'string') setInputText(''); setIsTyping(true); try { @@ -70,15 +92,20 @@ export function useAICoachViewModel() { } ); - const aiMsg: ChatMessage = { - id: (Date.now() + 1).toString(), - text: response.message, - isUser: false, - timestamp: new Date(), - suggestions: response.suggestions - }; + if (response.success) { + const data = response.data; + const aiMsg: ChatMessage = { + id: (Date.now() + 1).toString(), + text: data.message, + isUser: false, + timestamp: new Date(), + suggestions: data.suggestions, + recommendedArticles: data.recommendedArticles, + followUpQuestions: data.followUpQuestions + }; - setMessages(prev => [...prev, aiMsg]); + setMessages(prev => [...prev, aiMsg]); + } } catch (e) { console.error(e); } finally { @@ -98,6 +125,9 @@ export function useAICoachViewModel() { notifications, sendMessage, soberDays, - getStreakDays + getStreakDays, + speak, + stopSpeaking, + isSpeaking }; } diff --git a/services/AICoachService.ts b/services/AICoachService.ts index f5e722d..523b760 100644 --- a/services/AICoachService.ts +++ b/services/AICoachService.ts @@ -1,5 +1,6 @@ -import { findRelevantKnowledge } from './psychologyKnowledgeBase'; +import { findRelevantKnowledge, psychologyKnowledgeBase } from './psychologyKnowledgeBase'; import { Result, success, failure } from './types'; +import { articlesDatabase } from './articlesDatabase'; export interface AICoachMessage { id: string; @@ -57,6 +58,12 @@ export interface ConversationMemory { }; } +export interface RecommendedArticle { + id: string; + title: string; + category: string; +} + export interface EnhancedAIResponse { message: string; emotionalTone: 'empathetic' | 'motivational' | 'educational' | 'supportive'; @@ -64,6 +71,7 @@ export interface EnhancedAIResponse { followUpQuestions: string[]; memoryUpdates: string[]; confidenceLevel: number; + recommendedArticles?: RecommendedArticle[]; } export class AICoachService { @@ -144,32 +152,56 @@ export class AICoachService { let response: string; let emotionalTone: 'empathetic' | 'motivational' | 'educational' | 'supportive'; let suggestions: string[] = []; + let followUpQuestions: string[] = []; if (knowledgeMatch) { - response = knowledgeMatch.response; - emotionalTone = 'educational'; - suggestions = knowledgeMatch.techniques.slice(0, 3); + response = knowledgeMatch.response; + emotionalTone = this.determineTone(knowledgeMatch.category); + suggestions = knowledgeMatch.techniques.slice(0, 3); + followUpQuestions = this.generateFollowUp(knowledgeMatch.category); } else { - response = "Я рядом и готов поддержать вас на пути к трезвости."; - emotionalTone = 'supportive'; - suggestions = ['Дыхательное упражнение', 'Прогулка']; + response = "Я рядом и готов поддержать вас на пути к трезвости. Расскажите подробнее, что вы сейчас чувствуете?"; + emotionalTone = 'supportive'; + suggestions = ['Дыхательное упражнение', 'Прогулка', 'HALT проверка']; + followUpQuestions = ['Как прошел ваш день?', 'Что сейчас больше всего беспокоит?']; } + const recommendedArticles = this.recommendArticles(topics); this.updateMemory(userId, userMessage, response, context.userMood, topics); return success({ - message: response, - emotionalTone, - suggestions, - followUpQuestions: [], - memoryUpdates: [`Updated memory for ${userId}`], - confidenceLevel: knowledgeMatch ? 0.9 : 0.6 + message: response, + emotionalTone, + suggestions, + followUpQuestions, + memoryUpdates: [`Updated memory for ${userId}`, `Detected topics: ${topics.join(', ')}`], + confidenceLevel: knowledgeMatch ? 0.95 : 0.6, + recommendedArticles }); } catch (e) { return failure(e as Error); } } + private static determineTone(category: string): 'empathetic' | 'motivational' | 'educational' | 'supportive' { + switch (category) { + case 'Эмоциональная регуляция': return 'empathetic'; + case 'Мотивация и целеполагание': return 'motivational'; + case 'Когнитивные искажения': return 'educational'; + case 'Работа с тягой и триггерами': return 'supportive'; + default: return 'supportive'; + } + } + + private static generateFollowUp(category: string): string[] { + switch (category) { + case 'Эмоциональная регуляция': return ['Как часто вы это чувствуете?', 'Что обычно помогает вам успокоиться?']; + case 'Работа с тягой и триггерами': return ['Где вы сейчас находитесь?', 'Что произошло непосредственно перед этим?']; + case 'Мотивация и целеполагание': return ['Какая ваша главная цель на сегодня?', 'Что дает вам силы продолжать?']; + default: return ['Как я еще могу вам помочь?']; + } + } + static getUserInsights(userId: string) { const memory = this.getUserMemory(userId); return { @@ -184,15 +216,16 @@ export class AICoachService { } static detectTriggerPatterns(userId: string): TriggerPattern[] { + // В реальном приложении здесь был бы сложный анализ истории return [ { id: '1', name: 'Вечерний стресс', type: 'temporal', - description: 'Повышенная тяга вечером', + description: 'Повышенная тяга в вечернее время', severity: 4, frequency: 3, - countermeasures: ['Медитация', 'Чай'] + countermeasures: ['Медитация', 'Вечерний чай', 'Чтение статей о сне'] } ]; } @@ -203,29 +236,55 @@ export class AICoachService { id: 'p1', type: 'risk_prediction', title: 'Риск в выходные', - description: 'Повышенный риск срыва в субботу', + description: 'Повышенный риск из-за изменения привычного графика', confidence: 70 } ]; } static async getMotivationalMessage(soberDays: number): Promise { - if (soberDays === 0) return "Начало пути - самый важный шаг. Вы справитесь!"; - return `Поздравляю с ${soberDays} днями трезвости! Ваш прогресс вдохновляет.`; + if (soberDays === 0) return "Начало пути - самый сложный и важный шаг. Вы уже здесь, и это победа!"; + if (soberDays % 7 === 0) return `Вы трезвы уже ${soberDays / 7} недель! Это потрясающий результат.`; + return `Поздравляю с ${soberDays} днями трезвости! Каждый день делает вас сильнее.`; } private static extractTopics(message: string): string[] { - const topicKeywords = { - craving: ['хочу выпить', 'тяга', 'искушение'], - anxiety: ['тревога', 'беспокойство', 'страх'] - }; - const topics: string[] = []; - Object.entries(topicKeywords).forEach(([topic, keywords]) => { - if (keywords.some(keyword => message.includes(keyword))) { - topics.push(topic); - } + const topics: Set = new Set(); + const lowerMessage = message.toLowerCase(); + + // Извлекаем топики на основе базы знаний + psychologyKnowledgeBase.forEach(kb => { + kb.topics.forEach(topic => { + if (topic.keyword.some(kw => lowerMessage.includes(kw.toLowerCase()))) { + topics.add(kb.category); + // Добавляем также конкретные теги для поиска статей + topic.keyword.forEach(kw => { + if (kw.length > 4) topics.add(kw); + }); + } + }); }); - return topics; + + return Array.from(topics); + } + + private static recommendArticles(topics: string[]): RecommendedArticle[] { + if (topics.length === 0) return []; + + // Поиск статей по совпадению категории или тегов + const recommended = articlesDatabase + .filter(article => + topics.some(topic => + article.tags.some(tag => tag.toLowerCase().includes(topic.toLowerCase())) || + article.category.toLowerCase().includes(topic.toLowerCase()) || + topic.toLowerCase().includes(article.category.toLowerCase()) + ) + ) + .sort((a, b) => b.readTime - a.readTime) // Предлагаем более глубокие статьи первыми + .slice(0, 3) + .map(a => ({ id: a.id, title: a.title, category: a.category })); + + return recommended; } private static updateMemory( @@ -243,5 +302,11 @@ export class AICoachService { userMood, topics }); + + // Обновляем статистику по эмоциям/топикам + if (topics.length > 0) { + const currentEmotions = [...memory.emotionalPattern.commonEmotions, ...topics]; + memory.emotionalPattern.commonEmotions = Array.from(new Set(currentEmotions)).slice(-10); + } } } diff --git a/services/articlesDatabase.ts b/services/articlesDatabase.ts index 283ba01..5e21525 100644 --- a/services/articlesDatabase.ts +++ b/services/articlesDatabase.ts @@ -373,9 +373,289 @@ export const articlesDatabase: Article[] = [ color: '#4CAF50' }, - // Продолжение следует... Из-за ограничения длины ответа, я добавлю оставшиеся статьи в отдельном сообщении. - // Текущий файл содержит 27 статей. Осталось добавить еще ~23 статьи для достижения 50+. + // СЕМЬЯ И ОТНОШЕНИЯ (8 статей) + { + id: generateArticleId(28), + title: 'Созависимость: как выйти из замкнутого круга', + category: 'Семья и отношения', + readTime: 10, + difficulty: 'intermediate', + preview: 'Понимание динамики отношений в семье с зависимостью', + content: `Созависимость — это патологическая поглощенность жизнью другого человека. В семье с зависимостью роли часто распределяются по "Треугольнику Карпмана": Спасатель, Преследователь, Жертва. Выход из созависимости требует: 1. Осознания своих потребностей отдельно от партнера. 2. Установления жестких, но здоровых границ. 3. Передачи ответственности за употребление самому зависимому. 4. Фокуса на собственной жизни и хобби. Помните, что вы не можете "вылечить" другого, но можете изменить свою реакцию на его поведение. Работа с психологом или посещение групп Al-Anon значительно ускоряет процесс исцеления.`, + tags: ['созависимость', 'отношения', 'границы', 'семья'], + icon: 'groups', + color: '#FF5722' + }, + { + id: generateArticleId(29), + title: 'Восстановление доверия в семье', + category: 'Семья и отношения', + readTime: 8, + difficulty: 'intermediate', + preview: 'Как вернуть веру близких после периода употребления', + content: `Доверие строится годами, а разрушается за секунды. В восстановлении доверия важны не слова, а последовательные действия. Шаги к возвращению доверия: 1. Радикальная честность даже в мелочах. 2. Прозрачность (делитесь планами, будьте на связи). 3. Выполнение обещаний без исключений. 4. Терпение (близким нужно время, чтобы перестать ждать подвоха). Избегайте оправданий. Вместо "я же трезвый, чего вы еще хотите?", используйте "я понимаю вашу тревогу, я сделаю всё, чтобы вы чувствовали себя в безопасности". Доверие возвращается медленно, но это самый ценный фундамент для новой жизни.`, + tags: ['доверие', 'честность', 'семья', 'прощение'], + icon: 'favorite', + color: '#FF5722' + }, + { + id: generateArticleId(30), + title: 'Как говорить с детьми об алкоголе', + category: 'Семья и отношения', + readTime: 9, + difficulty: 'beginner', + preview: 'Возрастные рекомендации по честному диалогу', + content: `Дети чувствуют напряжение в семье, даже если им ничего не говорят. Честный диалог важен для их психического здоровья. До 6 лет: объясняйте на уровне "папа/мама болеет, поэтому ведет себя странно, мы лечимся". 7-12 лет: можно говорить о болезни зависимости и о том, что это не вина ребенка. Подростки: важна максимальная честность и признание их чувств (гнева, стыда). Главные правила: 1. Не делайте из этого тайну. 2. Снимайте вину с ребенка. 3. Будьте примером выздоровления. 4. Обеспечьте ребенку поддержку специалистов при необходимости. Ваша трезвость — лучший подарок для будущего ваших детей.`, + tags: ['дети', 'родительство', 'воспитание', 'честность'], + icon: 'child-care', + color: '#FF5722' + }, + { + id: generateArticleId(31), + title: 'Секс и близость в трезвости', + category: 'Семья и отношения', + readTime: 8, + difficulty: 'intermediate', + preview: 'Переоткрытие физической близости без допинга', + content: `Для многих секс без алкоголя в начале пути кажется пугающим или "пресным". Это нормально. Алкоголь притуплял чувства и снимал барьеры искусственно. Восстановление либидо и близости занимает 3-6 месяцев. Рекомендации: 1. Говорите с партнером о своих страхах. 2. Начинайте с эмоциональной близости (разговоры, прогулки). 3. Не торопите события. 4. Практикуйте осознанность (mindfulness), чтобы чувствовать свое тело в моменте. Трезвый секс со временем становится гораздо глубже и качественнее, так как в нем присутствует реальная связь и искренние чувства, а не химическая иллюзия.`, + tags: ['близость', 'секс', 'отношения', 'телесность'], + icon: 'favorite', + color: '#FF5722' + }, + { + id: generateArticleId(32), + title: 'Установление границ с пьющим окружением', + category: 'Семья и отношения', + readTime: 7, + difficulty: 'beginner', + preview: 'Как защитить свою трезвость от влияния других', + content: `Границы — это не стены, это двери, которые вы контролируете. Если в вашем окружении остались люди, которые продолжают активно употреблять, вам нужны четкие правила. 1. Избегайте мест, где алкоголь — главная цель. 2. Заранее подготовьте фразу отказа ("Я сегодня не пью, спасибо"). 3. Уходите, если чувствуете дискомфорт или давление. 4. Сообщите близким о своей позиции. Настоящие друзья поддержат ваше решение. Те, кто настаивает на выпивке, возможно, не должны быть в вашем близком кругу на этапе раннего выздоровления. Ваша трезвость — это ваш приоритет №1.`, + tags: ['границы', 'друзья', 'окружение', 'отказ'], + icon: 'shield', + color: '#FF5722' + }, + + // КАРЬЕРА И ФИНАНСЫ (7 статей) + { + id: generateArticleId(33), + title: 'Поиск работы после перерыва в карьере', + category: 'Карьера и финансы', + readTime: 9, + difficulty: 'intermediate', + preview: 'Стратегии возвращения на рынок труда', + content: `Возвращение к работе — важный этап социализации. Как подготовиться: 1. Обновите резюме, сфокусировавшись на навыках, а не на хронологии. 2. Не обязательно раскрывать детали зависимости на первом собеседовании. Можно сказать о "семейных обстоятельствах" или "личном проекте". 3. Начинайте с частичной занятости или фриланса, чтобы не перегореть. 4. Используйте волонтерство для получения свежего опыта. Главное — ваша надежность сейчас. Трезвый сотрудник — это дисциплинированный и ответственный профессионал, который ценит свой шанс.`, + tags: ['работа', 'резюме', 'карьера', 'собеседование'], + icon: 'work', + color: '#607D8B' + }, + { + id: generateArticleId(34), + title: 'Финансовая грамотность в трезвости', + category: 'Карьера и финансы', + readTime: 8, + difficulty: 'beginner', + preview: 'Как закрыть долги и начать копить', + content: `Зависимость часто оставляет после себя финансовые руины. План восстановления: 1. Проведите полный аудит долгов. 2. Составьте бюджет (приложения для учета расходов помогут). 3. Метод "снежного кома" для выплаты кредитов (сначала самые мелкие для мотивации). 4. Считайте сэкономленные на алкоголе деньги — откладывайте их в специальный фонд. Финансовая стабильность снижает уровень стресса и, как следствие, риск срыва. Трезвость — это самая выгодная инвестиция, которую вы когда-либо делали.`, + tags: ['деньги', 'бюджет', 'долги', 'экономия'], + icon: 'account-balance-wallet', + color: '#607D8B' + }, + { + id: generateArticleId(35), + title: 'Тайм-менеджмент: как не перегрузить себя', + category: 'Карьера и финансы', + readTime: 7, + difficulty: 'beginner', + preview: 'Планирование дня для поддержания баланса', + content: `Хаос в расписании — враг трезвости. Структура дня дает ощущение контроля и безопасности. Правила: 1. Оставляйте буферное время между задачами. 2. Правило "одного важного дела" в день. 3. Обязательно планируйте отдых и приемы пищи. 4. Используйте списки дел, чтобы разгрузить мозг. Помните про HALT (не будьте слишком голодным, злым, одиноким или усталым). Ваша задача — быть продуктивным, а не занятым 24/7. Баланс между работой и выздоровлением — ключ к долгосрочному успеху.`, + tags: ['время', 'планирование', 'продуктивность', 'баланс'], + icon: 'schedule', + color: '#607D8B' + }, + + // ПИТАНИЕ И ОБРАЗ ЖИЗНИ (10 статей) + { + id: generateArticleId(36), + title: 'Суперфуды для восстановления печени', + category: 'Питание и образ жизни', + readTime: 8, + difficulty: 'beginner', + preview: 'Продукты, которые ускоряют детоксикацию', + content: `Печень обладает потрясающей способностью к регенерации. Помогите ей: 1. Куркума (снимает воспаление). 2. Расторопша (силимарин защищает клетки печени). 3. Крестоцветные овощи (брокколи, цветная капуста активируют ферменты детокса). 4. Свекла (улучшает отток желчи). 5. Зеленый чай (антиоксиданты). Избегайте жареного, избытка сахара и трансжиров в первые месяцы. Пейте много чистой воды. Ваша печень скажет вам "спасибо" уже через несколько недель правильного питания.`, + tags: ['печень', 'диета', 'здоровье', 'детокс'], + icon: 'restaurant', + color: '#4CAF50' + }, + { + id: generateArticleId(37), + title: 'Витамины группы B: фундамент нервной системы', + category: 'Питание и образ жизни', + readTime: 7, + difficulty: 'intermediate', + preview: 'Почему они критически важны после отказа от алкоголя', + content: `Алкоголь буквально "вымывает" витамины группы B, особенно B1 (тиамин), B6 и B12. Дефицит приводит к раздражительности, депрессии, провалам в памяти и нейропатии. Источники: цельнозерноные продукты, бобовые, орехи, нежирное мясо, яйца. В начале выздоровления часто рекомендуется прием витаминных комплексов (после консультации с врачом). Восполнение дефицита группы B заметно улучшает ясность мышления и эмоциональную стабильность уже в первый месяц трезвости.`, + tags: ['витамины', 'нервы', 'здоровье', 'бады'], + icon: 'medication', + color: '#4CAF50' + }, + { + id: generateArticleId(38), + title: 'Сон без алкоголя: гигиена и ритуалы', + category: 'Питание и образ жизни', + readTime: 8, + difficulty: 'beginner', + preview: 'Как наладить сон, если мучает бессонница', + content: `Бессонница — самый частый повод для срыва в первый месяц. Алкоголь "выключал" мозг, но не давал реального отдыха. Как уснуть самому: 1. Никаких экранов за час до сна (синий свет блокирует мелатонин). 2. Ритуал: теплая ванна, чтение бумажной книги, чай с мятой. 3. Прохладная и темная комната. 4. Техника "сканирования тела" для расслабления. Если не можете уснуть более 20 минут — встаньте, займитесь чем-то спокойным (не телефоном!) и вернитесь в постель, когда почувствуете сонливость. Сон нормализуется, дайте организму время.`, + tags: ['сон', 'бессонница', 'режим', 'отдых'], + icon: 'bedtime', + color: '#4CAF50' + }, + { + id: generateArticleId(39), + title: 'Тяга к сладкому: почему это происходит', + category: 'Питание и образ жизни', + readTime: 7, + difficulty: 'beginner', + preview: 'Как управлять сахарной зависимостью в трезвости', + content: `Многие в трезвости становятся "сладкоежками". Причины: 1. Алкоголь — это быстрые углеводы, мозг требует привычного топлива. 2. Сахар стимулирует дофамин, как и алкоголь. Советы: 1. Не боритесь со сладким слишком жестко в первый месяц (лучше съесть конфету, чем выпить). 2. Переходите на фрукты и ягоды. 3. Ешьте больше белка и клетчатки, чтобы стабилизировать уровень сахара в крови. 4. Пейте воду при позывах к сладкому. Со временем тяга к сахару снизится вместе с общим восстановлением биохимии мозга.`, + tags: ['сахар', 'питание', 'дофамин', 'привычки'], + icon: 'icecream', + color: '#4CAF50' + }, + { + id: generateArticleId(40), + title: 'Йога и медитация для начинающих', + category: 'Питание и образ жизни', + readTime: 9, + difficulty: 'beginner', + preview: 'Связь тела и разума в процессе исцеления', + content: `Йога помогает "заземлиться" и почувствовать свое тело без критики. Медитация учит наблюдать за мыслями и тягой, не действуя по импульсу. Начните с 5-10 минут в день. Используйте приложения или видео-уроки. Фокусируйтесь на дыхании. Когда внимание улетает к мыслям об алкоголе — мягко возвращайте его к вдоху и выдоху. Это тренирует префронтальную кору головного мозга, которая отвечает за волевые решения. Регулярная практика снижает уровень кортизола (гормона стресса) на 25% и более.`, + tags: ['йога', 'медитация', 'mindfulness', 'стресс'], + icon: 'self-improvement', + color: '#4CAF50' + }, + // РЕЛАКСАЦИЯ И ХОББИ (10 статей) + { + id: generateArticleId(41), + title: 'Арт-терапия: выразите чувства без слов', + category: 'Релаксация и хобби', + readTime: 8, + difficulty: 'beginner', + preview: 'Как творчество помогает проживать сложные эмоции', + content: `Арт-терапия не требует умения рисовать. Цель — процесс, а не результат. Попробуйте: 1. Свободное рисование (выплесните гнев или грусть цветами). 2. Коллаж (создайте "карту трезвой жизни"). 3. Лепка из глины (работа с текстурой успокаивает). Творчество переключает мозг из режима "выживания и тяги" в режим "созидания". Это отличный способ занять вечера и получить безопасную дозу дофамина от создания чего-то нового.`, + tags: ['арт-терапия', 'творчество', 'хобби', 'эмоции'], + icon: 'palette', + color: '#FFC107' + }, + { + id: generateArticleId(42), + title: 'Чтение как способ побега в реальность', + category: 'Релаксация и хобби', + readTime: 7, + difficulty: 'beginner', + preview: 'Почему книги лучше соцсетей для восстановления', + content: `Книги требуют глубокой концентрации, что восстанавливает внимание, поврежденное алкоголем. Полезны как мемуары людей, победивших зависимость (дает надежду), так и художественная литература (развивает эмпатию). Соцсети же часто провоцируют сравнение себя с другими и вызывают стресс. Поставьте цель: читать по 15-20 страниц перед сном. Это успокаивает нервную систему и готовит к здоровому сну.`, + tags: ['книги', 'чтение', 'саморазвитие', 'фокус'], + icon: 'auto-stories', + color: '#FFC107' + }, + { + id: generateArticleId(43), + title: 'Садоводство и контакт с природой', + category: 'Релаксация и хобби', + readTime: 8, + difficulty: 'beginner', + preview: 'Терапевтический эффект земли и растений', + content: `Забота о растениях учит терпению — вы видите, как из маленького семени вырастает жизнь при регулярном уходе. Это метафора вашего выздоровления. Контакт с почвой (микробиом земли) научно доказанно повышает уровень серотонина. Если нет дачи — начните с цветов на подоконнике или прогулок в лесу. Наблюдение за циклами природы помогает принять временность трудностей в вашей жизни: зима (тяга) всегда сменяется весной (облегчением).`, + tags: ['природа', 'садоводство', 'растения', 'спокойствие'], + icon: 'park', + color: '#FFC107' + }, + { + id: generateArticleId(44), + title: 'Музыкальная терапия: создайте свой плейлист', + category: 'Релаксация и хобби', + readTime: 7, + difficulty: 'beginner', + preview: 'Влияние звуков на биохимию мозга', + content: `Музыка способна мгновенно менять эмоциональное состояние. Создайте три плейлиста: 1. "Релакс" (бинауральные ритмы, эмбиент для сна). 2. "Энергия" (ритмичная музыка для спорта и уборки). 3. "Мотивация" (песни со смыслом, которые вдохновляют вас оставаться трезвым). Избегайте музыки, которая прочно ассоциируется у вас с моментами употребления. Звуковая стимуляция может стать отличным якорем для входа в состояние спокойствия.`, + tags: ['музыка', 'звуки', 'настроение', 'плейлист'], + icon: 'music-note', + color: '#FFC107' + }, + { + id: generateArticleId(45), + title: 'Волонтерство: помогая другим, помогаешь себе', + category: 'Релаксация и хобби', + readTime: 10, + difficulty: 'beginner', + preview: 'Смысл и социальная значимость в трезвости', + content: `Помощь тем, кому хуже, переключает фокус с собственных страданий и жалеющей себя позиции. Волонтерство повышает уровень окситоцина и дает чувство принадлежности. Это может быть приют для животных, помощь пожилым или поддержка новичков в группах трезвости. Когда вы видите, что приносите пользу, ваша самооценка растет на реальных делах, а не на пустых обещаниях. Это мощный антидот против одиночества и скуки.`, + tags: ['волонтерство', 'помощь', 'смысл', 'социум'], + icon: 'volunteer-activism', + color: '#FFC107' + }, + { + id: generateArticleId(46), + title: 'Путешествия в трезвости: новые горизонты', + category: 'Релаксация и хобби', + readTime: 9, + difficulty: 'intermediate', + preview: 'Как отдыхать без "олл-инклюзива"', + content: `Первое путешествие без алкоголя может быть вызовом. Советы: 1. Выбирайте активный отдых (походы, экскурсии). 2. Избегайте отелей с бесплатным баром в первые полгода. 3. Планируйте ранние подъемы (вы увидите рассветы, которые раньше просыпали). 4. Найдите местное сообщество трезвости в городе посещения. Вы удивитесь, сколько деталей и красоты мира вы пропускали, находясь в тумане употребления. Трезвые воспоминания остаются с вами навсегда, а не стираются к утру.`, + tags: ['путешествия', 'отпуск', 'впечатления', 'туризм'], + icon: 'flight-takeoff', + color: '#FFC107' + }, + { + id: generateArticleId(47), + title: 'Дневниковая практика: разговор с собой', + category: 'Релаксация и хобби', + readTime: 8, + difficulty: 'beginner', + preview: 'Письменные техники для ясности ума', + content: `Дневник — это бесплатный терапевт, доступный 24/7. Методы: 1. Утренние страницы (3 страницы потока сознания). 2. Дневник благодарности (3 пункта вечером). 3. Дневник чувств (запись триггеров и реакций). Вынос мыслей на бумагу снижает тревожность и помогает увидеть ситуацию со стороны. Со временем перечитывание старых записей покажет вам, какой колоссальный путь вы проделали, что станет лучшей мотивацией в трудные минуты.`, + tags: ['дневник', 'письмо', 'самопознание', 'рефлексия'], + icon: 'edit-note', + color: '#FFC107' + }, + { + id: generateArticleId(48), + title: 'Спорт на свежем воздухе', + category: 'Релаксация и хобби', + readTime: 8, + difficulty: 'beginner', + preview: 'Сочетание движения и кислорода', + content: `Бег, скандинавская ходьба или просто активная прогулка в парке эффективнее спортзала для восстановления психики. Сочетание физической нагрузки и солнечного света (витамин D) лучше всего регулирует циркадные ритмы и настроение. Старайтесь проводить на улице не менее 30 минут в светлое время суток. Это естественным образом снижает тягу и помогает мозгу вырабатывать серотонин.`, + tags: ['спорт', 'прогулки', 'воздух', 'здоровье'], + icon: 'directions-run', + color: '#FFC107' + }, + { + id: generateArticleId(49), + title: 'Кулинария: новые вкусы жизни', + category: 'Релаксация и хобби', + readTime: 7, + difficulty: 'beginner', + preview: 'От алкогольных калорий к гастрономическому искусству', + content: `Приготовление сложного блюда требует внимания и времени — это отличная медитация. В трезвости ваши вкусовые рецепторы восстанавливаются, и еда обретает новые оттенки. Попробуйте изучить новую кухню (например, средиземноморскую или азиатскую). Красивая сервировка и качественные продукты — это форма заботы о себе, которой вы заслуживаете. Сделайте ужин праздником вкуса, а не просто приемом пищи.`, + tags: ['кулинария', 'еда', 'рецепты', 'забота о себе'], + icon: 'restaurant-menu', + color: '#FFC107' + }, + { + id: generateArticleId(50), + title: 'Изучение языков: тренировка нейропластичности', + category: 'Релаксация и хобби', + readTime: 10, + difficulty: 'intermediate', + preview: 'Как учеба восстанавливает связи в мозге', + content: `Изучение иностранного языка — это лучший фитнес для мозга. Это задействует память, логику и слух одновременно. Процесс формирования новых синапсов при обучении напрямую конкурирует с процессами деградации, вызванными алкоголем. Начните с Duolingo или подобных сервисов по 15 минут в день. Успехи в учебе дают мощный выброс здорового дофамина и повышают вашу уверенность в своих когнитивных способностях.`, + tags: ['обучение', 'языки', 'мозг', 'интеллект'], + icon: 'translate', + color: '#FFC107' + } ]; // Валидация базы данных diff --git a/services/dailyMotivationService.ts b/services/dailyMotivationService.ts index 4321604..5b7ed69 100644 --- a/services/dailyMotivationService.ts +++ b/services/dailyMotivationService.ts @@ -1,606 +1,85 @@ -// Система ежедневных напоминаний и мотивационных сообщений -import * as Notifications from 'expo-notifications'; -import { Platform } from 'react-native'; - -export interface DailyReminder { +export interface MotivationQuote { id: string; - type: 'motivation' | 'technique' | 'check_in' | 'milestone' | 'wellness' | 'social'; - title: string; - body: string; - scheduledTime: string; // HH:MM format - frequency: 'daily' | 'weekly' | 'weekdays' | 'weekends' | 'custom'; - customDays?: number[]; // 0-6, где 0 = воскресенье - enabled: boolean; - personalized: boolean; - category: string; - priority: 'low' | 'medium' | 'high'; - actionButtons?: NotificationAction[]; + text: string; + author: string; + category: 'motivation' | 'wisdom' | 'discipline' | 'hope' | 'strength' | 'patience'; } -export interface NotificationAction { +export interface RecoveryTip { id: string; title: string; - action: string; - icon?: string; -} - -export interface MotivationalContent { - id: string; - type: 'quote' | 'affirmation' | 'reminder' | 'achievement' | 'tip' | 'story'; content: string; - author?: string; - category: string; - mood: 'uplifting' | 'calming' | 'energizing' | 'reflective' | 'encouraging'; - difficultyLevel: 'easy' | 'challenging' | 'inspiring'; - personalityMatch: string[]; // типы личности, которым подходит -} - -export interface UserMotivationProfile { - userId: string; - preferredTimes: string[]; - motivationStyle: 'gentle' | 'direct' | 'inspirational' | 'practical'; - responseToReminders: 'high' | 'medium' | 'low'; - effectiveCategories: string[]; - skipDays: string[]; // дни недели для пропуска - personalizedQuotes: string[]; - milestonePreferences: MilestonePreference[]; -} - -export interface MilestonePreference { - type: string; - frequency: number; - celebrationStyle: 'quiet' | 'enthusiastic' | 'social'; + icon: string; } -export class DailyMotivationSystem { - private reminders: Map = new Map(); - private motivationalLibrary: MotivationalContent[]; - private userProfiles: Map = new Map(); - - constructor() { - this.motivationalLibrary = this.initializeMotivationalContent(); - this.setupNotificationHandlers(); - } - - // Инициализация системы уведомлений - async initializeNotifications(): Promise { - // Запрашиваем разрешения - const { status } = await Notifications.requestPermissionsAsync(); - - if (status !== 'granted') { - console.warn('Notification permissions not granted'); - return; - } - - // Настраиваем категории уведомлений - await this.setupNotificationCategories(); - - // Настраиваем обработчики - this.setupNotificationHandlers(); - } - - // Создание персонализированных напоминаний для пользователя - async createPersonalizedReminders(userId: string, preferences?: any): Promise { - const userProfile = this.getUserProfile(userId); - const baseReminders = this.getBaseReminderTemplates(); - - const personalizedReminders = baseReminders.map(reminder => - this.personalizeReminder(reminder, userProfile, preferences) - ); - - // Добавляем специальные напоминания на основе прогресса - const progressReminders = await this.generateProgressBasedReminders(userId); - personalizedReminders.push(...progressReminders); - - // Сохраняем напоминания - this.reminders.set(userId, personalizedReminders); - - // Планируем уведомления - await this.scheduleAllReminders(userId, personalizedReminders); - } - - // Базовые шаблоны напоминаний - private getBaseReminderTemplates(): DailyReminder[] { - return [ - { - id: 'morning_motivation', - type: 'motivation', - title: '🌅 Доброе утро!', - body: 'Новый день - новые возможности для роста и исцеления', - scheduledTime: '08:00', - frequency: 'daily', - enabled: true, - personalized: true, - category: 'morning', - priority: 'medium', - actionButtons: [ - { id: 'set_intention', title: 'Поставить цель дня', action: 'open_goal_setting' }, - { id: 'morning_meditation', title: 'Утренняя медитация', action: 'start_meditation' } - ] - }, - { - id: 'midday_checkin', - type: 'check_in', - title: '☀️ Как дела?', - body: 'Время проверить, как вы себя чувствуете', - scheduledTime: '13:00', - frequency: 'daily', - enabled: true, - personalized: true, - category: 'wellness', - priority: 'low', - actionButtons: [ - { id: 'mood_check', title: 'Отметить настроение', action: 'open_mood_tracker' }, - { id: 'quick_technique', title: 'Быстрая техника', action: 'suggest_technique' } - ] - }, - { - id: 'evening_reflection', - type: 'wellness', - title: '🌙 Время размышлений', - body: 'Что хорошего произошло сегодня?', - scheduledTime: '21:00', - frequency: 'daily', - enabled: true, - personalized: true, - category: 'evening', - priority: 'medium', - actionButtons: [ - { id: 'gratitude_log', title: 'Записать благодарность', action: 'open_gratitude' }, - { id: 'day_reflection', title: 'Отразить день', action: 'open_reflection' } - ] - }, - { - id: 'weekly_milestone', - type: 'milestone', - title: '🎉 Еженедельный прогресс', - body: 'Время отметить ваши достижения за неделю!', - scheduledTime: '19:00', - frequency: 'weekly', - enabled: true, - personalized: true, - category: 'achievement', - priority: 'high' - }, - { - id: 'technique_reminder', - type: 'technique', - title: '🧘 Время для практики', - body: 'Несколько минут практики могут изменить весь день', - scheduledTime: '16:00', - frequency: 'daily', - enabled: true, - personalized: true, - category: 'practice', - priority: 'medium' - }, - { - id: 'social_connection', - type: 'social', - title: '👥 Связь с близкими', - body: 'Поддержка других людей важна для выздоровления', - scheduledTime: '18:30', - frequency: 'weekdays', - enabled: false, // По умолчанию выключено - personalized: true, - category: 'social', - priority: 'low' - } - ]; - } - - // Персонализация напоминания - private personalizeReminder( - reminder: DailyReminder, - profile: UserMotivationProfile, - preferences?: any - ): DailyReminder { - const personalized = { ...reminder }; - - // Адаптируем время на основе предпочтений пользователя - if (profile.preferredTimes.length > 0) { - const preferredTime = profile.preferredTimes.find(time => - Math.abs(this.timeToMinutes(time) - this.timeToMinutes(reminder.scheduledTime)) < 120 - ); - if (preferredTime) { - personalized.scheduledTime = preferredTime; - } - } - - // Адаптируем стиль мотивации - personalized.body = this.adaptMessageStyle(reminder.body, profile.motivationStyle); - - // Включаем/выключаем на основе эффективности - if (profile.responseToReminders === 'low' && reminder.priority === 'low') { - personalized.enabled = false; - } - - return personalized; - } - - // Генерация напоминаний на основе прогресса - private async generateProgressBasedReminders(userId: string): Promise { - const progressReminders: DailyReminder[] = []; - - // Здесь можно добавить логику для создания напоминаний на основе: - // - Серии трезвых дней - // - Пройденных техник - // - Достигнутых целей - // - Предстоящих сложных дат - - // Пример: напоминание о серии - progressReminders.push({ - id: `streak_reminder_${userId}`, - type: 'milestone', - title: '🔥 Ваша серия растет!', - body: 'Каждый день трезвости - это победа. Продолжайте!', - scheduledTime: '20:00', - frequency: 'weekly', - enabled: true, - personalized: true, - category: 'achievement', - priority: 'high' - }); - - return progressReminders; - } - - // Планирование уведомлений - private async scheduleAllReminders(userId: string, reminders: DailyReminder[]): Promise { - // Отменяем существующие уведомления для пользователя - await this.cancelUserNotifications(userId); - - for (const reminder of reminders) { - if (reminder.enabled) { - await this.scheduleReminder(userId, reminder); - } - } - } - - // Планирование отдельного напоминания - private async scheduleReminder(userId: string, reminder: DailyReminder): Promise { - const notificationId = `${userId}_${reminder.id}`; - - try { - const trigger = this.createNotificationTrigger(reminder); - - await Notifications.scheduleNotificationAsync({ - identifier: notificationId, - content: { - title: reminder.title, - body: this.getPersonalizedContent(userId, reminder), - data: { - userId, - reminderId: reminder.id, - type: reminder.type, - category: reminder.category - }, - categoryIdentifier: reminder.category, - sound: 'default' - }, - trigger - }); - } catch (error) { - console.error('Error scheduling reminder:', error); - } - } - - // Создание триггера уведомления - private createNotificationTrigger(reminder: DailyReminder): any { - const [hours, minutes] = reminder.scheduledTime.split(':').map(Number); - - switch (reminder.frequency) { - case 'daily': - return { - hour: hours, - minute: minutes, - repeats: true - }; - - case 'weekly': - return { - weekday: 1, // Понедельник - hour: hours, - minute: minutes, - repeats: true - }; - - case 'weekdays': - // Планируем для каждого рабочего дня отдельно - return { - weekday: [2, 3, 4, 5, 6], // Вт-Сб (в iOS воскресенье = 1) - hour: hours, - minute: minutes, - repeats: true - }; - - case 'weekends': - return { - weekday: [1, 7], // Вс, Сб - hour: hours, - minute: minutes, - repeats: true - }; - - case 'custom': - if (reminder.customDays) { - return reminder.customDays.map(day => ({ - weekday: day + 1, // iOS использует 1-7 - hour: hours, - minute: minutes, - repeats: true - })); - } - break; - } - - return null; - } - - // Получение персонализированного контента - private getPersonalizedContent(userId: string, reminder: DailyReminder): string { - if (!reminder.personalized) { - return reminder.body; - } - - const profile = this.getUserProfile(userId); - - // Выбираем мотивационный контент на основе профиля - const relevantContent = this.motivationalLibrary.filter(content => - content.category === reminder.category || - profile.effectiveCategories.includes(content.category) - ); - - if (relevantContent.length > 0) { - const selectedContent = relevantContent[Math.floor(Math.random() * relevantContent.length)]; - return this.adaptMessageStyle(selectedContent.content, profile.motivationStyle); - } - - return reminder.body; - } - - // Адаптация стиля сообщения - private adaptMessageStyle(message: string, style: string): string { - switch (style) { - case 'gentle': - return message.replace(/!/g, '.').replace(/\b(должны|нужно)\b/g, 'можете'); - - case 'direct': - return message + ' Сделайте это прямо сейчас.'; - - case 'inspirational': - return '✨ ' + message + ' Вы способны на великие дела!'; - - case 'practical': - return message + ' Это займет всего несколько минут.'; - - default: - return message; - } - } - - // Инициализация мотивационного контента - private initializeMotivationalContent(): MotivationalContent[] { - return [ - { - id: 'quote_001', - type: 'quote', - content: 'Каждый день трезвости - это день, когда вы выбираете себя', - category: 'morning', - mood: 'uplifting', - difficultyLevel: 'easy', - personalityMatch: ['gentle', 'inspirational'] - }, - { - id: 'affirmation_001', - type: 'affirmation', - content: 'Я достоин любви, здоровья и счастья', - category: 'morning', - mood: 'uplifting', - difficultyLevel: 'easy', - personalityMatch: ['gentle', 'inspirational'] - }, - { - id: 'reminder_001', - type: 'reminder', - content: 'Помните: прогресс не всегда линеен, но каждый шаг имеет значение', - category: 'evening', - mood: 'encouraging', - difficultyLevel: 'challenging', - personalityMatch: ['direct', 'practical'] - }, - { - id: 'tip_001', - type: 'tip', - content: 'Когда чувствуете тягу, попробуйте технику "Остановись-Подыши-Наблюдай-Продолжай"', - category: 'practice', - mood: 'practical', - difficultyLevel: 'easy', - personalityMatch: ['practical', 'direct'] - }, - { - id: 'achievement_001', - type: 'achievement', - content: 'Вы уже прошли самую трудную часть - решили изменить свою жизнь', - category: 'achievement', - mood: 'encouraging', - difficultyLevel: 'inspiring', - personalityMatch: ['inspirational', 'gentle'] - }, - { - id: 'story_001', - type: 'story', - content: 'Каждый рассвет напоминает нам: у нас есть еще один шанс начать заново', - category: 'morning', - mood: 'reflective', - difficultyLevel: 'inspiring', - personalityMatch: ['inspirational', 'gentle'] - } - ]; - } - - // Настройка категорий уведомлений - private async setupNotificationCategories(): Promise { - const categories = [ - { - identifier: 'morning', - actions: [ - { identifier: 'set_intention', title: 'Поставить цель' }, - { identifier: 'morning_meditation', title: 'Медитация' } - ] - }, - { - identifier: 'wellness', - actions: [ - { identifier: 'mood_check', title: 'Настроение' }, - { identifier: 'quick_technique', title: 'Техника' } - ] - }, - { - identifier: 'evening', - actions: [ - { identifier: 'gratitude_log', title: 'Благодарность' }, - { identifier: 'day_reflection', title: 'Размышления' } - ] - } - ]; - - if (Platform.OS === 'ios') { - await Notifications.setNotificationCategoryAsync( - 'morning', - categories[0].actions.map(action => ({ - identifier: action.identifier, - buttonTitle: action.title, - options: { foreground: true } - })) - ); - } - } - - // Настройка обработчиков уведомлений - private setupNotificationHandlers(): void { - // Обработчик нажатия на уведомление - Notifications.addNotificationResponseReceivedListener(response => { - const { userId, reminderId, type } = response.notification.request.content.data as any; - this.handleNotificationResponse(userId, reminderId, type, response.actionIdentifier); - }); - - // Обработчик получения уведомления в активном приложении - Notifications.addNotificationReceivedListener(notification => { - console.log('Notification received while app is active:', notification); - }); - } - - // Обработка ответов на уведомления - private handleNotificationResponse( - userId: string, - reminderId: string, - type: string, - actionId: string - ): void { - console.log('Notification response:', { userId, reminderId, type, actionId }); - - // Здесь можно добавить логику для обработки различных действий - switch (actionId) { - case 'set_intention': - // Открыть экран постановки целей - break; - case 'morning_meditation': - // Запустить медитацию - break; - case 'mood_check': - // Открыть трекер настроения - break; - // ... другие действия - } - - // Записываем статистику взаимодействия - this.recordNotificationInteraction(userId, reminderId, actionId); - } - - // Запись статистики взаимодействий - private recordNotificationInteraction( - userId: string, - reminderId: string, - actionId: string - ): void { - // Здесь можно сохранять статистику для улучшения персонализации - console.log('Recording interaction:', { userId, reminderId, actionId }); - } - - // Отмена уведомлений пользователя - private async cancelUserNotifications(userId: string): Promise { - const scheduledNotifications = await Notifications.getAllScheduledNotificationsAsync(); - - const userNotifications = scheduledNotifications.filter(notification => - notification.identifier.startsWith(userId) - ); - - for (const notification of userNotifications) { - await Notifications.cancelScheduledNotificationAsync(notification.identifier); - } - } - - // Вспомогательные методы - private getUserProfile(userId: string): UserMotivationProfile { - let profile = this.userProfiles.get(userId); - - if (!profile) { - profile = { - userId, - preferredTimes: ['08:00', '13:00', '21:00'], - motivationStyle: 'gentle', - responseToReminders: 'medium', - effectiveCategories: ['morning', 'evening'], - skipDays: [], - personalizedQuotes: [], - milestonePreferences: [ - { type: 'daily', frequency: 1, celebrationStyle: 'quiet' }, - { type: 'weekly', frequency: 7, celebrationStyle: 'enthusiastic' } - ] - }; - this.userProfiles.set(userId, profile); - } - - return profile; - } - - private timeToMinutes(time: string): number { - const [hours, minutes] = time.split(':').map(Number); - return hours * 60 + minutes; - } - - // Публичные методы для управления напоминаниями - async updateReminderSettings( - userId: string, - reminderId: string, - settings: Partial - ): Promise { - const userReminders = this.reminders.get(userId); - if (!userReminders) return; - - const reminderIndex = userReminders.findIndex(r => r.id === reminderId); - if (reminderIndex === -1) return; - - // Обновляем настройки - userReminders[reminderIndex] = { ...userReminders[reminderIndex], ...settings }; - - // Перепланируем уведомления - await this.scheduleAllReminders(userId, userReminders); - } - - async getUserReminders(userId: string): Promise { - return this.reminders.get(userId) || []; - } - - async enableReminder(userId: string, reminderId: string): Promise { - await this.updateReminderSettings(userId, reminderId, { enabled: true }); - } - - async disableReminder(userId: string, reminderId: string): Promise { - await this.updateReminderSettings(userId, reminderId, { enabled: false }); +export class DailyMotivationService { + private static quotes: MotivationQuote[] = [ + { id: 'q1', text: 'Величайшая победа — это победа над самим собой.', author: 'Платон', category: 'wisdom' }, + { id: 'q2', text: 'Неважно, как медленно вы идете, пока вы не остановитесь.', author: 'Конфуций', category: 'discipline' }, + { id: 'q3', text: 'Трезвость не открывает врата рая, чтобы впустить вас туда, она открывает врата ада, чтобы выпустить вас оттуда.', author: 'Анонимный источник', category: 'motivation' }, + { id: 'q4', text: 'Ваше будущее создается тем, что вы делаете сегодня, а не завтра.', author: 'Роберт Кийосаки', category: 'discipline' }, + { id: 'q5', text: 'Трудности часто готовят обычного человека к необычной судьбе.', author: 'К.С. Льюис', category: 'hope' }, + { id: 'q6', text: 'Вы никогда не будете слишком стары, чтобы поставить новую цель или мечтать о новой мечте.', author: 'К.С. Льюис', category: 'hope' }, + { id: 'q7', text: 'Успех — это способность идти от одной неудачи к другой, не теряя энтузиазма.', author: 'Уинстон Черчилль', category: 'strength' }, + { id: 'q8', text: 'Наше величайшее величие не в том, чтобы никогда не падать, а в том, чтобы подниматься каждый раз, когда мы падаем.', author: 'Конфуций', category: 'strength' }, + { id: 'q9', text: 'Всегда кажется, что это невозможно, пока это не сделано.', author: 'Нельсон Мандела', category: 'motivation' }, + { id: 'q10', text: 'Тот, кто имеет "зачем" жить, может вынести почти любое "как".', author: 'Виктор Франкл', category: 'wisdom' }, + { id: 'q11', text: 'Ваша нынешняя ситуация — это не ваш конечный пункт назначения. Лучшее еще впереди.', author: 'Аноним', category: 'hope' }, + { id: 'q12', text: 'Дисциплина — это выбор между тем, чего вы хотите сейчас, и тем, чего вы хотите больше всего.', author: 'Авраам Линкольн', category: 'discipline' }, + { id: 'q13', text: 'Трезвость — это не просто отсутствие алкоголя, это присутствие самого себя.', author: 'Аноним', category: 'wisdom' }, + { id: 'q14', text: 'Один день за раз. Одно утро за раз. Один час за раз.', author: 'Принцип 12 шагов', category: 'patience' }, + { id: 'q15', text: 'Вы сильнее, чем вы думаете. Вы умнее, чем вы верите. Вы любимы больше, чем вы знаете.', author: 'А.А. Милн', category: 'strength' }, + { id: 'q16', text: 'Жизнь начинается там, где заканчивается ваша зона комфорта.', author: 'Нил Уолш', category: 'motivation' }, + { id: 'q17', text: 'Будьте тем изменением, которое вы хотите видеть в мире.', author: 'Махатма Ганди', category: 'wisdom' }, + { id: 'q18', text: 'Единственный способ сделать выдающуюся работу — искренне любить то, что вы делаете.', author: 'Стив Джобс', category: 'discipline' }, + { id: 'q19', text: 'Ваше время ограничено, не тратьте его, живя чужой жизнью.', author: 'Стив Джобс', category: 'wisdom' }, + { id: 'q20', text: 'Не бойтесь расти медленно, бойтесь оставаться неизменными.', author: 'Китайская пословица', category: 'patience' }, + { id: 'q21', text: 'Измените свои мысли, и вы измените свой мир.', author: 'Норман Винсент Пил', category: 'strength' }, + { id: 'q22', text: 'Каждое утро у нас есть шанс начать жизнь заново.', author: 'Будда', category: 'hope' }, + { id: 'q23', text: 'Свобода — это то, что вы делаете с тем, что с вами сделали.', author: 'Жан-Поль Сартр', category: 'wisdom' }, + { id: 'q24', text: 'Трезвость — это форма самоуважения.', author: 'Аноним', category: 'strength' }, + { id: 'q25', text: 'Маленькие шаги в правильном направлении могут привести к большим переменам.', author: 'Аноним', category: 'patience' }, + { id: 'q26', text: 'Самый лучший способ предсказать будущее — создать его.', author: 'Питер Друкер', category: 'discipline' }, + { id: 'q27', text: 'Прошлого не существует, есть только настоящее, в котором мы создаем будущее.', author: 'Аноним', category: 'wisdom' }, + { id: 'q28', text: 'Трезвость дает вам возможность быть тем, кем вы всегда хотели быть.', author: 'Аноним', category: 'hope' }, + { id: 'q29', text: 'Сила не в том, чтобы не иметь слабостей, а в том, чтобы уметь с ними работать.', author: 'Аноним', category: 'strength' }, + { id: 'q30', text: 'Каждый день трезвости — это кирпичик в фундаменте вашей новой жизни.', author: 'Аноним', category: 'discipline' } + ]; + + private static tips: RecoveryTip[] = [ + { id: 't1', title: 'Пейте больше воды', content: 'Гидратация помогает вымывать токсины и улучшает когнитивные функции. Старайтесь пить 1.5-2 литра в день.', icon: 'local-drink' }, + { id: 't2', title: 'Практикуйте дыхание', content: 'Когда чувствуете тягу, сделайте 10 глубоких вдохов. Это снизит уровень кортизола и успокоит нервную систему.', icon: 'air' }, + { id: 't3', title: 'Планируйте вечер', content: 'Заранее придумайте занятие на вечер пятницы или выходные, чтобы избежать старых триггерных ситуаций.', icon: 'event' }, + { id: 't4', title: 'HALT проверка', content: 'Если возникло желание выпить, проверьте: вы Голодны, Злы, Одиноки или Устали? Удовлетворите базовую потребность.', icon: 'warning' }, + { id: 't5', title: 'Дневник благодарности', content: 'Записывайте 3 вещи, за которые вы благодарны сегодня. Это переключает мозг на позитивное восприятие.', icon: 'edit' }, + { id: 't6', title: 'Физическая активность', content: 'Даже 15-минутная прогулка повышает уровень эндорфинов и помогает справиться со стрессом.', icon: 'directions-run' }, + { id: 't7', title: 'Звонок другу', content: 'Если становится тяжело, не изолируйтесь. Позвоните человеку, который поддерживает вашу трезвость.', icon: 'phone' }, + { id: 't8', title: 'Избегайте сахара', content: 'Скачки сахара могут имитировать тягу к алкоголю. Выбирайте сложные углеводы и белок.', icon: 'restaurant' }, + { id: 't9', title: 'Новое хобби', content: 'Займите мозг изучением чего-то нового. Это создает новые нейронные связи и снижает скуку.', icon: 'lightbulb' }, + { id: 't10', title: 'Сон — приоритет', content: 'Недостаток сна резко снижает волевой ресурс. Старайтесь спать не менее 7-8 часов.', icon: 'bedtime' }, + { id: 't11', title: 'Техника 5 минут', content: 'Если тяга сильная, договоритесь с собой подождать всего 5 минут. Обычно за это время острый пик проходит.', icon: 'timer' }, + { id: 't12', title: 'Поощряйте себя', content: 'На сэкономленные деньги купите себе что-то приятное. Визуализируйте пользу трезвости.', icon: 'redeem' }, + { id: 't13', title: 'Чистое окружение', content: 'Уберите из дома всё, что напоминает об употреблении. Создайте безопасное пространство.', icon: 'home' }, + { id: 't14', title: 'Медитация', content: 'Всего 10 минут тишины и наблюдения за дыханием в день укрепляют префронтальную кору мозга.', icon: 'self-improvement' }, + { id: 't15', title: 'Визуализация', content: 'Представьте свой вечер завтра: вы просыпаетесь бодрым, без похмелья и чувства вины.', icon: 'visibility' } + ]; + + static getDailyQuote(): MotivationQuote { + const dayOfYear = Math.floor((new Date().getTime() - new Date(new Date().getFullYear(), 0, 0).getTime()) / 86400000); + return this.quotes[dayOfYear % this.quotes.length]; + } + + static getDailyTip(): RecoveryTip { + const dayOfYear = Math.floor((new Date().getTime() - new Date(new Date().getFullYear(), 0, 0).getTime()) / 86400000); + return this.tips[dayOfYear % this.tips.length]; + } + + static getRandomQuote(): MotivationQuote { + return this.quotes[Math.floor(Math.random() * this.quotes.length)]; + } + + static getRandomTip(): RecoveryTip { + return this.tips[Math.floor(Math.random() * this.tips.length)]; } } - -export default DailyMotivationSystem; \ No newline at end of file diff --git a/services/journalService.ts b/services/journalService.ts new file mode 100644 index 0000000..f4b843b --- /dev/null +++ b/services/journalService.ts @@ -0,0 +1,100 @@ + +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { Result, success, failure } from './types'; +import { AICoachService } from './AICoachService'; + +export interface JournalEntry { + id: string; + date: string; + content: string; + mood: number; + tags: string[]; + aiAnalysis?: { + sentiment: 'positive' | 'negative' | 'neutral'; + dominantEmotions: string[]; + potentialTriggers: string[]; + advice: string; + }; +} + +const STORAGE_KEY = '@journal_entries'; + +export class JournalService { + static async getEntries(): Promise> { + try { + const data = await AsyncStorage.getItem(STORAGE_KEY); + return success(data ? JSON.parse(data) : []); + } catch (e) { + return failure(e as Error); + } + } + + static async addEntry(content: string, mood: number): Promise> { + try { + const entriesResult = await this.getEntries(); + if (!entriesResult.success) return entriesResult as any; + const entries = entriesResult.data; + + const analysis = await this.analyzeEntry(content); + + const newEntry: JournalEntry = { + id: Date.now().toString(), + date: new Date().toISOString(), + content, + mood, + tags: analysis.dominantEmotions, + aiAnalysis: analysis + }; + + const updatedEntries = [newEntry, ...entries]; + await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updatedEntries)); + + return success(newEntry); + } catch (e) { + return failure(e as Error); + } + } + + private static async analyzeEntry(content: string) { + // В реальном приложении здесь был бы вызов LLM + // Имитируем анализ на основе ключевых слов + const lowerContent = content.toLowerCase(); + const emotions = []; + const triggers = []; + + if (lowerContent.includes('груст') || lowerContent.includes('плохо')) emotions.push('грусть'); + if (lowerContent.includes('зл') || lowerContent.includes('бесит')) emotions.push('гнев'); + if (lowerContent.includes('рад') || lowerContent.includes('хорошо')) emotions.push('радость'); + if (lowerContent.includes('трево') || lowerContent.includes('страх')) emotions.push('тревога'); + + if (lowerContent.includes('раб')) triggers.push('работа'); + if (lowerContent.includes('вечер')) triggers.push('вечернее время'); + if (lowerContent.includes('друз')) triggers.push('социальное давление'); + + return { + sentiment: emotions.includes('радость') ? 'positive' : emotions.length > 0 ? 'negative' : 'neutral' as any, + dominantEmotions: emotions.length > 0 ? emotions : ['спокойствие'], + potentialTriggers: triggers, + advice: this.getAdviceForEmotions(emotions) + }; + } + + private static getAdviceForEmotions(emotions: string[]): string { + if (emotions.includes('гнев')) return 'Попробуйте технику глубокого дыхания 4-7-8, чтобы успокоиться.'; + if (emotions.includes('тревога')) return 'Используйте технику заземления 5-4-3-2-1 для возврата в настоящий момент.'; + if (emotions.includes('грусть')) return 'Не забывайте о самосострадании. Вы делаете большую работу.'; + return 'Продолжайте осознанно проживать каждый день. Вы на верном пути!'; + } + + static async deleteEntry(id: string): Promise> { + try { + const entriesResult = await this.getEntries(); + if (!entriesResult.success) return entriesResult as any; + const updatedEntries = entriesResult.data.filter(e => e.id !== id); + await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updatedEntries)); + return success(undefined); + } catch (e) { + return failure(e as Error); + } + } +} diff --git a/services/psychologyKnowledgeBase.ts b/services/psychologyKnowledgeBase.ts index 54c3188..a6ca4a9 100644 --- a/services/psychologyKnowledgeBase.ts +++ b/services/psychologyKnowledgeBase.ts @@ -1,4 +1,4 @@ -// Расширенная база психологических знаний для AI-коуча +// Расширенная база психологических знаний для AI-коуча - Версия 1.3.0 export interface PsychologyKnowledge { category: string; @@ -20,26 +20,45 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ techniques: [ 'Упражнение "Колесо жизни": оцените 8 сфер жизни и увидьте, как алкоголь влияет на каждую', 'Техника "Письмо себе из будущего": напишите письмо от себя через год трезвости', - 'Визуализация последствий: представьте свою жизнь через 5 лет с алкоголем VS без него' + 'Визуализация последствий: представьте свою жизнь через 5 лет с алкоголем VS без него', + 'Техника 5 "Почему?": спрашивайте себя почему трезвость важна, пока не дойдете до базовой ценности' ], resources: [ 'Книга: "Атомные привычки" Джеймс Клир', 'Практика: Дневник благодарности за трезвость', - 'Видео: TED Talk "Сила привычек"' + 'Видео: TED Talk "Сила привычек"', + 'Статья: "Построение новой идентичности в трезвости"' ] }, { - keyword: ['сорваться', 'не получится', 'не справлюсь', 'слабый'], + keyword: ['сорваться', 'не получится', 'не справлюсь', 'слабый', 'не верю'], response: 'Эти мысли называются "катастрофизацией" - когнитивное искажение, при котором мы предсказываем худший исход. Важно отделить мысли от фактов. То, что вы думаете, что сорветесь, не означает, что это произойдет. Давайте проверим эти мысли на реалистичность.', techniques: [ 'CBT техника "Проверка мыслей": какие факты за и против этой мысли?', 'Декатастрофизация: что самое худшее может произойти? Как справитесь?', - 'Поиск альтернативных мыслей: как бы друг посмотрел на эту ситуацию?' + 'Поиск альтернативных мыслей: как бы друг посмотрел на эту ситуацию?', + 'Техника "Доказательства успеха": вспомните 3 случая, когда вы справились с трудностью' ], resources: [ 'Рабочая тетрадь CBT для зависимостей', 'Приложение: Трекер когнитивных искажений', - 'Техника: ABCDE модель Альберта Эллиса' + 'Техника: ABCDE модель Альберта Эллиса', + 'Статья: "Переопределение успеха и неудачи"' + ] + }, + { + keyword: ['прокрастинация', 'откладываю', 'лень', 'не могу начать'], + response: 'Прокрастинация часто связана не с ленью, а с тревогой перед задачей или перфекционизмом. В трезвости мозг может сопротивляться новым усилиям. Важно снизить порог входа для действия.', + techniques: [ + 'Правило 5 минут: договоритесь делать задачу всего 5 минут', + 'Техника Помодоро: 25 минут работы, 5 минут отдыха', + 'Разбиение на "швейцарский сыр": выгрызайте в задаче маленькие кусочки по 2 минуты', + 'Устранение цифровых триггеров: уберите телефон в другую комнату' + ], + resources: [ + 'Книга: "Легкий способ перестать откладывать на потом" Нил Фьоре', + 'Приложение: Forest для концентрации', + 'Статья: "Тайм-менеджмент: как не перегрузить себя"' ] } ] @@ -48,7 +67,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Эмоциональная регуляция', topics: [ { - keyword: ['тревога', 'паника', 'страх', 'беспокойство', 'нервничаю'], + keyword: ['тревога', 'паника', 'страх', 'беспокойство', 'нервничаю', 'дрожь'], response: 'Тревога - это нормальная эмоция, но при зависимости она может быть усилена. Алкоголь ранее подавлял тревогу, теперь ваш мозг учится справляться с ней естественными способами. Это временно и улучшится с практикой.', techniques: [ 'Дыхание 4-7-8: вдох 4, задержка 7, выдох 8 - активирует парасимпатическую систему', @@ -59,11 +78,12 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Приложение: Headspace или Calm для управления тревогой', 'Книга: "Осознанность" Марк Уильямс', - 'Практика: Дневник тревоги для выявления триггеров' + 'Практика: Дневник тревоги для выявления триггеров', + 'Статья: "Тревога и панические атаки в трезвости"' ] }, { - keyword: ['гнев', 'злость', 'раздражение', 'бешенство', 'ярость'], + keyword: ['гнев', 'злость', 'раздражение', 'бешенство', 'ярость', 'бесит'], response: 'Гнев часто маскирует более глубокие эмоции - боль, страх, беспомощность. При восстановлении гнев может усилиться, так как алкоголь больше не подавляет эмоции. Важно научиться выражать гнев здоровыми способами.', techniques: [ 'RAIN техника: Recognize (распознать), Allow (разрешить), Investigate (исследовать), Nurture (позаботиться)', @@ -74,11 +94,12 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Книга: "Гнев: укрощение зверя внутри" Рональд Поттер-Эфрон', 'DBT навыки эмоциональной регуляции', - 'Практика: Лист "Триггеры гнева" для отслеживания паттернов' + 'Практика: Лист "Триггеры гнева" для отслеживания паттернов', + 'Статья: "Управление гневом в трезвости"' ] }, { - keyword: ['депрессия', 'грусть', 'печаль', 'тоска', 'безнадежность'], + keyword: ['депрессия', 'грусть', 'печаль', 'тоска', 'безнадежность', 'ничего не хочу'], response: 'Депрессия часто сопровождает раннее восстановление. Алкоголь нарушал баланс нейромедиаторов, и мозгу нужно время, чтобы восстановиться. Обычно улучшение наступает через 2-4 недели трезвости, но важно обратиться к специалисту, если депрессия тяжелая.', techniques: [ 'Поведенческая активация: делайте приятные активности, даже если не хочется', @@ -89,7 +110,23 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Самопомощь при депрессии: руководство CBT', 'Приложение: Moodpath для отслеживания настроения', - 'Важно: консультация психотерапевта при затяжной депрессии' + 'Важно: консультация психотерапевта при затяжной депрессии', + 'Статья: "Работа с депрессией в восстановлении"' + ] + }, + { + keyword: ['скука', 'скучно', 'нечем заняться', 'серость', 'пустота'], + response: 'Скука в трезвости - это признак того, что ваша дофаминовая система восстанавливается. Раньше алкоголь давал "искусственную яркость", теперь мозгу нужно время, чтобы снова научиться радоваться простым вещам.', + techniques: [ + 'Список 20 удовольствий: напишите 20 вещей, которые приносят радость без алкоголя', + 'Эксперимент недели: каждую неделю пробуйте одно совершенно новое хобби', + 'Mindfulness: учитесь присутствовать в моменте скуки, наблюдайте за ней', + 'Волонтерство: помощь другим - лучший способ наполнить жизнь смыслом' + ], + resources: [ + 'Статья: "Скука в трезвости: новый источник смысла"', + 'Книга: "Поток" Михай Чиксентмихайи', + 'Список идей для хобби в приложении' ] } ] @@ -98,7 +135,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Работа с тягой и триггерами', topics: [ { - keyword: ['хочу выпить', 'тяга', 'искушение', 'соблазн'], + keyword: ['хочу выпить', 'тяга', 'искушение', 'соблазн', 'желание выпить'], response: 'Тяга - это волна. Она поднимается, достигает пика и спадает, обычно за 15-30 минут. Ключ - не бороться с ней, а "серфить" по ней. Наблюдайте за ощущениями без осуждения и действия.', techniques: [ 'Urge Surfing (Серфинг по тяге): наблюдайте за тягой как волной, где в теле чувствуете, как меняется', @@ -109,11 +146,12 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Приложение: I Am Sober для отслеживания тяг', 'Техника: Карточки совладания с тягой', - 'Видео: Mindfulness для работы с тягой' + 'Видео: Mindfulness для работы с тягой', + 'Статья: "Работа с тягой: техники в моменте"' ] }, { - keyword: ['триггер', 'запускает', 'провоцирует', 'напоминает'], + keyword: ['триггер', 'запускает', 'провоцирует', 'напоминает', 'обстановка'], response: 'Триггеры бывают внешние (места, люди, время) и внутренние (эмоции, мысли). Важно составить карту триггеров и план действий для каждого. На ранних этапах - избегание, позже - навыки совладания.', techniques: [ 'Картирование триггеров: список всех известных триггеров + рейтинг силы', @@ -124,7 +162,23 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Рабочая тетрадь: Триггеры и план совладания', 'Практика: Ежедневный обзор триггеров', - 'Техника: Экспозиционная терапия (с терапевтом)' + 'Техника: Экспозиционная терапия (с терапевтом)', + 'Статья: "Триггеры: как их распознать и управлять ими"' + ] + }, + { + keyword: ['срыв', 'сорвался', 'выпил', 'все пропало', 'ошибка'], + response: 'Срыв - это не конец пути, а важная точка обучения. Главное сейчас - не впадать в самобичевание, а проанализировать ситуацию и вернуться в трезвость прямо сейчас. Ваша прошлая трезвость никуда не делась.', + techniques: [ + 'Анализ срыва: Что произошло за 48 часов до? Какая была эмоция? Какая мысль?', + 'План 24 часов: сфокусируйтесь только на том, чтобы быть трезвым следующие 24 часа', + 'Техника "Прощение себя": признайте ошибку, но не делайте ее своей личностью', + 'Звонок поддержки: честно расскажите о случившемся близкому человеку' + ], + resources: [ + 'Статья: "Переопределение успеха и неудачи"', + 'Группы поддержки (АА, SMART Recovery)', + 'Книга: "Путь к выздоровлению" Стефани Браун' ] } ] @@ -133,7 +187,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Когнитивные искажения', topics: [ { - keyword: ['все или ничего', 'идеально', 'перфекционизм'], + keyword: ['все или ничего', 'идеально', 'перфекционизм', 'крайности'], response: 'Мышление "все или ничего" - частое когнитивное искажение. Реальность не черно-белая. Прогресс не линейный. Даже "плохой" день трезвости лучше дня с алкоголем.', techniques: [ 'Техника "Оттенки серого": оцените ситуацию по шкале 0-100, а не 0 или 100', @@ -166,7 +220,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Социальные ситуации', topics: [ { - keyword: ['друзья пьют', 'компания', 'вечеринка', 'давление'], + keyword: ['друзья пьют', 'компания', 'вечеринка', 'давление', 'праздник'], response: 'Социальное давление - один из самых сложных триггеров. Важно иметь заготовленные ответы, поддерживающих людей и стратегию выхода из ситуации.', techniques: [ 'Подготовка отговорок: "Я за рулем", "Принимаю лекарства", "Эксперимент со здоровьем"', @@ -177,11 +231,12 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Скрипты для отказа от алкоголя', 'Практика: Ролевая игра сложных ситуаций', - 'Сообщество: группы поддержки для социализации без алкоголя' + 'Сообщество: группы поддержки для социализации без алкоголя', + 'Статья: "Установление границ с пьющим окружением"' ] }, { - keyword: ['одиночество', 'изоляция', 'нет друзей', 'один'], + keyword: ['одиночество', 'изоляция', 'нет друзей', 'один', 'никто не понимает'], response: 'Изоляция - опасный фактор риска. Человек - социальное существо. Важно строить новые, здоровые связи. Это процесс, требующий времени и усилий.', techniques: [ 'Маленькие шаги социализации: начните с онлайн-групп, потом очные встречи', @@ -201,7 +256,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Самооценка и идентичность', topics: [ { - keyword: ['стыд', 'вина', 'позор', 'ненавижу себя'], + keyword: ['стыд', 'вина', 'позор', 'ненавижу себя', 'совесть'], response: 'Стыд и вина - мощные эмоции при зависимости. Важно различать: вина - "я сделал плохое", стыд - "я плохой". Вина может быть продуктивной, стыд - разрушителен. Вы не определяетесь прошлым.', techniques: [ 'Техника самосострадания Кристин Нефф: говорите с собой как с другом', @@ -212,11 +267,12 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Книга: "Дары несовершенства" Брене Браун', 'Медитация самосострадания', - 'Терапия: работа со стыдом с психологом' + 'Терапия: работа со стыдом с психологом', + 'Статья: "Прощение себя: работа со стыдом и виной"' ] }, { - keyword: ['кто я', 'идентичность', 'потерял себя', 'не знаю'], + keyword: ['кто я', 'идентичность', 'потерял себя', 'не знаю кто я'], response: 'Алкоголь часто становится частью идентичности. При отказе может возникнуть кризис "кто я без алкоголя?". Это возможность построить новую, аутентичную идентичность.', techniques: [ 'Исследование ценностей: что действительно важно для вас?', @@ -227,7 +283,8 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Упражнения по исследованию ценностей', 'Книга: "Психология убеждений" Кэрол Двек', - 'Практика: Дневник "Кто я?"' + 'Практика: Дневник "Кто я?"', + 'Статья: "Построение новой идентичности в трезвости"' ] } ] @@ -236,7 +293,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Стресс и копинг-стратегии', topics: [ { - keyword: ['стресс', 'перегрузка', 'не справляюсь', 'давит'], + keyword: ['стресс', 'перегрузка', 'не справляюсь', 'давит', 'тяжело'], response: 'Стресс - главный триггер срывов. Алкоголь был стратегией совладания, теперь нужны новые, здоровые способы. Важно иметь "набор инструментов" для разных уровней стресса.', techniques: [ 'Техника стресс-термометра: оцените стресс 1-10, для каждого уровня - свой инструмент', @@ -248,7 +305,8 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Набор инструментов совладания со стрессом', 'Приложение: Breathe для дыхательных техник', - 'Книга: "Стрессоустойчивость" Шэрон Мельник' + 'Книга: "Стрессоустойчивость" Шэрон Мельник', + 'Статья: "DBT навыки для толерантности к дистрессу"' ] } ] @@ -257,7 +315,7 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ category: 'Сон и здоровье', topics: [ { - keyword: ['не могу спать', 'бессонница', 'плохой сон'], + keyword: ['не могу спать', 'бессонница', 'плохой сон', 'кошмары'], response: 'Нарушения сна - частое явление в раннем восстановлении. Алкоголь нарушал естественные циклы сна. Восстановление может занять 1-3 месяца. Важна гигиена сна.', techniques: [ 'Гигиена сна: одно и то же время сна/подъема, прохладная темная комната', @@ -268,7 +326,63 @@ export const psychologyKnowledgeBase: PsychologyKnowledge[] = [ resources: [ 'Приложение: Sleep Cycle для отслеживания сна', 'Техника: Сканирование тела для засыпания', - 'При стойкой бессоннице: консультация врача' + 'При стойкой бессоннице: консультация врача', + 'Статья: "Сон без алкоголя: гигиена и ритуалы"' + ] + }, + { + keyword: ['печень', 'здоровье', 'организм', 'восстановление тела'], + response: 'Ваше тело обладает удивительной способностью к исцелению. После отказа от алкоголя процессы регенерации запускаются мгновенно. Важно поддержать организм правильным питанием и режимом.', + techniques: [ + 'Детокс-диета: больше воды, крестоцветных овощей, куркумы', + 'Легкие упражнения: ходьба стимулирует лимфодренаж', + 'Витаминная поддержка: витамины группы B после консультации с врачом', + 'HALT проверка: своевременное питание предотвращает тягу' + ], + resources: [ + 'Статья: "Суперфуды для восстановления печени"', + 'Статья: "Как алкоголь влияет на мозг"', + 'Книга: "Тело помнит все" Бессел ван дер Колк' + ] + } + ] + }, + { + category: 'Травма и ПТСР', + topics: [ + { + keyword: ['травма', 'птср', 'прошлое', 'воспоминания', 'насилие', 'детство'], + response: 'Многие используют алкоголь как самолечение при травматическом опыте. Важно понимать, что трезвость - это первый шаг к исцелению травмы, но сама травма требует работы со специалистом.', + techniques: [ + 'Техники заземления: возврат в "здесь и сейчас" при флешбэках', + 'Создание "Безопасного места": мысленная визуализация пространства спокойствия', + 'Работа с телом: йога или танцевальная терапия (соматический подход)', + 'Дневник самонаблюдения: выявление связи между триггерами травмы и тягой' + ], + resources: [ + 'Статья: "Работа с травмой и ПТСР"', + 'Книга: "Тело помнит все" Бессел ван дер Колк', + 'Поиск травма-терапевта (EMDR, соматическая терапия)' + ] + } + ] + }, + { + category: 'Семья и отношения', + topics: [ + { + keyword: ['жена', 'муж', 'семья', 'дети', 'родители', 'созависимость'], + response: 'Зависимость - это семейная болезнь. Ваши близкие тоже пострадали и им нужно время на восстановление. Доверие возвращается долго, но последовательная трезвость - лучший способ его вернуть.', + techniques: [ + 'Установление здоровых границ: учитесь говорить "нет" без вины', + 'Семейная коммуникация: используйте "Я-сообщения"', + 'Терпение к близким: примите их гнев и подозрительность как часть процесса', + 'Совместный досуг: планируйте активности, не связанные с алкоголем' + ], + resources: [ + 'Статья: "Созависимость: как выйти из замкнутого круга"', + 'Статья: "Восстановление доверия в семье"', + 'Группы Al-Anon (для близких)' ] } ] @@ -284,6 +398,7 @@ export function findRelevantKnowledge(userMessage: string): { } | null { const lowerMessage = userMessage.toLowerCase(); + // Приоритетный поиск по точным совпадениям ключевых слов for (const category of psychologyKnowledgeBase) { for (const topic of category.topics) { const hasKeyword = topic.keyword.some(keyword =>