diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..8d75d76 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,15 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +polar: # Replace with a single Polar username +buy_me_a_coffee: mreccentric +thanks_dev: # +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..58c0cff --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,27 @@ +name: Bug report +description: Create a report to help us improve +labels: bug +body: + - type: textarea + attributes: + label: Describe the bug + description: Describe the bug. + placeholder: > + A clear and concise description of what the bug is. + validations: + required: true + - type: textarea + attributes: + label: To Reproduce + placeholder: > + Steps to reproduce the behavior: + - type: textarea + attributes: + label: Expected behavior + placeholder: > + A clear and concise description of what you expected to happen. + - type: textarea + attributes: + label: Additional context + placeholder: > + Add any other context about the problem here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..12a08a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,2 @@ +blank_issue_enable: true +blank_issue_title: "Please provide a title for your issue" \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..bfe9d8d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,26 @@ +name: Feature request +description: Suggest an idea for this project +labels: enhancement +body: + - type: textarea + attributes: + label: Is your feature request related to a problem or challenge? + description: Please describe what you are trying to do. + placeholder: > + A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + (This section helps developers understand the context and *why* for this feature, in addition to the *what*) + - type: textarea + attributes: + label: Describe the solution you'd like + placeholder: > + A clear and concise description of what you want to happen. + - type: textarea + attributes: + label: Describe alternatives you've considered + placeholder: > + A clear and concise description of any alternative solutions or features you've considered. + - type: textarea + attributes: + label: Additional context + placeholder: > + Add any other context or screenshots about the feature request here. \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..790fcf6 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,38 @@ +## Which issue does this PR close? + + + +- Closes #. + +## Rationale for this change + + + +## What changes are included in this PR? + + + +## Are these changes tested? + + + +## Are there any user-facing changes? + + + + \ No newline at end of file diff --git a/.github/workflows/auto-author-assign.yml b/.github/workflows/auto-author-assign.yml new file mode 100644 index 0000000..2ab0bb7 --- /dev/null +++ b/.github/workflows/auto-author-assign.yml @@ -0,0 +1,16 @@ +name: Auto Author Assign + +on: + pull_request_target: + types: [ opened, reopened ] + +permissions: + pull-requests: write + +jobs: + assign-author: + runs-on: ubuntu-latest + steps: + - uses: toshimaru/auto-author-assign@v2.1.1 + with: + repo-token: ${{ secrets.GH_PERSONAL_TOKEN }} diff --git a/.github/workflows/sync-issue-labels.yml b/.github/workflows/sync-issue-labels.yml new file mode 100644 index 0000000..5abc15d --- /dev/null +++ b/.github/workflows/sync-issue-labels.yml @@ -0,0 +1,58 @@ +name: Sync Labels from Issues to Merged PRs + +on: + workflow_dispatch: + schedule: + - cron: '0 2 * * *' + +jobs: + sync-labels: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install GitHub CLI & jq + run: | + sudo apt-get update + sudo apt-get install -y gh jq + + - name: Sync labels from linked issues to merged PRs + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: eccentriccoder01/talkheal + run: | + echo "๐Ÿ“ฅ Fetching merged PRs for $REPO..." + gh pr list --state merged --limit 100 --repo "$REPO" --json number,title,body > merged_prs.json + + jq -c '.[]' merged_prs.json | while read -r pr; do + pr_number=$(echo "$pr" | jq -r '.number') + pr_title=$(echo "$pr" | jq -r '.title') + pr_body=$(echo "$pr" | jq -r '.body') + + issue_number=$(echo "$pr_title $pr_body" | grep -oE '#[0-9]+' | head -n 1 | tr -d '#') + + if [ -z "$issue_number" ]; then + echo "โŒ PR #$pr_number has no linked issue." + continue + fi + + echo "๐Ÿ”— PR #$pr_number linked to issue #$issue_number" + + issue_labels=$(gh issue view "$issue_number" --repo "$REPO" --json labels | jq -r '.labels[].name') + + if [ -z "$issue_labels" ]; then + echo "โš ๏ธ Issue #$issue_number has no labels." + continue + fi + + while IFS= read -r label; do + echo "๐Ÿท๏ธ Applying label '$label' to PR #$pr_number..." + gh pr edit "$pr_number" --repo "$REPO" --add-label "$label" + done <<< "$issue_labels" + + sleep 0.5 + done + + echo "โœ… Done syncing labels." diff --git a/.streamlit/secrets.toml b/.streamlit/secrets.toml new file mode 100644 index 0000000..9aa7542 --- /dev/null +++ b/.streamlit/secrets.toml @@ -0,0 +1 @@ +GEMINI_API_KEY = "AIzaSyDsLJgA58LvgFtnUdVBLFb08GZQV0wXYjQ" \ No newline at end of file diff --git a/README.md b/README.md index a6989d3..ce5e063 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## ๐Ÿง  Your AI-Powered Mental Health Companion -**TalkHeal** is an empathetic, intelligent, and interactive mental health support assistant built using **Python** and **Streamlit**. Designed with compassion and care at its core, it offers 24/7 support, emotional journaling, resource guidance, and AI-powered conversations powered by Googleโ€™s Gemini Pro. +**TalkHeal** is an empathetic, intelligent, and interactive mental health support assistant built using **Python** and **Streamlit**. Designed with compassion and care at its core, it offers 24/7 support, emotional journaling, resource guidance, and AI-powered conversations powered by Googleโ€™s Gemini. --- @@ -56,29 +56,26 @@ ## ๐Ÿ“Š Project Stats -

- - GitHub Stars - - - GitHub Forks - - - Contributors - - - Open Issues - - - Open Pull Requests - - - Last Commit - - - License - +

+

+ +[![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) +![PRs Welcome](https://img.shields.io/badge/PRs-Welcome-brightgreen.svg?style=flat) +![Visitors](https://api.visitorbadge.io/api/Visitors?path=eccentriccoder01%2FTalkHeal%20&countColor=%23263759&style=flat) +![GitHub Forks](https://img.shields.io/github/forks/eccentriccoder01/TalkHeal) +![GitHub Repo Stars](https://img.shields.io/github/stars/eccentriccoder01/TalkHeal) +![GitHub Contributors](https://img.shields.io/github/contributors/eccentriccoder01/TalkHeal) +![GitHub Last Commit](https://img.shields.io/github/last-commit/eccentriccoder01/TalkHeal) +![GitHub Repo Size](https://img.shields.io/github/repo-size/eccentriccoder01/TalkHeal) +![GitHub Total Lines](https://sloc.xyz/github/eccentriccoder01/TalkHeal) +![Github](https://img.shields.io/github/license/eccentriccoder01/TalkHeal) +![GitHub Issues](https://img.shields.io/github/issues/eccentriccoder01/TalkHeal) +![GitHub Closed Issues](https://img.shields.io/github/issues-closed-raw/eccentriccoder01/TalkHeal) +![GitHub Pull Requests](https://img.shields.io/github/issues-pr/eccentriccoder01/TalkHeal) +![GitHub Closed Pull Requests](https://img.shields.io/github/issues-pr-closed/eccentriccoder01/TalkHeal) +

+
--- @@ -104,14 +101,11 @@ For a detailed walkthrough of TalkHeal's features and how to use them, check out ## ๐Ÿ› ๏ธ Technologies Used -| Tech | Purpose | -| --------------------- | --------------------------------- | -| **Python** | Core backend and AI logic | -| **Streamlit** | UI and frontend integration | -| **Google Gemini API** | Generative AI Conversations | -| **Session State** | Manage multi-threaded chat memory | -| **CSS Variables** | Theming and modern styling | -| **Streamlit Secrets** | Secure API key management | +![Python](https://img.shields.io/badge/Python-20232A?style=for-the-badge&logo=python&logoColor=61DAFB) +![CSS](https://img.shields.io/badge/CSS-38B2AC?style=for-the-badge&logo=css&logoColor=white) +![SQLite](https://img.shields.io/badge/SQLite-4EA94B?style=for-the-badge&logo=sqlite&logoColor=white) +![Gemini](https://img.shields.io/badge/Gemini-3448C5?style=for-the-badge&logo=google&logoColor=white) +![Streamlit](https://img.shields.io/badge/Streamlit-0099FF?style=for-the-badge&logo=streamlit&logoColor=white) --- diff --git a/TalkHeal.py b/TalkHeal.py index f99cfb6..cc28d6e 100644 --- a/TalkHeal.py +++ b/TalkHeal.py @@ -1,12 +1,48 @@ import streamlit as st +from auth.auth_utils import init_db +from components.login_page import show_login_page -# โœ… MUST be the first Streamlit command -st.set_page_config( - page_title="TalkHeal", - page_icon="๐Ÿ’ฌ", - layout="wide", - initial_sidebar_state=st.session_state.get("sidebar_state", "expanded") -) +st.set_page_config(page_title="TalkHeal", page_icon="๐Ÿ’ฌ", layout="wide") + +# --- DB Initialization --- +if "db_initialized" not in st.session_state: + init_db() + st.session_state["db_initialized"] = True + +# --- Auth State Initialization --- +if "authenticated" not in st.session_state: + st.session_state.authenticated = False +if "show_signup" not in st.session_state: + st.session_state.show_signup = False + +# --- LOGIN PAGE --- +if not st.session_state.authenticated: + show_login_page() + st.stop() + +# --- TOP RIGHT BUTTONS: THEME TOGGLE & LOGOUT --- +if st.session_state.get("authenticated", False): + col_spacer, col_theme, col_logout = st.columns([5, 0.5, 0.7]) + with col_spacer: + pass # empty spacer to push buttons right + with col_theme: + is_dark = st.session_state.get('dark_mode', False) + if st.button("๐ŸŒ™" if is_dark else "โ˜€๏ธ", key="top_theme_toggle", help="Toggle Light/Dark Mode", use_container_width=True): + st.session_state.dark_mode = not is_dark + st.session_state.theme_changed = True + st.rerun() + with col_logout: + if st.button("Logout", key="logout_btn", use_container_width=True): + for key in ["authenticated", "user_email", "user_name", "show_signup"]: + if key in st.session_state: + del st.session_state[key] + st.rerun() + +# --- MAIN UI (only after login) --- +header_col1, header_col2, header_col3 = st.columns([6, 1, 1]) +with header_col1: + st.title(f"Welcome to TalkHeal, {st.session_state.user_name}! ๐Ÿ’ฌ") + st.markdown("Navigate to other pages from the sidebar.") import google.generativeai as genai from core.utils import save_conversations, load_conversations @@ -17,7 +53,7 @@ from components.sidebar import render_sidebar from components.chat_interface import render_chat_interface, handle_chat_input from components.emergency_page import render_emergency_page - +from components.profile import apply_global_font_size # --- 1. INITIALIZE SESSION STATE --- if "chat_history" not in st.session_state: @@ -41,7 +77,7 @@ st.session_state.selected_tone = "Compassionate Listener" # --- 2. SET PAGE CONFIG --- - +apply_global_font_size() # --- 3. APPLY STYLES & CONFIGURATIONS --- apply_custom_css() @@ -93,7 +129,84 @@ def get_tone_prompt(): else: with main_area: render_header() - st.subheader(f"๐Ÿ—ฃ๏ธ Current Chatbot Tone: **{st.session_state['selected_tone']}**") + st.markdown(f""" +
+

๐Ÿ—ฃ๏ธ Current Chatbot Tone: {st.session_state['selected_tone']}

+
+""", unsafe_allow_html=True) + + # --- Mood Slider with Keyboard Navigation --- + def mood_slider(): + slider_html = """ +
+ + +
Neutral
+ + +
+ """ + mood_value = st.components.v1.html(slider_html, height=100) + return mood_value + + # --- Mood Slider --- + st.subheader("๐Ÿ˜Š Track Your Mood") + mood_options = ['Very Sad', 'Sad', 'Neutral', 'Happy', 'Very Happy'] + mood = st.slider( + 'Select your mood', + min_value=1, max_value=5, value=3, step=1 +) + coping_tips = { + 1: "Itโ€™s okay to feel this way. Try some deep breathing exercises to find calm.", + 2: "Consider writing down your thoughts in the journal to process your feelings.", + 3: "A short walk or some light stretching might help you feel balanced.", + 4: "Great to hear youโ€™re feeling happy! Share something positive in your journal.", + 5: "Youโ€™re shining today! Keep spreading that positivity with a kind act." +} + st.write(f"Selected mood: {mood_options[mood-1]}") + st.write(f"Coping tip: {coping_tips.get(mood, 'Letโ€™s explore how youโ€™re feeling.')}") + render_chat_interface() handle_chat_input(model, system_prompt=get_tone_prompt()) diff --git a/pink.png b/assets/pink.png similarity index 100% rename from pink.png rename to assets/pink.png diff --git a/assets/yoga_animation.json b/assets/yoga_animation.json new file mode 100644 index 0000000..31a96aa --- /dev/null +++ b/assets/yoga_animation.json @@ -0,0 +1 @@ +{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.20","a":"","k":"","d":"","tc":""},"fr":24,"ip":0,"op":168,"w":500,"h":500,"nm":"Relax","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Main_Null","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[250,229.99999999999997,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":84,"s":[250,190,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":168,"s":[250,229.99999999999997,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":169,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Hair_Front","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,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],[-0.687,-1.629],[1.152,0.839]],"o":[[0,0],[5.37,12.739],[-20.221,-14.712]],"v":[[-21.906,-85.944],[-23.528,-86.59],[0.666,-64.276]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.176470592618,0.301960796118,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":"Shape 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.25,-4],[0,0],[-2.25,3.25],[-2.75,6.5]],"o":[[0,0],[-0.25,4],[0,0],[2.25,-3.25],[2.75,-6.5]],"v":[[-26.5,-88.5],[-40.75,-52.75],[-37.5,-42.75],[-30.292,-54.26],[-22.288,-62.747]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.176470592618,0.301960796118,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":"Shape 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.25,-0.25],[-7.558,-9.448],[0.394,-21.172],[0,0],[1,1]],"o":[[-2.25,0.25],[30.882,38.618],[-0.312,17.851],[0,0],[-1,-1]],"v":[[-7,-100.75],[-24.75,-90],[22.25,-43.25],[26.75,-48.75],[19.25,-93]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.176470592618,0.301960796118,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":"Shape 1","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":-74,"op":170,"st":-74,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Top","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2,40,0],"ix":2},"a":{"a":0,"k":[133.596,126.196,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":[[-16.736,5.563],[-2.848,-4.49],[1.915,6.169],[2.102,16.813],[2.029,-11.435],[15.736,-10.247],[0,0],[2.53,-7.764],[-0.694,10.927],[-7.901,-6.186],[-10.216,-0.238]],"o":[[10.001,-3.324],[0.652,5.76],[-2.414,-7.778],[0,0],[-19.781,-13.547],[-2.458,-10.963],[-2.314,17.284],[-1.878,5.764],[2.556,-1.073],[11.553,9.046],[10.035,0.234]],"v":[[163.595,143.52],[173.444,119.186],[179.774,167.313],[172.487,128.016],[168.628,155.743],[100.11,154.943],[95.02,130.329],[88.202,165.23],[93.04,118.519],[101.247,141.132],[132.561,142.462]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9019607843137255,1,0.7803921568627451,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":"Shape 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.481,-12.015],[-1.24,-4.105],[1.915,6.169],[2.102,16.813],[2.692,-8.613],[2.616,8.637],[0,0],[2.53,-7.764],[-0.83,2.661],[-0.904,4.192],[-3.599,9.582],[-7.764,9.41],[6.69,25.848],[-2.146,-1.931],[-5.384,-6.998]],"o":[[4.522,11.403],[0.867,4.199],[0.806,2.669],[-2.414,-7.778],[0,0],[-2.691,8.614],[-2.616,-8.638],[-2.314,17.284],[-1.878,5.764],[1.276,-4.094],[2.586,-11.992],[5.858,-15.593],[-5.134,19.39],[1.337,1.675],[10.768,9.691],[5.384,6.999]],"v":[[189.923,109.627],[196.845,145.77],[199.944,158.186],[179.774,167.313],[172.487,128.016],[165.623,166.663],[102.809,165.801],[95.02,130.329],[88.202,165.23],[68.29,159.519],[71.497,147.132],[77.311,108.462],[113.23,80.306],[151.406,78.847],[156.586,84.235],[184.581,98.771]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8745098039215686,0.9686274509803922,0.7568627450980392,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":"Shape 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":169,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Pant","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2,40,0],"ix":2},"a":{"a":0,"k":[133.596,126.196,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":[[3.742,18.113],[0,0],[-1.615,-5.384],[-2.154,-2.155],[-23.687,-8.614],[27.261,-6.586]],"o":[[0,0],[0,0],[1.616,5.383],[0,0],[0,0],[9.886,-6.086]],"v":[[167.354,183.833],[168.43,187.064],[172.16,194.601],[177.006,208.637],[226.573,211.078],[166.585,213.407]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.403921574354,0.384313732386,0.670588254929,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":"Shape 5","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-8.176,-5.895],[0,0],[0,0],[-1.662,5.37],[0,0],[0,0]],"o":[[-32.426,-7.395],[23.763,-8.406],[2.172,-2.135],[1.662,-5.369],[0,0],[-5.059,23.63]],"v":[[101.272,214.341],[39.442,212.667],[90.282,210.663],[95.754,196.42],[99.05,188.912],[99.405,185.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.403921574354,0.384313732386,0.670588254929,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":"Shape 4","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.063,-5.663],[0,0],[0,0],[8.595,2.23],[0,0],[-15.074,-0.73],[0,0],[8.032,2.311],[11.778,2.748],[0,0],[-10.899,-3.607]],"o":[[6.312,5.462],[0,0],[0,0],[-8.594,-2.228],[-6.255,-7.775],[15.074,0.73],[-2.846,-5.596],[-29.505,-8.488],[-12.966,-3.026],[0.746,-0.733],[44.531,14.736]],"v":[[116.784,238.484],[123.746,255.436],[82.854,256.53],[36.556,255.875],[23.226,249.596],[40.522,251.591],[119.067,250.042],[111.726,235.309],[69.068,222.447],[47.157,227.163],[70.066,221.584]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.403921574354,0.384313732386,0.670588254929,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":"Shape 3","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.936,-0.155],[-11.91,-9.191],[-30.977,2.618],[-1.013,16.756],[5.384,-3.229],[8.614,-2.154],[0,0],[0,0],[2.171,-0.158],[9.436,0.885],[5.636,1.039],[5.921,0],[-2.55,-1.37],[-20.169,2.148],[-0.494,-0.369],[14.229,-2.47]],"o":[[6.686,4.345],[0,0],[0,0],[2.691,7.538],[0,0],[-8.613,2.154],[0,0],[0,0],[0,0],[-4.689,-4.24],[-2.117,-0.39],[3.959,-1.032],[10.977,5.897],[14.134,-1.505],[0.718,0.535],[-17.826,3.095]],"v":[[138.66,235.601],[173.006,248.137],[236.073,247.578],[248.609,226.19],[243.975,247.898],[231.342,254.321],[184.043,254.571],[176.756,254.571],[171.939,254.245],[162.66,246.561],[141.335,241.407],[127.608,230.946],[135.62,232.549],[185.675,221.688],[208.137,226.578],[183.89,223.197]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.403921574354,0.384313732386,0.670588254929,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":"Shape 2","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.383,5.613],[0,0],[-1.615,-5.384],[-2.154,-2.155],[-23.687,-8.614],[-2.692,-7.537],[5.384,-3.229],[8.614,-2.154],[0,0],[0,0],[2.171,-0.158],[9.436,0.885],[5.636,1.039],[5.921,0],[6.562,-5.788],[0,0],[0,0],[8.595,2.23],[0,0],[-2.758,7.514],[0,0],[0,0],[-1.662,5.37],[0,0],[0,0]],"o":[[0,0],[0,0],[1.616,5.383],[0,0],[0,0],[2.691,7.538],[0,0],[-8.613,2.154],[0,0],[0,0],[0,0],[-4.689,-4.24],[-2.117,-0.39],[-5.923,0],[6.312,5.462],[0,0],[0,0],[-8.594,-2.228],[-5.355,-3.278],[2.757,-7.513],[23.763,-8.406],[2.172,-2.135],[1.662,-5.369],[0,0],[22.191,3.63]],"v":[[167.354,183.833],[168.43,187.064],[172.16,194.601],[177.006,208.637],[226.573,211.078],[248.609,226.19],[243.975,247.898],[231.342,254.321],[184.043,254.571],[176.756,254.571],[171.939,254.245],[162.66,246.561],[141.335,241.407],[127.608,230.946],[116.034,239.859],[123.746,255.436],[82.854,256.53],[36.556,255.875],[23.226,249.596],[17.772,228.591],[39.442,212.667],[90.282,210.663],[95.754,196.42],[99.05,188.912],[99.405,185.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.498039215803,0.470588237047,0.823529422283,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":"Shape 1","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":169,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Body","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2,40,0],"ix":2},"a":{"a":0,"k":[133.596,126.196,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],[-3.25,4.25]],"o":[[0,0],[3.25,-4.25]],"v":[[125.971,51.946],[134.846,50.071]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.666666686535,0.43935328722,0.358169943094,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"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 8","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.188,0.5],[0,0],[-1.5,0]],"o":[[-2.375,2],[0,0],[1.5,0]],"v":[[134.221,43.196],[126.346,44.633],[129.971,46.133]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078431375325,0.160784319043,0.215686276555,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.78823530674,0.524025976658,0.429665505886,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":"Shape 7","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[8,-0.25]],"o":[[0,0],[-8,0.25]],"v":[[148.096,27.571],[137.221,23.071]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078431375325,0.160784319043,0.215686276555,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"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 6","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.875,-0.375]],"o":[[0,0],[7.875,0.375]],"v":[[112.346,28.196],[123.471,23.571]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078431375325,0.160784319043,0.215686276555,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"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 5","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.125,0.125],[3.5,0.035],[0.031,-0.031],[-4.188,-0.063]],"o":[[0.125,-0.125],[-3.094,-0.031],[0.438,0.781],[3.812,0.057]],"v":[[148.096,31.008],[142.69,33.227],[137.221,31.258],[142.971,33.946]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078431375325,0.160784319043,0.215686276555,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":"Shape 4","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.125,0.125],[3.5,0.035],[0.031,-0.031],[-4.188,-0.063]],"o":[[0.125,-0.125],[-3.094,-0.031],[0.438,0.781],[3.812,0.057]],"v":[[123.596,31.008],[118.19,33.227],[112.721,31.258],[118.471,33.946]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078431375325,0.160784319043,0.215686276555,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":"Shape 3","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.938,8],[0,0],[0.438,-5.25],[0,0]],"o":[[-15.688,19.625],[0,0],[9.5,-7.375],[0,0]],"v":[[147.409,56.571],[114.409,56.571],[116.159,73.196],[147.096,71.071]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827450990677,0.545314967632,0.444552093744,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":"Shape 2","np":3,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.481,-12.015],[-1.24,-4.105],[-1.379,-2.422],[-1.58,-1.829],[-6.216,-7.195],[-2.386,-2.355],[-2.153,-1.077],[-2.693,0.538],[-3.768,-1.076],[-1.076,-0.538],[3.769,-1.077],[0,0],[-3.229,0.538],[0,5.384],[-1.986,0.993],[0,0],[-2.153,-0.539],[0,0],[0.538,-1.616],[0,0],[1.616,0],[0,0],[2.153,1.615],[3.768,3.769],[7.537,7.538],[2.154,5.384],[3.769,30.149],[2.692,-8.613],[-1.077,-3.768],[0,0],[-1.615,-5.384],[-2.154,-2.155],[-23.687,-8.614],[-2.692,-7.537],[5.384,-3.229],[8.614,-2.154],[0,0],[0,0],[2.171,-0.158],[0,0],[0.573,0],[5.921,0],[8.076,-1.615],[0,0],[0,0],[8.595,2.23],[0,0],[-2.758,7.514],[0,0],[0,0],[-1.662,5.37],[0,0],[0,0],[2.616,8.637],[0,0],[2.201,-5.364],[7.603,-7.472],[0,0],[2.168,-1.596],[0,0],[1.615,0.014],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.072,-0.546],[0,0],[0,0],[0,0],[3.759,1.11],[-1.081,0.53],[-3.778,1.043],[-2.687,-0.561],[0,0],[-2.244,2.175],[-2.214,2.517],[-6.279,7.14],[-1.214,2.089],[-0.83,2.661],[-0.904,4.192],[-3.599,9.582],[-0.921,16],[6.461,5.384],[-1.077,7.537],[-0.538,6.998],[-10.767,4.307],[-13.948,-10.438],[0.268,-0.433],[0,0],[3.348,-4.872],[0,0],[0.538,-7.537],[-10.767,-9.691],[-5.384,-6.998]],"o":[[4.522,11.403],[0.867,4.199],[0.806,2.669],[1.197,2.099],[6.215,7.196],[2.191,2.536],[2.224,2.195],[0,0],[2.691,-0.538],[3.769,1.078],[1.077,0.539],[-3.768,1.076],[0,0],[0,0],[0,0],[1.076,-0.538],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.615,0],[0,0],[-2.155,-1.616],[0,0],[-7.538,-7.537],[-2.153,-5.383],[0,0],[-2.691,8.614],[0,0],[0,0],[1.616,5.383],[0,0],[0,0],[2.691,7.538],[0,0],[-8.613,2.154],[0,0],[0,0],[0,0],[-0.813,0.056],[-2.153,0],[-5.923,0],[0,0],[0,0],[0,0],[-8.594,-2.228],[-5.355,-3.278],[2.757,-7.513],[23.763,-8.406],[2.172,-2.135],[1.662,-5.369],[0,0],[1.109,-3.759],[-2.616,-8.638],[-4.032,30.114],[-2.2,5.364],[-7.603,7.471],[-3.801,3.735],[-2.167,1.596],[0,0],[-1.615,-0.014],[0,0],[-0.524,-1.62],[0,0],[2.158,-0.519],[0,0],[1.976,1.011],[-0.047,5.383],[3.225,0.567],[0,0],[-3.76,-1.109],[1.082,-0.529],[3.778,-1.044],[2.687,0.563],[2.163,-1.058],[2.406,-2.334],[6.278,-7.14],[1.596,-1.815],[1.401,-2.41],[1.276,-4.094],[2.586,-11.992],[7.155,-19.047],[0,0],[-6.46,-5.383],[1.077,-7.537],[0.539,-6.999],[0,0],[10.397,7.781],[1.768,1.942],[0,0],[-1.152,2.128],[0,0],[-0.538,7.538],[10.768,9.691],[5.384,6.999]],"v":[[189.173,109.627],[195.595,145.77],[198.944,158.186],[201.947,165.971],[206.315,171.743],[224.963,193.328],[231.735,200.758],[238.418,205.906],[241.649,205.906],[252.954,206.982],[263.721,208.598],[260.491,212.905],[254.03,213.443],[259.952,219.365],[260.491,213.981],[262.645,210.213],[263.721,212.905],[266.413,211.29],[265.336,218.827],[266.413,220.981],[256.723,224.749],[254.03,225.287],[245.417,223.134],[241.649,221.519],[229.266,213.443],[200.733,193.523],[184.581,175.219],[172.737,126.766],[164.123,163.913],[167.354,183.833],[168.43,187.064],[171.66,194.601],[176.506,209.137],[226.573,211.828],[248.109,227.44],[242.725,247.898],[230.342,253.821],[184.043,253.821],[176.506,253.821],[171.939,254.245],[171.66,255.436],[163.585,253.282],[146.358,253.821],[124.284,254.359],[123.746,255.436],[82.854,255.53],[36.556,255.125],[24.226,249.096],[19.022,228.591],[40.692,213.167],[90.782,210.913],[95.754,196.42],[99.05,188.912],[100.155,185.691],[103.559,165.801],[95.27,128.579],[83.003,176.927],[66.693,195.09],[37.986,214.759],[25.533,222.726],[21.751,224.308],[13.119,226.386],[10.432,225.824],[0.774,221.971],[1.87,219.827],[0.859,212.28],[3.537,213.919],[4.637,211.236],[6.757,215.024],[7.249,220.412],[13.222,214.542],[6.767,213.947],[3.574,209.612],[14.355,208.092],[25.67,207.113],[28.9,207.142],[35.629,202.053],[42.465,194.682],[61.301,173.261],[65.718,167.527],[68.79,159.769],[72.247,147.382],[79.061,108.462],[116.209,72.929],[110.286,50.856],[102.211,35.782],[104.364,26.63],[114.593,0.25],[147.497,1],[156.781,27.745],[159.364,30.788],[158.201,44.934],[151.24,50.683],[146.896,61.085],[156.586,84.235],[184.581,98.771]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784316063,0.629434883595,0.51372551918,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":"Shape 1","np":3,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":169,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Hair_Back","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,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":[[8,1.25],[0.25,-27.5],[1.25,-16.75],[-35.378,24.973],[7.5,12.25]],"o":[[-8,-1.25],[-0.25,27.5],[-1.157,15.507],[34,-24],[-10.256,-16.752]],"v":[[13.5,-69],[-30.5,-45.5],[-38.25,-1],[47.5,45.5],[29.5,-20.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.015732409433,0.071019984782,0.121568627656,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":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[12.5,23],[32.452,4.275],[2.156,-12.245],[-1.177,-7.706],[0,-34],[-48.303,31.422],[18.981,16.04]],"o":[[-3.784,-6.962],[-15.097,-1.989],[-10.844,3.505],[5.5,36],[0,15.55],[46.5,-30.25],[-17.75,-15]],"v":[[31.5,-77.25],[-5.452,-105.775],[-38.406,-84.005],[-49,-63.5],[-53.5,1],[47.5,45.5],[46.5,-43.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.745097994804,0.141176000237,0.129411995411,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.176470592618,0.301960796118,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":"Shape 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-66,"op":170,"st":-66,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Halo 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[75,75,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"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":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":-78,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":6,"s":[60]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":90,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":174,"s":[60]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":258,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":342,"s":[60]},{"t":426,"s":[0]}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":26,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-113,"op":170,"st":-65,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Halo","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[229.99999999999997,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[75,75,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"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":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":-2,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":82,"s":[60]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":166,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":250,"s":[60]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":334,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":418,"s":[60]},{"t":502,"s":[0]}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":26,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-37,"op":191,"st":11,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":20,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,450,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":0,"s":[243,8]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":84,"s":[186,6]},{"t":168,"s":[243,8]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.282352954149,0.282352954149,0.282352954149,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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":169,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Circles - 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":71,"ix":10},"p":{"a":0,"k":[376.898,209.72,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[-80,80,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-167,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-145.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-122.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-87.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-67.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":-39.445,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":-21.189,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":1,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":22.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":45.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":80.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":100.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":128.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":146.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":169,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-167,"op":191,"st":-167,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Circles - 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":71,"ix":10},"p":{"a":0,"k":[376.898,209.72,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[-80,80,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-122,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-100.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-77.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-42.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-22.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":5.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":23.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":46,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":67.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":90.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":125.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":145.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":173.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":191.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":214,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-122,"op":183,"st":-122,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Circles - 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":71,"ix":10},"p":{"a":0,"k":[376.898,209.72,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[-80,80,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-68,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-46.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-23.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":11.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":31.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":59.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":77.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":100,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":121.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":144.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":179.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":199.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":227.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":245.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":268,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-68,"op":179,"st":-68,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Circles - 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":129,"ix":10},"p":{"a":0,"k":[173.913,303.783,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[39,39,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-167,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-145.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-122.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-87.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-67.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":-39.445,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":-21.189,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":1,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":22.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":45.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":80.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":100.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":128.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":146.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":169,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-167,"op":191,"st":-167,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Circles - 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":129,"ix":10},"p":{"a":0,"k":[173.913,303.783,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[39,39,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-122,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-100.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-77.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-42.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-22.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":5.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":23.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":46,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":67.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":90.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":125.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":145.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":173.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":191.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":214,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-122,"op":183,"st":-122,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Circles - 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":129,"ix":10},"p":{"a":0,"k":[173.913,303.783,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[39,39,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-68,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-46.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-23.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":11.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":31.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":59.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":77.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":100,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":121.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":144.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":179.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":199.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":227.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":245.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":268,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-68,"op":179,"st":-68,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Circles - 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":66,"ix":10},"p":{"a":0,"k":[370.6,138.448,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[-28.000000000000004,28.000000000000004,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-167,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-145.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-122.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-87.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-67.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":-39.445,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":-21.189,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":1,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":22.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":45.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":80.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":100.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":128.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":146.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":169,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-167,"op":191,"st":-167,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Circles - 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":66,"ix":10},"p":{"a":0,"k":[370.6,138.448,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[-28.000000000000004,28.000000000000004,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-122,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-100.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-77.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-42.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-22.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":5.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":23.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":46,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":67.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":90.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":125.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":145.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":173.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":191.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":214,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-122,"op":183,"st":-122,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Circles - 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":66,"ix":10},"p":{"a":0,"k":[370.6,138.448,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[-28.000000000000004,28.000000000000004,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-68,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-46.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-23.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":11.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":31.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":59.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":77.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":100,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":121.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":144.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":179.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":199.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":227.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":245.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":268,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-68,"op":179,"st":-68,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Circles - 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[164.187,108.128,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-167,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-145.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-122.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-87.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-67.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":-39.445,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":-21.189,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":1,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":22.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":45.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":80.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":100.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":128.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":146.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":169,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-167,"op":191,"st":-167,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Circles - 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[164.187,108.128,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-122,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-100.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-77.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":-42.196,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":-22.154,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":5.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":23.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":46,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":67.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":90.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":125.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":145.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":173.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":191.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":214,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-122,"op":183,"st":-122,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Circles - 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[164.187,108.128,0],"ix":2},"a":{"a":0,"k":[194.187,88.128,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":-68,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":-46.421,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":-23.066,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":11.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":31.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":59.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":77.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"i":{"x":0.575,"y":0.575},"o":{"x":0.167,"y":0.167},"t":100,"s":[232,72],"to":[-49.639,1.418],"ti":[15,-43]},{"i":{"x":0.637,"y":0.638},"o":{"x":0.299,"y":0.299},"t":121.579,"s":[159,168],"to":[-15,43],"ti":[-10,-61]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.315,"y":0.315},"t":144.934,"s":[73,268],"to":[10,61],"ti":[-36,37]},{"i":{"x":0.669,"y":0.669},"o":{"x":0.333,"y":0.333},"t":179.804,"s":[253,316],"to":[36,-37],"ti":[-54.512,7.9]},{"i":{"x":0.685,"y":0.685},"o":{"x":0.345,"y":0.345},"t":199.846,"s":[364,332],"to":[69,-10],"ti":[38,35]},{"i":{"x":0.693,"y":0.693},"o":{"x":0.354,"y":0.354},"t":227.555,"s":[420,208],"to":[-38,-35],"ti":[46,48]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.445,"y":0.445},"t":245.811,"s":[327,152],"to":[-38.548,-40.225],"ti":[70,-2]},{"t":268,"s":[232,72]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5607843137254902,0.7176470588235294,0.3686274509803922,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":[233,73],"ix":2},"a":{"a":0,"k":[233,73],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-68,"op":179,"st":-68,"bm":0}],"markers":[{"tm":168,"cm":"1","dr":0}]} \ No newline at end of file diff --git a/auth/auth_utils.py b/auth/auth_utils.py new file mode 100644 index 0000000..8c11f89 --- /dev/null +++ b/auth/auth_utils.py @@ -0,0 +1,46 @@ +import sqlite3 +import bcrypt + +def init_db(): + conn = sqlite3.connect("users.db") + cursor = conn.cursor() + cursor.execute(""" + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + password TEXT NOT NULL + ) + """) + conn.commit() + conn.close() + +def hash_password(password): + return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() + +def check_password(password, hashed): + return bcrypt.checkpw(password.encode(), hashed.encode()) + +def register_user(name, email, password): + conn = sqlite3.connect("users.db") + cursor = conn.cursor() + hashed_pw = hash_password(password) + try: + cursor.execute("INSERT INTO users (name, email, password) VALUES (?, ?, ?)", (name, email, hashed_pw)) + conn.commit() + return True, "User registered successfully" + except sqlite3.IntegrityError: + return False, "Email already registered" + finally: + conn.close() + +def authenticate_user(email, password): + conn = sqlite3.connect("users.db") + cursor = conn.cursor() + cursor.execute("SELECT name, password FROM users WHERE email = ?", (email,)) + result = cursor.fetchone() + conn.close() + if result and check_password(password, result[1]): + user = {"name": result[0], "email": email} + return True, user + return False, None \ No newline at end of file diff --git a/auth/users.yaml b/auth/users.yaml new file mode 100644 index 0000000..e69de29 diff --git a/components/Breathing_Exercise.py b/components/Breathing_Exercise.py new file mode 100644 index 0000000..d9f9db6 --- /dev/null +++ b/components/Breathing_Exercise.py @@ -0,0 +1,60 @@ +import streamlit as st +import time + +def breathing_exercise(): + st.markdown("

๐Ÿง˜ Breathing Exercise

", unsafe_allow_html=True) + + st.markdown("### ๐Ÿ‘‡ Follow the animation to breathe in and out") + st.write("Use this simple breathing exercise to relax. Follow the circle expanding and contracting.") + + circle_animation = """ + + +
+ """ + st.markdown(circle_animation, unsafe_allow_html=True) + + breath_text = st.empty() + + if st.button("๐ŸŒ€ Start Breathing"): + for _ in range(3): + breath_text.markdown("## ๐ŸŒฌ๏ธ Breathe In...") + time.sleep(4) + breath_text.markdown("## โœ‹ Hold...") + time.sleep(2) + breath_text.markdown("## ๐Ÿ˜ฎโ€๐Ÿ’จ Breathe Out...") + time.sleep(4) + breath_text.markdown("### โœ… Done! Feel better?") + + with st.expander("๐Ÿ•’ Need a Timer?"): + minutes = st.slider("How many minutes do you want to do this?", 1, 10, 2) + if st.button("Start Timer"): + st.success("Relax and follow the animation...") + timer_placeholder = st.empty() + for i in range(minutes * 60, 0, -1): + mins, secs = divmod(i, 60) + timer_text = f"{mins:02d}:{secs:02d}" + timer_placeholder.markdown(f"## โณ {timer_text}") + time.sleep(1) + timer_placeholder.markdown("### โœ… Timer complete!") + +if __name__ == "__main__": + breathing_exercise() diff --git a/components/header.py b/components/header.py index 43bd86f..6a1224c 100644 --- a/components/header.py +++ b/components/header.py @@ -2,38 +2,12 @@ def render_header(): with st.container(): - # Top bar with hamburger menu and theme toggle - col1, col2, col3 = st.columns([0.1, 0.8, 0.1]) - - with col1: - if st.button("โ˜ฐ", key="top_hamburger_menu", help="Toggle Sidebar", use_container_width=True): - if st.session_state.sidebar_state == "expanded": - st.session_state.sidebar_state = "collapsed" - else: - st.session_state.sidebar_state = "expanded" - st.rerun() - - with col3: - is_dark = st.session_state.get('dark_mode', False) - if st.button("๐ŸŒ™" if is_dark else "โ˜€๏ธ", key="top_theme_toggle", help="Toggle Light/Dark Mode", use_container_width=True): - st.session_state.dark_mode = not is_dark - st.session_state.theme_changed = True - st.rerun() - - st.markdown(""" -
-

TalkHeal

-

Your Mental Health Companion ๐Ÿ’™

-
- """, unsafe_allow_html=True) - ## Commented out this part of the header because the 'emergency button' functionality is quite similar, hence causing redundancy. ## - - # with st.expander("๐Ÿ“ Find Help Nearby"): - # location_input = st.text_input("Enter your city", key="header_location_search") - # if st.button("๐Ÿ” Search Centers", key="header_search_nearby"): - # if location_input: - # search_url = f"https://www.google.com/maps/search/mental+health+centers+{location_input.replace(' ', '+')}" - # st.markdown(f'๐Ÿ—บ๏ธ View Mental Health Centers Near {location_input}', unsafe_allow_html=True) - # st.success("Opening search results in a new tab...") - # else: - # st.warning("Please enter a city name") + # Only one column for header + column = st.columns(1)[0] + with column: + st.markdown(""" +
+

TalkHeal

+

Your Mental Health Companion ๐Ÿ’™

+
+ """, unsafe_allow_html=True) diff --git a/components/login_page.py b/components/login_page.py new file mode 100644 index 0000000..a84e209 --- /dev/null +++ b/components/login_page.py @@ -0,0 +1,72 @@ +import streamlit as st +from auth.auth_utils import register_user, authenticate_user + +def show_login_page(): + st.markdown( + """ + + """, unsafe_allow_html=True + ) + + # Use session state to switch between login and signup + if "show_signup" not in st.session_state: + st.session_state.show_signup = False + + if st.session_state.show_signup: + st.subheader("๐Ÿ“ Sign Up") + name = st.text_input("Name", key="signup_name") + email = st.text_input("Email", key="signup_email") + password = st.text_input("Password", type="password", key="signup_password") + if st.button("Sign Up"): + success, message = register_user(name, email, password) + if success: + st.success("Account created! Welcome.") + st.session_state.authenticated = True + st.session_state.user_email = email + st.session_state.user_name = name + st.session_state.show_signup = False + st.rerun() + else: + st.error(message) + # Only this button for switching to login + if st.button("Already have an account? Login"): + st.session_state.show_signup = False + st.rerun() + else: + st.subheader("๐Ÿ” Login") + email = st.text_input("Email", key="login_email") + password = st.text_input("Password", type="password", key="login_password") + if st.button("Login"): + success, user = authenticate_user(email, password) + if success: + st.session_state.authenticated = True + st.session_state.user_email = user["email"] + st.session_state.user_name = user["name"] + st.rerun() + else: + st.warning("Invalid email or password.") + # Only this button for switching to signup + if st.button("Don't have an account? Sign up"): + st.session_state.show_signup = True + st.rerun() \ No newline at end of file diff --git a/components/profile.py b/components/profile.py new file mode 100644 index 0000000..90d8943 --- /dev/null +++ b/components/profile.py @@ -0,0 +1,353 @@ +""" +TalkHeal Profile Management Module + +This module handles user profile functionality including: +- Profile creation and editing +- Profile picture upload and management +- User preferences (name, font size) +- Profile display in sidebar + +Author: TalkHeal Team +Version: 1.0 +""" + +import streamlit as st +import base64 +from datetime import datetime +from io import BytesIO +from PIL import Image + + +def initialize_profile_state(): + """Initialize profile data in session state if not exists""" + if "user_profile" not in st.session_state: + st.session_state.user_profile = { + "name": "", + "profile_picture": None, + "join_date": datetime.now().strftime("%B %Y"), + "font_size": "Medium" + } + + +def get_greeting(): + """Get appropriate greeting based on current time""" + current_hour = datetime.now().hour + if current_hour < 12: + return "Good morning" + elif current_hour < 17: + return "Good afternoon" + else: + return "Good evening" + + +def get_user_initials(name): + """Generate user initials from name""" + if name: + return ''.join([word[0].upper() for word in name.split()[:2]]) + return "TH" + + +def create_default_avatar(initials, size=80): + """Create a default avatar with user initials""" + return st.markdown(f""" +
+ {initials} +
+ """, unsafe_allow_html=True) + + +def handle_profile_picture_upload(uploaded_file): + """Handle profile picture upload and processing""" + if uploaded_file is not None: + try: + # Process and resize image to medium size + image = Image.open(uploaded_file) + # Resize to medium size (200x200) while maintaining aspect ratio + image.thumbnail((200, 200), Image.Resampling.LANCZOS) + + # Convert to base64 for storage + buffered = BytesIO() + image.save(buffered, format="PNG") + img_str = base64.b64encode(buffered.getvalue()).decode() + + # Save to session state + st.session_state.user_profile["profile_picture"] = f"data:image/png;base64,{img_str}" + + st.success("โœ… Profile picture uploaded successfully!") + return True + + except Exception as e: + st.error("โŒ Error uploading image. Please try a different file.") + return False + + return False + + +def render_profile_header(): + """Render the profile header with picture and greeting""" + profile_data = st.session_state.user_profile + greeting = get_greeting() + + # Profile header section + st.markdown("### ๐Ÿ‘ค Profile") + + # Profile picture and greeting + col1, col2 = st.columns([1, 2]) + + with col1: + if profile_data["profile_picture"]: + # Display uploaded profile picture with circular shape and medium size + st.markdown(f""" +
+ Profile Picture +
+ """, unsafe_allow_html=True) + else: + # Default avatar with initials + initials = get_user_initials(profile_data["name"]) + create_default_avatar(initials, 80) + + with col2: + if profile_data["name"]: + display_name = profile_data["name"].split()[0] + st.markdown(f"**{greeting}, {display_name}!** ๐Ÿ‘‹") + else: + st.markdown(f"**Welcome to TalkHeal!** ๐ŸŒŸ") + st.caption(f"Member since {profile_data['join_date']}") + + +def render_profile_settings(): + """Render the profile settings form""" + profile_data = st.session_state.user_profile + + # Add CSS to fix the text input color issue + st.markdown(""" + + """, unsafe_allow_html=True) + + with st.expander("โš™๏ธ Profile Settings"): + + # Name input + st.markdown("**Your Name**") + new_name = st.text_input( + "Enter your name", + value=profile_data["name"], + key="profile_name_input", + placeholder="Enter your name", + help="Enter your preferred name for personalized interactions" + ) + + # Profile picture upload + st.markdown("**Profile Picture**") + uploaded_file = st.file_uploader( + "Upload a profile picture (Optional)", + type=['png', 'jpg', 'jpeg'], + key="profile_pic_upload", + help="Drag and drop or click to upload. Supported formats: PNG, JPG, JPEG" + ) + + # Handle file upload + handle_profile_picture_upload(uploaded_file) + + # Font size preference + st.markdown("**Font Size**") + font_size = st.selectbox( + "Choose your preferred text size", + ["Small", "Medium", "Large"], + index=["Small", "Medium", "Large"].index(profile_data["font_size"]), + key="font_size_selector", + help="This will change the font size throughout the entire application" + ) + + # Action buttons row + col_save, col_reset = st.columns(2) + + with col_save: + # Save profile button + if st.button("๐Ÿ’พ Save Profile", key="save_profile", use_container_width=True, type="primary"): + # Update profile data + profile_data["name"] = new_name.strip() + profile_data["font_size"] = font_size + + # Save to session state + st.session_state.user_profile = profile_data + + # Apply font size globally (you can implement this in your main app) + st.session_state.global_font_size = font_size + + # Success message + st.success("๐ŸŽ‰ Profile saved successfully!") + st.balloons() + + # Rerun to update the display + st.rerun() + + with col_reset: + # Reset profile button + if st.button("๐Ÿ”„ Reset All", key="reset_profile", use_container_width=True, type="secondary"): + # Show confirmation dialog + st.session_state.show_reset_confirmation = True + st.rerun() + + # Reset confirmation dialog + if st.session_state.get("show_reset_confirmation", False): + st.warning("โš ๏ธ Are you sure you want to reset all profile settings?") + col_confirm, col_cancel = st.columns(2) + + with col_confirm: + if st.button("โœ… Yes, Reset", key="confirm_reset", use_container_width=True, type="primary"): + # Reset to default values + st.session_state.user_profile = { + "name": "", + "profile_picture": None, + "join_date": datetime.now().strftime("%B %Y"), + "font_size": "Medium" + } + # Reset global font size + st.session_state.global_font_size = "Medium" + st.session_state.show_reset_confirmation = False + st.success("๐Ÿ”„ Profile reset successfully!") + st.rerun() + + with col_cancel: + if st.button("โŒ Cancel", key="cancel_reset", use_container_width=True): + st.session_state.show_reset_confirmation = False + st.rerun() + + +def render_profile_stats(): + """Render simplified profile statistics""" + profile_data = st.session_state.user_profile + + if profile_data["name"]: + with st.expander("๐Ÿ“Š Your TalkHeal Journey"): + col1, col2 = st.columns(2) + + with col1: + st.metric("Conversations", "0", help="Total chat sessions") + + with col2: + st.metric("Days Active", "1", help="Days you've used TalkHeal") + + +def render_profile_section(): + """ + Main function to render the complete profile section + This is the function that should be imported and called in sidebar + """ + # Initialize profile state + initialize_profile_state() + + # Render profile components + render_profile_header() + render_profile_settings() + render_profile_stats() + + # Add separator + st.markdown("---") + + +# Optional: Helper functions for other parts of the app +def get_user_name(): + """Get the current user's name""" + if "user_profile" in st.session_state: + return st.session_state.user_profile.get("name", "") + return "" + + +def get_user_font_size(): + """Get the current user's preferred font size""" + if "global_font_size" in st.session_state: + return st.session_state.global_font_size + elif "user_profile" in st.session_state: + return st.session_state.user_profile.get("font_size", "Medium") + return "Medium" + + +def apply_global_font_size(): + """ + Apply the user's font size preference globally across the application. + Call this function in your main app to apply font size changes. + """ + font_size = get_user_font_size() + + # Font size mappings + font_sizes = { + "Small": "14px", + "Medium": "16px", + "Large": "18px" + } + + selected_size = font_sizes.get(font_size, "16px") + + # Apply CSS to change font size globally + st.markdown(f""" + + """, unsafe_allow_html=True) + + +def get_user_profile_picture(): + """Get the current user's profile picture""" + if "user_profile" in st.session_state: + return st.session_state.user_profile.get("profile_picture", None) + return None \ No newline at end of file diff --git a/components/sidebar.py b/components/sidebar.py index 208d066..462617e 100644 --- a/components/sidebar.py +++ b/components/sidebar.py @@ -3,6 +3,9 @@ from datetime import datetime from core.utils import create_new_conversation, get_current_time from core.theme import get_current_theme, toggle_theme, set_palette, PALETTES +from components.profile import initialize_profile_state, render_profile_section +from streamlit_js_eval import streamlit_js_eval +import requests # --- Structured Emergency Resources --- GLOBAL_RESOURCES = [ @@ -18,6 +21,69 @@ "url": "https://www.childhelplineinternational.org/"} ] + +def get_country_from_coords(lat, lon): + try: + url = f"https://geocode.maps.co/reverse?lat={lat}&lon={lon}" + resp = requests.get(url, timeout=5) + if resp.status_code == 200: + data = resp.json() + return data.get("address", {}).get("country_code", "").upper() + except: + pass + return None + +def get_user_country(): + # 1. Try to get user's actual browser location (via JS) + coords = streamlit_js_eval( + js_expressions=""" + new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition( + position => resolve({ + latitude: position.coords.latitude, + longitude: position.coords.longitude + }), + error => resolve(null) + ); + }); + """, + key="get_coords" + ) + + if coords and "latitude" in coords and "longitude" in coords: + country = get_country_from_coords(coords["latitude"], coords["longitude"]) + if country: + return country + + # 2. Fallback to IP-based location using ipapi.co (no key required) + try: + resp = requests.get("https://ipapi.co/json/", timeout=3) + if resp.status_code == 200: + return resp.json().get("country_code", "").upper() + except: + pass + + return None # final fallback if everything fails + +country_helplines = { + "US": [ + "National Suicide Prevention Lifeline: 988", + "Crisis Text Line: Text HOME to 741741", + "SAMHSA National Helpline: 1-800-662-4357" + ], + "IN": [ + "AASRA: 9152987821", + "Sneha Foundation: 044-24640050" + ], + "GB": [ + "Samaritans: 116 123" + ], + "AU": [ + "Lifeline: 13 11 14" + ] +} +IASP_LINK = "https://findahelpline.com/" + mental_health_resources_full = { "Depression & Mood Disorders": { "description": "Information on understanding and coping with depression, persistent depressive disorder, and other mood-related challenges.", @@ -74,9 +140,17 @@ def render_sidebar(): """Renders the left and right sidebars.""" - + with st.sidebar: + render_profile_section() + + st.markdown("### ๐Ÿ“‚ Explore") + st.page_link("pages/Journaling.py", label="๐Ÿ“ Journaling", use_container_width=True) + st.page_link("pages/Yoga.py", label="๐Ÿง˜ Yoga", use_container_width=True) + st.markdown("---") + st.markdown("### ๐Ÿ’ฌ Conversations") + if "show_quick_start_prompts" not in st.session_state: st.session_state.show_quick_start_prompts = False if "pre_filled_chat_input" not in st.session_state: @@ -88,6 +162,7 @@ def render_sidebar(): create_new_conversation() st.session_state.show_quick_start_prompts = True st.rerun() + if st.session_state.show_quick_start_prompts: st.markdown("---") st.markdown("**Start with a common topic:**") @@ -108,6 +183,7 @@ def render_sidebar(): st.markdown("---") + if st.session_state.conversations: if "delete_candidate" not in st.session_state: for i, convo in enumerate(st.session_state.conversations): @@ -125,9 +201,19 @@ def render_sidebar(): st.session_state.active_conversation = i st.rerun() with col2: - if st.button("๐Ÿ—‘๏ธ", key=f"delete_{i}", type="primary"): - st.session_state.delete_candidate = i - st.rerun() + if convo["messages"]: + if st.button("๐Ÿ—‘๏ธ", key=f"delete_{i}", type="primary", use_container_width=True): + st.session_state.delete_candidate = i + st.rerun() + else: + st.button( + "๐Ÿ—‘๏ธ", + key=f"delete_{i}", + type="primary", + use_container_width=True, + disabled=not convo["messages"] # Disable if it's a new/empty conversation + ) + else: st.warning( @@ -298,6 +384,21 @@ def render_sidebar(): for resource in GLOBAL_RESOURCES: st.markdown( f"**{resource['name']}**: {resource['desc']} [Visit Website]({resource['url']})") + + # Provide localized helplines based on user's country + user_country = get_user_country() + country_label = user_country if user_country else "your country" + st.markdown("### ๐Ÿšจ Emergency Help") + if user_country and user_country in country_helplines: + st.markdown(f"**Helplines for {country_label}:**") + for line in country_helplines[user_country]: + st.markdown(f"โ€ข {line}") + else: + st.markdown( + f"Couldn't detect a local helpline for {country_label}. [Find help worldwide via IASP]({IASP_LINK})" + ) + + st.markdown("---") # Theme toggle in sidebar with st.expander("๐ŸŽจ Theme Settings"): @@ -415,4 +516,4 @@ def render_sidebar(): *"It's absolutely okay not to be okay :)"* ๐Ÿ“… Enhanced Version - May 2025 - """) \ No newline at end of file + """) diff --git a/core/config.py b/core/config.py index a7fa361..e385eb8 100644 --- a/core/config.py +++ b/core/config.py @@ -14,7 +14,7 @@ "menu_items": None } -st.set_page_config(**PAGE_CONFIG) +#st.set_page_config(**PAGE_CONFIG) # ---------- Custom Dropdown Style ---------- st.markdown(""" diff --git a/css/styles.py b/css/styles.py index b4ee017..18ec9cd 100644 --- a/css/styles.py +++ b/css/styles.py @@ -63,23 +63,10 @@ def apply_custom_css(): --transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); }} - /* Streamlit header and toolbar fixes */ .stApp > header {{ background-color: transparent !important; }} - div[data-testid="stToolbar"] {{ - visibility: hidden; - }} - - .stDeployButton {{ - visibility: hidden; - }} - - footer {{ - visibility: hidden; - }} - /* Main app background and styling */ .stApp {{ background-image: url("data:image/jpeg;base64,{base64_image}"); @@ -498,7 +485,7 @@ def apply_custom_css(): .stTextInput > div > div > input, .stTextArea > div > div > textarea {{ background: var(--glass-effect) !important; - background-color: #FFFFD0 !important; + background-color: #FFDDEE !important; border: 2px solid var(--border) !important; border-radius: var(--radius) !important; font-size: 1em !important; diff --git a/data/Yoga.json b/data/Yoga.json new file mode 100644 index 0000000..765d13f --- /dev/null +++ b/data/Yoga.json @@ -0,0 +1,91 @@ +{ + "Anxious": { + "sanskrit_name": "Viparita Karani", + "english_name": "Legs-Up-the-Wall Pose", + "benefit": "Relieves anxiety and calms the nervous system.", + "steps": [ + "Lie on your back and extend your legs up against a wall.", + "Keep your arms relaxed at your sides.", + "Breathe deeply and relax for 5-15 minutes." + ] + }, + "Sad": { + "sanskrit_name": "Balasana", + "english_name": "Child's Pose", + "benefit": "Soothes sadness and encourages inner reflection.", + "steps": [ + "Kneel down and sit back on your heels.", + "Bend forward and stretch your arms in front of you.", + "Rest your forehead on the mat and take deep breaths." + ] + }, + "Stressed": { + "sanskrit_name": "Bhramari Pranayama", + "english_name": "Bee Breath", + "benefit": "Reduces stress and relaxes the mind through calming vibrations.", + "steps": [ + "Sit comfortably with your spine straight.", + "Close your eyes and take a deep breath in.", + "Exhale slowly while making a humming sound like a bee.", + "Repeat this for 5-10 rounds." + ] + }, + "Motivated": { + "sanskrit_name": "Surya Namaskar", + "english_name": "Sun Salutation", + "benefit": "Boosts energy, motivation, and positivity through a full-body flow.", + "steps": [ + "Stand tall in Mountain Pose with hands in prayer.", + "Inhale, raise your arms overhead and arch back slightly.", + "Exhale, fold forward and place your hands on the ground.", + "Inhale, lift your head and chest halfway up.", + "Exhale, step back into a plank and lower to the floor.", + "Inhale into Cobra pose.", + "Exhale into Downward Dog and hold.", + "Inhale, step forward, and repeat the flow for 3-5 rounds." + ] + }, + "Tired": { + "sanskrit_name": "Savasana", + "english_name": "Corpse Pose", + "benefit": "Promotes deep rest and rejuvenation.", + "steps": [ + "Lie flat on your back with legs extended and arms by your sides.", + "Close your eyes and let your entire body relax.", + "Focus on your breath and stay in this pose for 5-10 minutes." + ] + }, + "Angry": { + "sanskrit_name": "Simhasana", + "english_name": "Lion's Breath", + "benefit": "Releases anger and tension through expressive breath.", + "steps": [ + "Sit in a comfortable kneeling position.", + "Inhale deeply through the nose.", + "Exhale forcefully through the mouth while sticking out your tongue and roaring like a lion.", + "Repeat for 5 rounds." + ] + }, + "Lonely": { + "sanskrit_name": "Matsyasana", + "english_name": "Fish Pose", + "benefit": "Opens the heart center and promotes emotional release.", + "steps": [ + "Lie on your back and slide your hands under your hips.", + "Press your forearms and elbows into the ground.", + "Lift your chest and gently drop your head back.", + "Hold for 5 breaths, then relax." + ] + }, + "Joyful": { + "sanskrit_name": "Natarajasana", + "english_name": "Dancer's Pose", + "benefit": "Celebrates balance, grace, and self-expression.", + "steps": [ + "Stand tall and shift your weight to your left foot.", + "Bend your right knee and hold your ankle from behind.", + "Extend your left arm forward and lift your right leg up.", + "Hold for 5-7 breaths, then switch sides." + ] + } +} diff --git a/journals.db b/journals.db new file mode 100644 index 0000000..597e43a Binary files /dev/null and b/journals.db differ diff --git a/pages/Journaling.py b/pages/Journaling.py new file mode 100644 index 0000000..715e19c --- /dev/null +++ b/pages/Journaling.py @@ -0,0 +1,173 @@ +import streamlit as st +import sqlite3 +import datetime +import base64 +from uuid import uuid4 + +def get_base64_of_bin_file(bin_file_path): + with open(bin_file_path, 'rb') as f: + data = f.read() + return base64.b64encode(data).decode() + +def set_background(main_bg_path, sidebar_bg_path=None): + main_bg = get_base64_of_bin_file(main_bg_path) + sidebar_bg = get_base64_of_bin_file(sidebar_bg_path) if sidebar_bg_path else main_bg + + st.markdown( + f""" + + """, + unsafe_allow_html=True + ) + +def analyze_sentiment(entry: str) -> str: + if any(word in entry.lower() for word in ['sad', 'tired', 'upset', 'angry']): + return "Negative" + elif any(word in entry.lower() for word in ['happy', 'grateful', 'joy']): + return "Positive" + return "Neutral" + +DB_PATH = "journals.db" + +def init_journal_db(): + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + cursor.execute(""" + CREATE TABLE IF NOT EXISTS journal_entries ( + id TEXT PRIMARY KEY, + email TEXT, + entry TEXT, + sentiment TEXT, + date TEXT + ) + """) + conn.commit() + conn.close() + +def save_entry(email, entry, sentiment): + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO journal_entries (id, email, entry, sentiment, date) + VALUES (?, ?, ?, ?, ?) + """, (str(uuid4()), email, entry, sentiment, str(datetime.date.today()))) + conn.commit() + conn.close() + +def fetch_entries(email, sentiment_filter=None, start_date=None, end_date=None): + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + query = """ + SELECT entry, sentiment, date FROM journal_entries + WHERE email = ? + """ + params = [email] + + if sentiment_filter and sentiment_filter != "All": + query += " AND sentiment = ?" + params.append(sentiment_filter) + + if start_date and end_date: + query += " AND date BETWEEN ? AND ?" + params.extend([start_date, end_date]) + + rows = cursor.execute(query, params).fetchall() + conn.close() + return rows + +def journaling_app(): + set_background("mint.png") # Use your background image path or comment this line + st.markdown( + """ + + """, + unsafe_allow_html=True + ) + email = st.session_state.get("user_email") + if not email: + st.warning("โš ๏ธ Please login from the main page to access your journal.") + st.stop() + + st.title("๐Ÿ“ My Journal") + st.markdown("Write about your day, thoughts, or anything you'd like to reflect on.") + + with st.form("journal_form"): + journal_text = st.text_area("How are you feeling today?", height=200) + submitted = st.form_submit_button("Submit Entry") + + if submitted and journal_text.strip(): + sentiment = analyze_sentiment(journal_text) + save_entry(email, journal_text, sentiment) + st.success(f"Entry saved! Sentiment: **{sentiment}**") + + st.markdown("---") + st.subheader("๐Ÿ“– Your Journal Entries") + + filter_sentiment = st.selectbox("Filter by Sentiment", ["All", "Positive", "Neutral", "Negative"]) + + col1, col2 = st.columns(2) + with col1: + start_date = st.date_input("Start Date", value=datetime.date.today().replace(day=1)) + with col2: + end_date = st.date_input("End Date", value=datetime.date.today()) + + entries = fetch_entries(email, sentiment_filter=filter_sentiment, start_date=start_date, end_date=end_date) + + if not entries: + st.info("No entries found for selected filters.") + else: + for entry, sentiment, date in entries: + with st.expander(f"{date} - Mood: {sentiment}"): + st.write(entry) + +init_journal_db() +journaling_app() diff --git a/pages/Yoga.py b/pages/Yoga.py new file mode 100644 index 0000000..270aca2 --- /dev/null +++ b/pages/Yoga.py @@ -0,0 +1,298 @@ +import streamlit as st +import json +import os +import base64 +from streamlit_lottie import st_lottie + +st.set_page_config(page_title="๐Ÿง˜ Yoga for Mental Health", layout="centered") + +def load_lottiefile(filepath: str): + try: + with open(filepath, "r") as f: + return json.load(f) + except FileNotFoundError: + return None + +# Function to encode image to base64 +def get_base64_of_bin_file(bin_file): + try: + with open(bin_file, 'rb') as f: + data = f.read() + return base64.b64encode(data).decode() + except FileNotFoundError: + st.error(f"Background image not found at {bin_file}. Please check the path.") + return "" + +lottie_yoga = load_lottiefile("assets/yoga_animation.json") + +# --- Load Yoga Data --- +try: + with open(os.path.join("data", "Yoga.json"), "r") as f: + yoga_data = json.load(f) +except FileNotFoundError: + yoga_data = {} + +background_image_path = "lavender.png" +base64_background_image = get_base64_of_bin_file(background_image_path) + +# --- Custom CSS --- +st.markdown(f""" + +""", unsafe_allow_html=True) + +# --- Animation --- +st.markdown('
', unsafe_allow_html=True) +if lottie_yoga: + st_lottie(lottie_yoga, height=220, key="yoga") +st.markdown('
', unsafe_allow_html=True) + +# --- Title & Description --- +st.markdown("

๐Ÿง˜โ€โ™€๏ธ Yoga for Mental Wellness

", unsafe_allow_html=True) +st.markdown("

Choose your mood and explore a calming yoga asana to support your mind and body.

", unsafe_allow_html=True) + +# --- Dropdown -- +def format_mood(option): + return "Select your mood" if option == "Select your mood" else option + +mood_options = ["Select your mood"] + list(yoga_data.keys()) +selected_mood = st.selectbox( + "๐ŸŒธ How are you feeling today?", + options=mood_options, + index=0, + format_func=format_mood, + key="mood_selector" +) + +# --- Asana Section --- +if selected_mood != "Select your mood": + asana = yoga_data.get(selected_mood) + if asana: + st.markdown("
", unsafe_allow_html=True) + st.markdown(f"
๐Ÿง˜ {asana.get('sanskrit_name')} ({asana.get('english_name')})
", unsafe_allow_html=True) + st.markdown(f"

๐Ÿ’– {asana.get('benefit')}

", unsafe_allow_html=True) + + with st.expander("๐Ÿ“‹ Steps to Perform"): + steps = asana.get("steps", []) + if steps: + for i, step in enumerate(steps, 1): + fixed_step = step.replace("รขโ‚ฌโ€œ", "โ€“").replace("รขโ‚ฌโ€น", "") + st.markdown(f"
{i}. {fixed_step}
", unsafe_allow_html=True) + else: + st.markdown("
No steps available for this asana.
", unsafe_allow_html=True) + + st.markdown("
", unsafe_allow_html=True) + else: + st.warning(f"No yoga asana found for '{selected_mood}'. Please select another mood.") diff --git a/requirements.txt b/requirements.txt index c6beb4f..0660064 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,7 @@ streamlit_modal google-generativeai geopy requests -Pillow \ No newline at end of file +Pillow +streamlit-lottie +bcrypt +streamlit_js_eval \ No newline at end of file diff --git a/streamlit.toml b/streamlit.toml index 0a23a05..5cdfe5c 100644 --- a/streamlit.toml +++ b/streamlit.toml @@ -1 +1,2 @@ -GEMINI_API_KEY = "AIzaSyDsLJgA58LvgFtnUdVBLFb08GZQV0wXYjQ" +GEMINI_API_KEY = "GEMINI_API_KEY" + diff --git a/users.db b/users.db new file mode 100644 index 0000000..1931765 Binary files /dev/null and b/users.db differ