diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..964b19db
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,7 @@
+## 📋 ì´ìŠˆ ë‚´ìš©
+
+
+## ✅ ì²´í¬ë¦¬ìŠ¤íŠ¸
+- [ ]
+
+## ðŸ“ ë ˆí¼ëŸ°ìŠ¤
\ 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 00000000..c5c07b8c
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,20 @@
+## #ï¸âƒ£ì—°ê´€ëœ ì´ìŠˆ
+
+## 📋 PR 개요
+
+
+## ✅ PR ìœ í˜•
+- [ ] 새로운 기능 추가
+- [ ] 버그 ìˆ˜ì •
+- [ ] CSS 등 ì‚¬ìš©ìž UI ë””ìžì¸ 변경
+- [ ] ì½”ë“œì— ì˜í–¥ì„ 주지 않는 변경사í•(오타 ìˆ˜ì •, íƒ ì‚¬ì´ì¦ˆ 변경, 변수명 변경)
+- [ ] 코드 ë¦¬íŒ©í† ë§
+- [ ] ì£¼ì„ ì¶”ê°€ ë° ìˆ˜ì •
+- [ ] 문서 ìˆ˜ì •
+- [ ] 테스트 추가, 테스트 ë¦¬íŒ©í† ë§
+- [ ] 빌드 부분 í˜¹ì€ íŒ¨í‚¤ì§€ ë§¤ë‹ˆì € ìˆ˜ì •
+- [ ] íŒŒì¼ í˜¹ì€ í´ë”명 ìˆ˜ì •
+- [ ] íŒŒì¼ í˜¹ì€ í´ë” ì‚ì œ
+
+## âœï¸ 변경 사í•
+- ë‚´ìš©ì„ ì 어주세요.
\ No newline at end of file
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000..2b6ae04b
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,59 @@
+name: Build and Deploy to EC2
+
+on:
+ push:
+ branches: [ "dev_backend" ]
+ pull_request:
+ branches: [ "dev_backend" ]
+
+defaults:
+ run:
+ shell: bash
+
+env:
+ AWS_S3_BUCKET: howabouttrip-backend-s3
+ AWS_CODE_DEPLOY_APPLICATION: HowAboutTrip-Backend-CD
+ AWS_CODE_DEPLOY_GROUP: HowAboutTrip-Backend-CD-Group
+
+jobs:
+ deploy:
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'corretto'
+
+ - name: Grant execute permission for gradlew
+ working-directory: ./backend
+ run: chmod +x ./gradlew
+ shell: bash
+
+ - name: Build Project and Test
+ working-directory: ./backend
+ run: ./gradlew build test
+
+ - name: Setup MySQL
+ uses: mirromutth/mysql-action@v1.1
+ with:
+ mysql database: 'trip'
+ mysql user: ${DB_USERNAME}
+ mysql password: ${DB_PASSWORD}
+
+ - name: Configure AWS credential
+ uses: aws-actions/configure-aws-credentials@v1
+ with:
+ aws-region: ap-northeast-2
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+
+ - name: Upload to S3
+ working-directory: ./backend
+ run: aws deploy push --application-name ${{ env.AWS_CODE_DEPLOY_APPLICATION }} --ignore-hidden-files --s3-location s3://${{ env.AWS_S3_BUCKET }}/HowAboutTrip-Backend-EC2/$GITHUB_SHA.zip --source .
+
+ - name: Code Deploy to EC2
+ working-directory: ./backend
+ run: aws deploy create-deployment --application-name ${{ env.AWS_CODE_DEPLOY_APPLICATION }} --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name ${{ env.AWS_CODE_DEPLOY_GROUP }} --s3-location bucket=${{ env.AWS_S3_BUCKET }},key=HowAboutTrip-Backend-EC2/$GITHUB_SHA.zip,bundleType=zip
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..bdce34a9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,294 @@
+# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,gradle,intellij+all,java,intellij,sonar
+# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,gradle,intellij+all,java,intellij,sonar
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+# https://plugins.jetbrains.com/plugin/7973-sonarlint
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator-enh.xml
+.idea/**/markdown-navigator/
+
+# Cache file creation bug
+# See https://youtrack.jetbrains.com/issue/JBR-2257
+.idea/$CACHE_FILE$
+
+# CodeStream plugin
+# https://plugins.jetbrains.com/plugin/12206-codestream
+.idea/codestream.xml
+
+# Azure Toolkit for IntelliJ plugin
+# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
+.idea/**/azureSettings.xml
+
+### Intellij+all ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+
+# AWS User-specific
+
+# Generated files
+
+# Sensitive or high-churn files
+
+# Gradle
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+
+# Mongo Explorer plugin
+
+# File-based project format
+
+# IntelliJ
+
+# mpeltonen/sbt-idea plugin
+
+# JIRA plugin
+
+# Cursive Clojure plugin
+
+# SonarLint plugin
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+
+# Editor-based Rest Client
+
+# Android studio 3.1+ serialized cache file
+
+### Intellij+all Patch ###
+# Ignore everything but code style settings and run configurations
+# that are supposed to be shared within teams.
+
+.idea/*
+
+!.idea/codeStyles
+!.idea/runConfigurations
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+replay_pid*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### macOS Patch ###
+# iCloud generated files
+*.icloud
+
+### Sonar ###
+#Sonar generated dir
+/.sonar/
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+### Gradle ###
+.gradle
+**/build/
+!src/**/build/
+.idea/sonarlint
+
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Avoid ignore Gradle wrappper properties
+!gradle-wrapper.properties
+
+# Cache of project
+.gradletasknamecache
+
+# Eclipse Gradle plugin generated files
+# Eclipse Core
+.project
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+### Gradle Patch ###
+# Java heap dump
+*.hprof
+
+# End of https://www.toptal.com/developers/gitignore/api/macos,windows,gradle,intellij+all,java,intellij,sonar
+*.pptx
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..92d600d2
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+.idea/sonarlint
+
diff --git a/.idea/ISP.iml b/.idea/ISP.iml
new file mode 100644
index 00000000..55a758cf
--- /dev/null
+++ b/.idea/ISP.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 00000000..6b7d6740
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 00000000..f9030907
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 00000000..fdc392fe
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jpa-buddy.xml b/.idea/jpa-buddy.xml
new file mode 100644
index 00000000..898e07a6
--- /dev/null
+++ b/.idea/jpa-buddy.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..a449ab52
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..1900631b
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/backend.iml b/.idea/modules/backend.iml
new file mode 100644
index 00000000..1bd5cb3e
--- /dev/null
+++ b/.idea/modules/backend.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/backend.main.iml b/.idea/modules/backend.main.iml
new file mode 100644
index 00000000..6bd375ab
--- /dev/null
+++ b/.idea/modules/backend.main.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/backend.test.iml b/.idea/modules/backend.test.iml
new file mode 100644
index 00000000..10c8c277
--- /dev/null
+++ b/.idea/modules/backend.test.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/0/6/065e95c874597c49590257f1b37ccd1a809185ce b/.idea/sonarlint/issuestore/0/6/065e95c874597c49590257f1b37ccd1a809185ce
new file mode 100644
index 00000000..4d440a06
--- /dev/null
+++ b/.idea/sonarlint/issuestore/0/6/065e95c874597c49590257f1b37ccd1a809185ce
@@ -0,0 +1,3 @@
+
+{
+java:S1128"`Remove this unused import 'com.isp.backend.global.exception.member.MemberNotActivatedException'.(ÙŸ‘žûÿÿÿÿ
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/2/1/21d4b1ec4e3be89735ba8533a58eee07a372667a b/.idea/sonarlint/issuestore/2/1/21d4b1ec4e3be89735ba8533a58eee07a372667a
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/2/3/2363d464b7abe433f93c6cab2d693ce0bd00ed52 b/.idea/sonarlint/issuestore/2/3/2363d464b7abe433f93c6cab2d693ce0bd00ed52
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/2/3/23e463b2e953a590c1c20f64075baaa7a9b12eb7 b/.idea/sonarlint/issuestore/2/3/23e463b2e953a590c1c20f64075baaa7a9b12eb7
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/2/5/25e7bc2e784c14c74b34d15b334f63726e22b891 b/.idea/sonarlint/issuestore/2/5/25e7bc2e784c14c74b34d15b334f63726e22b891
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/3/3/330813660e7d0a96999bd35a5cebf19a0e34105b b/.idea/sonarlint/issuestore/3/3/330813660e7d0a96999bd35a5cebf19a0e34105b
new file mode 100644
index 00000000..3b3481d4
--- /dev/null
+++ b/.idea/sonarlint/issuestore/3/3/330813660e7d0a96999bd35a5cebf19a0e34105b
@@ -0,0 +1,2 @@
+
+o java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(ª¥¿
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/3/d/3de99115bf130d9ac74cb84cf73160d47a7d6f22 b/.idea/sonarlint/issuestore/3/d/3de99115bf130d9ac74cb84cf73160d47a7d6f22
new file mode 100644
index 00000000..3b525412
--- /dev/null
+++ b/.idea/sonarlint/issuestore/3/d/3de99115bf130d9ac74cb84cf73160d47a7d6f22
@@ -0,0 +1,2 @@
+
+t java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(¯žÄüÿÿÿÿ
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/3/e/3e7baf5788b82805f2e8de304ea856c7f50e4463 b/.idea/sonarlint/issuestore/3/e/3e7baf5788b82805f2e8de304ea856c7f50e4463
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/4/5/45fb1e19d829b0c832b3cac40fc3f67fd0df95a2 b/.idea/sonarlint/issuestore/4/5/45fb1e19d829b0c832b3cac40fc3f67fd0df95a2
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/4/7/4782521f7af0b5e4af513038bfb522ed4dc91c53 b/.idea/sonarlint/issuestore/4/7/4782521f7af0b5e4af513038bfb522ed4dc91c53
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/4/b/4bea8a271179cc56b85f48f234ab6200a9668cc5 b/.idea/sonarlint/issuestore/4/b/4bea8a271179cc56b85f48f234ab6200a9668cc5
new file mode 100644
index 00000000..39e0c846
--- /dev/null
+++ b/.idea/sonarlint/issuestore/4/b/4bea8a271179cc56b85f48f234ab6200a9668cc5
@@ -0,0 +1,7 @@
+
+f
+java:S11925"KDefine a constant instead of duplicating this literal "token_type" 4 times.(«¿‹€ûÿÿÿÿ
+~
+java:S14889"cImmediately return this expression instead of assigning it to the temporary variable "accessToken".(Ì글üÿÿÿÿ
+z
+java:S1488M"dImmediately return this expression instead of assigning it to the temporary variable "refreshToken".(Ж¬À
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/5/4/5427e158efe231e7f47bb4a5853deac93cbcae0f b/.idea/sonarlint/issuestore/5/4/5427e158efe231e7f47bb4a5853deac93cbcae0f
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/6/4/64208b6155f2d4e2e3fe0106eb90088af7d3b2e4 b/.idea/sonarlint/issuestore/6/4/64208b6155f2d4e2e3fe0106eb90088af7d3b2e4
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/6/a/6a2dd50a3f6743dd249b62f3b60675b35f1da4c3 b/.idea/sonarlint/issuestore/6/a/6a2dd50a3f6743dd249b62f3b60675b35f1da4c3
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/7/3/739b9a34c92bd055e28df022d452c330a2c0c3c2 b/.idea/sonarlint/issuestore/7/3/739b9a34c92bd055e28df022d452c330a2c0c3c2
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/7/b/7b3a79f800e85c8b44fcfc250f8be64bf945f627 b/.idea/sonarlint/issuestore/7/b/7b3a79f800e85c8b44fcfc250f8be64bf945f627
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/7/d/7d88f08545b388a8671b7bf33741a819d744615e b/.idea/sonarlint/issuestore/7/d/7d88f08545b388a8671b7bf33741a819d744615e
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/7/e/7e16691a9fc60084a157565ec422c8094d3df67c b/.idea/sonarlint/issuestore/7/e/7e16691a9fc60084a157565ec422c8094d3df67c
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/7/e/7e30ae1cb84f6db862cf23385cd180d2ee224023 b/.idea/sonarlint/issuestore/7/e/7e30ae1cb84f6db862cf23385cd180d2ee224023
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/7/f/7f150bb1711df2425db4160648cf05d67e224656 b/.idea/sonarlint/issuestore/7/f/7f150bb1711df2425db4160648cf05d67e224656
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/8/6/86da04119b555391860b194466103596afaf9d52 b/.idea/sonarlint/issuestore/8/6/86da04119b555391860b194466103596afaf9d52
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/8/a/8acaf61470b8ba9aa6049283e1007d390bfaa9be b/.idea/sonarlint/issuestore/8/a/8acaf61470b8ba9aa6049283e1007d390bfaa9be
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/8/e/8eb84e93349d79436a7fe24fb4d9f0c36b25c479 b/.idea/sonarlint/issuestore/8/e/8eb84e93349d79436a7fe24fb4d9f0c36b25c479
new file mode 100644
index 00000000..aad5046c
--- /dev/null
+++ b/.idea/sonarlint/issuestore/8/e/8eb84e93349d79436a7fe24fb4d9f0c36b25c479
@@ -0,0 +1,3 @@
+
+H
+java:S2699 "-Add at least one assertion to this test case.(áùêÌùÿÿÿÿ
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d b/.idea/sonarlint/issuestore/8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/9/5/95352dc9683fc5665e000eb792c2e520ec020fa5 b/.idea/sonarlint/issuestore/9/5/95352dc9683fc5665e000eb792c2e520ec020fa5
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/9/5/954cd358297ecfdc47b7f4515dcf34dfb67f86aa b/.idea/sonarlint/issuestore/9/5/954cd358297ecfdc47b7f4515dcf34dfb67f86aa
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/9/6/9691797aa04d85d3238a4a45d4fa240168a3d92d b/.idea/sonarlint/issuestore/9/6/9691797aa04d85d3238a4a45d4fa240168a3d92d
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/9/8/982d85ea34e066de5118505e73079ae8c0bbd2f1 b/.idea/sonarlint/issuestore/9/8/982d85ea34e066de5118505e73079ae8c0bbd2f1
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/9/8/988ee194fffff9c0b19490c3f17aec47381ae2a0 b/.idea/sonarlint/issuestore/9/8/988ee194fffff9c0b19490c3f17aec47381ae2a0
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/a/4/a4d45d939048b362dfb05cd73baff88946c380da b/.idea/sonarlint/issuestore/a/4/a4d45d939048b362dfb05cd73baff88946c380da
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302 b/.idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/a/9/a9e70078b70425918411b78b3c53d5603c3ce5c7 b/.idea/sonarlint/issuestore/a/9/a9e70078b70425918411b78b3c53d5603c3ce5c7
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/a/d/ad8639f749dc49476f473a3e26d54daae5f52c58 b/.idea/sonarlint/issuestore/a/d/ad8639f749dc49476f473a3e26d54daae5f52c58
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/a/d/ade58d0c2cdff8bd319d05c89afd49ae61d4c888 b/.idea/sonarlint/issuestore/a/d/ade58d0c2cdff8bd319d05c89afd49ae61d4c888
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/b/3/b329b210b93dd6d96e8198d55bd14bd3361ac708 b/.idea/sonarlint/issuestore/b/3/b329b210b93dd6d96e8198d55bd14bd3361ac708
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/b/5/b556167afb84bda333b2fab7fc28934e32b459d9 b/.idea/sonarlint/issuestore/b/5/b556167afb84bda333b2fab7fc28934e32b459d9
new file mode 100644
index 00000000..17cc0b43
--- /dev/null
+++ b/.idea/sonarlint/issuestore/b/5/b556167afb84bda333b2fab7fc28934e32b459d9
@@ -0,0 +1,7 @@
+
+x
+java:S1128"]Remove this unused import 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder'.(åÅÚ…ûÿÿÿÿ
+s
+java:S1128"]Remove this unused import 'org.springframework.security.crypto.password.NoOpPasswordEncoder'.(ƒ»ÅÅ
+t
+java:S1128"YRemove this unused import 'org.springframework.security.crypto.password.PasswordEncoder'.(‰¡ßáÿÿÿÿÿ
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/b/d/bd7108983578f649cb6893456714cdace9161089 b/.idea/sonarlint/issuestore/b/d/bd7108983578f649cb6893456714cdace9161089
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/b/f/bf8a91d94ba6d87e3accbb8ff83cce215d706910 b/.idea/sonarlint/issuestore/b/f/bf8a91d94ba6d87e3accbb8ff83cce215d706910
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/c/2/c2919d98ae33730c77963d99ccd650551213ef68 b/.idea/sonarlint/issuestore/c/2/c2919d98ae33730c77963d99ccd650551213ef68
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/sonarlint/issuestore/c/5/c50f0cf17624e9670cc09596eb1c566241c04477 b/.idea/sonarlint/issuestore/c/5/c50f0cf17624e9670cc09596eb1c566241c04477
new file mode 100644
index 00000000..292236ec
--- /dev/null
+++ b/.idea/sonarlint/issuestore/c/5/c50f0cf17624e9670cc09596eb1c566241c04477
@@ -0,0 +1,8 @@
+
+c
+java:S11921"MDefine a constant instead of duplicating this literal "Access-Token" 3 times.(¢ìäÈ
+i
+java:S11922"NDefine a constant instead of duplicating this literal "Refresh-Token" 3 times.(óŸãáûÿÿÿÿ
+] java:S125"
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..56ab882d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,56 @@
+
+
+
+# 여행어때
+
+
+```
+âœˆï¸ ì—¬í–‰ ì¼ì •ì´ 필요해? 우리가 만들어줄게!
+```
+
+
+## CONTRIBUTORS
+| 김수현
([@ksh-g001](https://github.com/ksh-g001)) | í™ë‹¤ì—°
([@Dayeon-Hong](https://github.com/Dayon-Hong)) | 김지윤
([@yo0oni](https://github.com/yo0oni)) |
+|:---------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|
+| | |
+| `Android` | `Backend` | `Backend`
`DevOps` |
+
+
+## TECH STACK
+### Android
+- Android App Architecture
+- Retrofit2, OkHttp3
+- Coroutine & Flow
+- Data Binding & View Binding
+- Google OAuth
+- Lottie
+- Google Map SDK & Google Place SDK
+
+### Backend
+- Spring Boot 3.2.2 with Java 17
+- MySQL & JPA
+- AWS EC2, CodeDeploy for deploy
+- AWS S3
+- GPT-4o API
+- Amadeus API
+
+
+
+## [ERD](https://dbdiagram.io/d/HowAboutTrip-6634f0ee5b24a634d071a4d7)
+![HowAboutTrip](https://github.com/tukcomCD2024/ISP/assets/95288297/6eb6e6a6-7fde-413e-adfd-3df8f934214d)
+
+
+
+
+
+## SCREENSHOTS
+| ë·° | 1 | 2 | 3 | 4 |
+|:-------------:|:---------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|
+| 스플래쉬
ë¡œê·¸ì¸ | | | | |
+| ì¼ì •
ìƒì„±í•˜ê¸° | | | | |
+| ìƒì„±ëœ
ì¼ì •
ìˆ˜ì •í•˜ê¸° | | | | |
+| ì¼ì •
확ì¸í•˜ê¸° | | | | |
+| í•ê³µê¶Œ
ë° ìˆ™ë°•
예약하기
(작업 중) | | | | |
+
+
+
diff --git a/android/HowAboutTrip/.gitignore b/android/HowAboutTrip/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/android/HowAboutTrip/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/android/HowAboutTrip/.idea/.gitignore b/android/HowAboutTrip/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/android/HowAboutTrip/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/android/HowAboutTrip/.idea/appInsightsSettings.xml b/android/HowAboutTrip/.idea/appInsightsSettings.xml
new file mode 100644
index 00000000..23b2e1fe
--- /dev/null
+++ b/android/HowAboutTrip/.idea/appInsightsSettings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/compiler.xml b/android/HowAboutTrip/.idea/compiler.xml
new file mode 100644
index 00000000..b589d56e
--- /dev/null
+++ b/android/HowAboutTrip/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/deploymentTargetDropDown.xml b/android/HowAboutTrip/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 00000000..0c0c3383
--- /dev/null
+++ b/android/HowAboutTrip/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/gradle.xml b/android/HowAboutTrip/.idea/gradle.xml
new file mode 100644
index 00000000..0897082f
--- /dev/null
+++ b/android/HowAboutTrip/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/kotlinc.xml b/android/HowAboutTrip/.idea/kotlinc.xml
new file mode 100644
index 00000000..8d81632f
--- /dev/null
+++ b/android/HowAboutTrip/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/migrations.xml b/android/HowAboutTrip/.idea/migrations.xml
new file mode 100644
index 00000000..f8051a6f
--- /dev/null
+++ b/android/HowAboutTrip/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/misc.xml b/android/HowAboutTrip/.idea/misc.xml
new file mode 100644
index 00000000..8978d23d
--- /dev/null
+++ b/android/HowAboutTrip/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/.idea/render.experimental.xml b/android/HowAboutTrip/.idea/render.experimental.xml
new file mode 100644
index 00000000..8ec256a5
--- /dev/null
+++ b/android/HowAboutTrip/.idea/render.experimental.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/.gitignore b/android/HowAboutTrip/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/android/HowAboutTrip/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/build.gradle.kts b/android/HowAboutTrip/app/build.gradle.kts
new file mode 100644
index 00000000..b3331632
--- /dev/null
+++ b/android/HowAboutTrip/app/build.gradle.kts
@@ -0,0 +1,86 @@
+import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
+
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+ id("com.google.gms.google-services")
+ id("kotlin-kapt")
+}
+
+android {
+ namespace = "com.project.how"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.project.how"
+ minSdk = 29
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ buildFeatures{
+ dataBinding = true
+ buildConfig = true
+ }
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+ resValue("string", "API_SERVER", getApiKey("api_server"))
+
+ buildConfigField("String", "GOOGLE_OAUTH_ID", getApiKey("google_oauth_id"))
+ buildConfigField("String", "GOOGLE_MAP_API_KEY", getApiKey("google_map_api_key"))
+ buildConfigField("String", "GOOGLE_SERVER_ID", getApiKey("google_server_id"))
+ buildConfigField("String", "API_SERVER", getApiKey("api_server"))
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+fun getApiKey(propertyKey: String):String = gradleLocalProperties(rootDir).getProperty(propertyKey)
+
+dependencies {
+
+ implementation("androidx.core:core-ktx:1.12.0")
+ implementation("androidx.appcompat:appcompat:1.6.1")
+ implementation("com.google.android.material:material:1.11.0")
+ implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+ implementation("com.airbnb.android:lottie:6.3.0")
+
+ implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0")
+ implementation("androidx.fragment:fragment-ktx:1.7.0-alpha08")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
+ implementation("androidx.datastore:datastore-preferences:1.0.0")
+
+ implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
+ implementation("com.google.firebase:firebase-analytics")
+ implementation("com.google.firebase:firebase-auth:22.3.1")
+ implementation("com.google.android.gms:play-services-auth:20.7.0")
+
+ implementation("com.squareup.retrofit:retrofit:2.0.0-beta2")
+ implementation("com.squareup.retrofit2:converter-gson:2.9.0")
+ implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.12")
+ implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
+ implementation("com.squareup.retrofit2:converter-scalars:2.9.0")
+
+ implementation("com.github.bumptech.glide:glide:5.0.0-rc01")
+
+
+ testImplementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.5")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/google-services.json b/android/HowAboutTrip/app/google-services.json
new file mode 100644
index 00000000..1d353f25
--- /dev/null
+++ b/android/HowAboutTrip/app/google-services.json
@@ -0,0 +1,47 @@
+{
+ "project_info": {
+ "project_number": "740845966307",
+ "project_id": "howabouttrip",
+ "storage_bucket": "howabouttrip.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:740845966307:android:71aff1bfe733b688ad46d6",
+ "android_client_info": {
+ "package_name": "com.project.how"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "740845966307-oulmuvm5mv595vlu9hf1a3j5n4ouvskg.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.project.how",
+ "certificate_hash": "8f29dbe96504294182411cc8b5af35fee8e57de8"
+ }
+ },
+ {
+ "client_id": "740845966307-vhqequ0l999eglm9p87su14da4bjreid.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyDg0_7_UQD4gNj9XmKnQZpBGREl0r9CZ_Q"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "740845966307-vhqequ0l999eglm9p87su14da4bjreid.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/proguard-rules.pro b/android/HowAboutTrip/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/android/HowAboutTrip/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/androidTest/java/com/project/how/ExampleInstrumentedTest.kt b/android/HowAboutTrip/app/src/androidTest/java/com/project/how/ExampleInstrumentedTest.kt
new file mode 100644
index 00000000..4e1dac40
--- /dev/null
+++ b/android/HowAboutTrip/app/src/androidTest/java/com/project/how/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.project.how
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.project.how", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/AndroidManifest.xml b/android/HowAboutTrip/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..af2348be
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/CalendarAdapter.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/CalendarAdapter.kt
new file mode 100644
index 00000000..1811f8be
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/CalendarAdapter.kt
@@ -0,0 +1,154 @@
+package com.project.how.adapter
+
+import android.graphics.Color
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.project.how.R
+import com.project.how.databinding.CalendarDayItemBinding
+import java.time.LocalDate
+
+class CalendarAdapter(
+ repositoryDays : List,
+ selectedDate : LocalDate,
+ private val onItemClickListener : OnItemClickListener)
+ : RecyclerView.Adapter() {
+ private var sd = selectedDate
+ private var selected : MutableList = mutableListOf()
+ private val selectedMonthDays : MutableMap> = mutableMapOf()
+ private val selectedTwoDay : MutableMap = mutableMapOf()
+ private var days = repositoryDays
+ private var emptyCount = 0
+ private var dayCount = 1
+ private var selectedCount = 0
+
+ init {
+ Log.d("CalendarAdapter", "init repositoryDays.size : ${repositoryDays.size}\n${days.size}")
+ initSelected()
+ }
+
+ inner class ViewHolder(val binding : CalendarDayItemBinding) : RecyclerView.ViewHolder(binding.root){
+ fun bind(data: Int, position: Int){
+ if(data != EMPTY){
+ binding.day.text = dayCount++.toString()
+ val firstSelected = selectedTwoDay[FIRST]
+ val secondSelected = selectedTwoDay[SECOND]
+ if(firstSelected != null && secondSelected != null){
+ if(firstSelected.month.value < secondSelected.month.value){
+ if((position - emptyCount) < secondSelected.dayOfMonth){
+ binding.day.setTextColor(Color.parseColor("#00000000"))
+ binding.background.setBackgroundResource(R.color.black)
+ }
+ }else if(firstSelected.month.value > secondSelected.month.value){
+ if((position - emptyCount) < firstSelected.dayOfMonth){
+ binding.day.setTextColor(Color.parseColor("#00000000"))
+ binding.background.setBackgroundResource(R.color.black)
+ }
+ }else{
+ if(firstSelected.dayOfMonth < secondSelected.dayOfMonth){
+ if((firstSelected.dayOfMonth < (position - emptyCount)) && (secondSelected.dayOfMonth > (position - emptyCount))) {
+ binding.day.setTextColor(Color.parseColor("#00000000"))
+ binding.background.setBackgroundResource(R.color.black)
+ }
+ }else if(firstSelected.dayOfMonth > secondSelected.dayOfMonth){
+ if((firstSelected.dayOfMonth > (position - emptyCount)) && (secondSelected.dayOfMonth < (position - emptyCount))) {
+ binding.day.setTextColor(Color.parseColor("#00000000"))
+ binding.background.setBackgroundResource(R.color.black)
+ }
+ }
+ }
+ }
+ binding.day.setOnClickListener {
+// selected[position] = !selected[position]
+ selectedTwoDay[selectedCount++%2] = sd.withDayOfMonth(position-emptyCount)
+ val sd = sd.withDayOfMonth(position-emptyCount)
+ onItemClickListener.onItemClickListener(data, selected, position, sd)
+ }
+
+ changeColor(binding, position)
+ }else{
+ binding.day.text = " "
+ emptyCount++
+ }
+
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(
+ CalendarDayItemBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ )
+
+ override fun getItemCount(): Int = days.size
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val data = days[position]
+ holder.bind(data, position)
+ }
+
+ fun update(newDays : List, sd: LocalDate){
+ days = newDays
+ dayCount = 1
+ emptyCount = 0
+ observeMonthChange(sd)
+ notifyDataSetChanged()
+ }
+
+ fun observeMonthChange(sd : LocalDate){
+ selectedMonthDays[this.sd.month.value] = selected
+ this.sd = sd
+ initSelected()
+ }
+
+ private fun initSelected(){
+ Log.d("CalendarAdapter", "Before ${selected.size}\n${days.size}")
+ selected = mutableListOf()
+ for(i in days.indices){
+ selected.add(false)
+ }
+ Log.d("CalendarAdapter", "After ${selected.size}\n${days.size}")
+ }
+
+ fun resetSelected(){
+ for(i in days.indices)
+ selected[i] = false
+ dayCount = 1
+ emptyCount = 0
+ notifyDataSetChanged()
+ }
+
+ private fun changeColor(binding: CalendarDayItemBinding, position: Int){
+ if(selected[position]){
+ binding.day.setTextColor(Color.parseColor("#FFFFFFFF"))
+ binding.background.setBackgroundResource(R.drawable.black_oval_day_background)
+ }else{
+ binding.day.setTextColor(Color.parseColor("#FF000000"))
+ binding.background.setBackgroundResource(R.drawable.white_oval_day_background)
+ }
+ }
+
+ fun getSelectedDays() : MutableMap?{
+ if (selectedTwoDay[FIRST] != null || selectedTwoDay[SECOND] != null)
+ return selectedTwoDay
+ return null
+ }
+
+ fun getSelectedDay() : LocalDate?{
+ if (selectedTwoDay[FIRST] != null)
+ return selectedTwoDay[FIRST]
+ return null
+ }
+
+ interface OnItemClickListener{
+ fun onItemClickListener(data : Int, selected : MutableList, position: Int, sd: LocalDate){}
+ }
+ companion object{
+ private const val EMPTY = 99
+ private const val FIRST = 0
+ private const val SECOND = 1
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/MemberInfo.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/MemberInfo.kt
new file mode 100644
index 00000000..2c2958fe
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/MemberInfo.kt
@@ -0,0 +1,7 @@
+package com.project.how.data_class
+
+data class MemberInfo(
+ val name : String,
+ val birth : String,
+ val phone : String
+)
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/Tokens.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/Tokens.kt
new file mode 100644
index 00000000..07f922ef
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/Tokens.kt
@@ -0,0 +1,6 @@
+package com.project.how.data_class
+
+data class Tokens(
+ val accessToken : String,
+ val refreshToken: String
+)
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/AuthRecreateRequest.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/AuthRecreateRequest.kt
new file mode 100644
index 00000000..0b3365f4
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/AuthRecreateRequest.kt
@@ -0,0 +1,7 @@
+package com.project.how.data_class.dto
+
+import com.google.gson.annotations.SerializedName
+
+data class AuthRecreateRequest(
+ @SerializedName("refreshToken") val refreshToken : String
+)
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/EmptyResponse.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/EmptyResponse.kt
new file mode 100644
index 00000000..6be866f3
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/EmptyResponse.kt
@@ -0,0 +1,3 @@
+package com.project.how.data_class.dto
+
+class EmptyResponse()
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/GetInfoResponse.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/GetInfoResponse.kt
new file mode 100644
index 00000000..2359be4c
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/GetInfoResponse.kt
@@ -0,0 +1,10 @@
+package com.project.how.data_class.dto
+
+import com.google.gson.annotations.SerializedName
+
+data class GetInfoResponse(
+ @SerializedName("uid") val uid : String,
+ @SerializedName("name") val name : String,
+ @SerializedName("birth") val birth : String,
+ @SerializedName("phoneNumber") val phone : String
+)
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/LoginRequest.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/LoginRequest.kt
new file mode 100644
index 00000000..d890cb60
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/LoginRequest.kt
@@ -0,0 +1,6 @@
+package com.project.how.data_class.dto
+import com.google.gson.annotations.SerializedName
+
+data class LoginRequest (
+ @SerializedName("uid") val uid : String
+)
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/SignUpInfo.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/SignUpInfo.kt
new file mode 100644
index 00000000..3e9f7aaa
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/SignUpInfo.kt
@@ -0,0 +1,7 @@
+package com.project.how.data_class.dto
+
+data class SignUpInfo(
+ val name : String,
+ val birth : String,
+ val phone : String
+)
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/SignUpRequest.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/SignUpRequest.kt
new file mode 100644
index 00000000..0a76791c
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/SignUpRequest.kt
@@ -0,0 +1,9 @@
+package com.project.how.data_class.dto
+
+import com.google.gson.annotations.SerializedName
+
+data class SignUpRequest(
+ @SerializedName("name") val name : String,
+ @SerializedName("birth") val birth : String,
+ @SerializedName("phoneNumber") val phone : String
+)
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/datastore/TokenDataStore.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/datastore/TokenDataStore.kt
new file mode 100644
index 00000000..71b74980
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/datastore/TokenDataStore.kt
@@ -0,0 +1,37 @@
+package com.project.how.datastore
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
+import androidx.datastore.preferences.core.stringPreferencesKey
+import androidx.datastore.preferences.preferencesDataStore
+import com.project.how.data_class.Tokens
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
+
+object TokenDataStore {
+ val Context.dataStore: DataStore by preferencesDataStore(name = "tokens")
+
+ val ACCESS_TOKEN = stringPreferencesKey("access_token")
+ val REFRESH_TOKEN = stringPreferencesKey("refresh_token")
+
+ suspend fun saveTokens(context: Context, tokens : Tokens){
+ context.dataStore.edit {
+ it[ACCESS_TOKEN] = tokens.accessToken
+ it[REFRESH_TOKEN] = tokens.refreshToken
+ }
+ }
+ fun getTokens(context: Context): Flow = flow {
+ context.dataStore.data.collect {
+ val accessToken = it[ACCESS_TOKEN]
+ val refreshToken = it[REFRESH_TOKEN]
+ if(accessToken.isNullOrEmpty() || refreshToken.isNullOrEmpty()){
+ this.emit(null)
+ }else{
+ this.emit(Tokens(accessToken, refreshToken))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/model/CalendarRepository.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/model/CalendarRepository.kt
new file mode 100644
index 00000000..4e32fcf6
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/model/CalendarRepository.kt
@@ -0,0 +1,76 @@
+package com.project.how.model
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
+import java.time.LocalDate
+
+class CalendarRepository {
+ private val nowDate = LocalDate.now()
+ private val _selectedDate = MutableLiveData()
+ val selectedDate : LiveData
+ get() = _selectedDate
+ private lateinit var monthOfFirstDate : LocalDate
+ private lateinit var sd : LocalDate
+ private var monthOfFirstDayOfWeek = Companion.EMPTY
+ private var lastDay = 0
+
+ private fun getMonthInform(fdw : Int) : Flow> = flow {
+ val monthInfo = mutableListOf()
+ lastDay = sd.lengthOfMonth()
+ var week = fdw
+ for (i in 0 until fdw)
+ monthInfo.add(Companion.EMPTY)
+ for(i in 1..lastDay){
+ monthInfo.add(week)
+ week = (week+1) % 7
+ }
+ this.emit(monthInfo)
+ }
+
+ private fun getMonthOfFirstDayOfWeekChangeInt() : Int {
+ when(monthOfFirstDate.dayOfWeek.toString()){
+ "MONDAY" -> return 1
+ "TUESDAY" -> return 2
+ "WEDNESDAY" -> return 3
+ "THURSDAY" -> return 4
+ "FRIDAY" -> return 5
+ "SATURDAY" -> return 6
+ "SUNDAY" -> return 0
+ else -> {
+ Log.e("getMonthOfFirstDayOfWeek", "monthOfFirstDate.dayOfWeek.toString() go to else case\n${monthOfFirstDate.dayOfWeek}")
+ return 99}
+ }
+ }
+
+ private fun getFirstDate(): Flow> {
+ monthOfFirstDate = sd.withDayOfMonth(1)!!
+ monthOfFirstDayOfWeek = getMonthOfFirstDayOfWeekChangeInt()
+ return getMonthInform(monthOfFirstDayOfWeek)
+ }
+
+ fun plusSelectedDate(): Flow> {
+ sd = sd.plusMonths(1)
+ _selectedDate.postValue(sd)
+ return getFirstDate()
+ }
+
+ fun minusSelectedDate(): Flow> {
+ sd = sd.minusMonths(1)
+ _selectedDate.postValue(sd)
+ return getFirstDate()
+ }
+
+ fun init() : Flow>{
+ sd = nowDate
+ _selectedDate.postValue(nowDate)
+ return getFirstDate()
+ }
+
+ companion object {
+ private const val EMPTY = 99
+ }
+
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/model/MemberRepository.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/model/MemberRepository.kt
new file mode 100644
index 00000000..5e6f12d9
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/model/MemberRepository.kt
@@ -0,0 +1,79 @@
+package com.project.how.model
+
+import android.content.Context
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import com.google.firebase.auth.FirebaseAuth
+import com.google.firebase.auth.FirebaseUser
+import com.google.firebase.auth.GoogleAuthProvider
+import com.project.how.data_class.MemberInfo
+import com.project.how.data_class.Tokens
+import com.project.how.datastore.TokenDataStore
+
+class MemberRepository {
+ private val firebaseAuth = FirebaseAuth.getInstance()
+ private val _currentUserLiveData = MutableLiveData()
+ private val _userLiveData = MutableLiveData()
+ private val _tokensLiveData = MutableLiveData()
+ private val _tokensSaveLiveData = MutableLiveData()
+ private val _Member_infoLiveData = MutableLiveData()
+ val currentUserLiveData : LiveData
+ get() = _currentUserLiveData
+ val userLiveData: LiveData
+ get() = _userLiveData
+ val tokensLiveData : LiveData
+ get() = _tokensLiveData
+ val tokensSaveLiveData : LiveData
+ get() = _tokensSaveLiveData
+ val memberInfoLiveData : LiveData
+ get() = _Member_infoLiveData
+
+ fun getUser(idToken: String) {
+ val credential = GoogleAuthProvider.getCredential(idToken, null)
+ firebaseAuth.signInWithCredential(credential).addOnCompleteListener{
+ if(it.isSuccessful){
+ _userLiveData.postValue(firebaseAuth.currentUser)
+ } else{
+ Log.e("GoogleAuthRepository", "getUser is failed\n${it.exception}")
+ }
+ }
+ }
+
+ suspend fun init(context: Context) {
+ Log.d("init", "LoginRepository init start")
+ TokenDataStore.getTokens(context).collect{
+ Log.d("init", "LoginRepository init getTokens() \tToken is null : ${it == null}")
+ if (it != null){
+ Log.d("init", "LoginRepository init getTokens()\naccessToken : ${it.accessToken}\nrefreshToken : ${it.refreshToken}")
+ _tokensLiveData.postValue(it)
+ _tokensSaveLiveData.postValue(true)
+ }else{
+ Log.d("init", "LoginRepository init getTokens() _tokensSaveLiveData.postValue(false)")
+ _tokensSaveLiveData.postValue(false)
+ }
+ }
+ Log.d("init", "LoginRepository init end")
+ }
+
+ fun checkCurrentUser() {
+ val currentUser = firebaseAuth.currentUser
+ if(currentUser != null){
+ Log.d("checkCurrentUser", "firebaseAuth.current != null\nemail : ${currentUser.email}\ndisplayName : ${currentUser.displayName}")
+ _currentUserLiveData.postValue(currentUser!!)
+ Log.d("checkCurrentUser", "currentUserLiveData.value : ${currentUserLiveData.value}")
+ }else{
+ Log.d("checkCurrentUser", "firebaseAuth.current == null")
+ }
+ }
+
+ suspend fun getTokens(context: Context, accessToken : String, refreshToken: String) {
+ val tokens = Tokens(accessToken, refreshToken)
+ _tokensLiveData.postValue(tokens)
+ TokenDataStore.saveTokens(context, Tokens(accessToken, refreshToken))
+ }
+
+ fun getInfo(memberInfo : MemberInfo){
+ _Member_infoLiveData.postValue(memberInfo)
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/MemberService.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/MemberService.kt
new file mode 100644
index 00000000..8d546d8e
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/MemberService.kt
@@ -0,0 +1,37 @@
+package com.project.how.network.api_interface
+
+import com.project.how.data_class.dto.EmptyResponse
+import com.project.how.data_class.dto.LoginRequest
+import com.project.how.data_class.dto.SignUpRequest
+import com.project.how.data_class.dto.AuthRecreateRequest
+import com.project.how.data_class.dto.GetInfoResponse
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.Header
+import retrofit2.http.Headers
+import retrofit2.http.POST
+import retrofit2.http.PUT
+
+interface MemberService {
+ @POST("members/login")
+ fun login(
+ @Body login: LoginRequest
+ ) : Call
+
+ @PUT("members/signup")
+ fun signUp(
+ @Header("Authorization") accessToken : String,
+ @Body signUp: SignUpRequest
+ ) : Call
+
+ @POST("members/refresh")
+ fun authRecreate(
+ @Body authRecreate : AuthRecreateRequest
+ ) : Call
+
+ @GET("members/info")
+ fun getInfo(
+ @Header("Authorization") accessToken: String
+ ) : Call
+}
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/MemberRetrofit.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/MemberRetrofit.kt
new file mode 100644
index 00000000..475f5f0e
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/MemberRetrofit.kt
@@ -0,0 +1,41 @@
+package com.project.how.network.client
+
+import com.google.gson.GsonBuilder
+import com.project.how.BuildConfig
+import com.project.how.network.api_interface.MemberService
+import com.project.how.network.converter_factory.NullOnEmptyConverterFactory
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object MemberRetrofit {
+ private const val BASE_URL = BuildConfig.API_SERVER
+
+ fun getApiService() : MemberService? = getInstance()?.create(MemberService::class.java)
+
+ private fun getInstance() : Retrofit? {
+ val gson = GsonBuilder().setLenient().create()
+
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(2, TimeUnit.MINUTES)
+ .readTimeout(1, TimeUnit.MINUTES)
+ .writeTimeout(1, TimeUnit.MINUTES)
+
+ val loggingInterceptor = HttpLoggingInterceptor().apply {
+ level = HttpLoggingInterceptor.Level.BODY
+ }
+ httpClient.addInterceptor(loggingInterceptor)
+
+ return Retrofit.Builder()
+ .baseUrl(BASE_URL)
+ .addConverterFactory(ScalarsConverterFactory.create())
+ .addConverterFactory(NullOnEmptyConverterFactory())
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .client(httpClient.build())
+ .build()
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/converter_factory/NullOnEmptyConverterFactory.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/converter_factory/NullOnEmptyConverterFactory.kt
new file mode 100644
index 00000000..c10c38c7
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/converter_factory/NullOnEmptyConverterFactory.kt
@@ -0,0 +1,19 @@
+package com.project.how.network.converter_factory
+
+
+import com.project.how.data_class.dto.EmptyResponse
+import okhttp3.ResponseBody
+import retrofit2.Converter
+import retrofit2.Retrofit
+import java.lang.reflect.Type
+
+class NullOnEmptyConverterFactory : Converter.Factory() {
+ override fun responseBodyConverter(type: Type?, annotations: Array?, retrofit: Retrofit?): Converter? {
+ val delegate = retrofit!!.nextResponseBodyConverter(this, type!!, annotations!!)
+ return Converter {
+ if (it.contentLength() == 0L) return@Converter EmptyResponse()
+ delegate.convert(it)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/LoginActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/LoginActivity.kt
new file mode 100644
index 00000000..27587970
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/LoginActivity.kt
@@ -0,0 +1,129 @@
+package com.project.how.view.activity
+
+import android.app.Activity
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.util.Log
+import android.widget.Toast
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.activity.viewModels
+import androidx.databinding.DataBindingUtil
+import androidx.lifecycle.lifecycleScope
+import com.google.android.gms.auth.api.signin.GoogleSignIn
+import com.google.android.gms.auth.api.signin.GoogleSignInClient
+import com.google.android.gms.auth.api.signin.GoogleSignInOptions
+import com.project.how.BuildConfig
+import com.project.how.R
+import com.project.how.data_class.dto.LoginRequest
+import com.project.how.databinding.ActivityLoginBinding
+import com.project.how.view_model.MemberViewModel
+import kotlinx.coroutines.launch
+
+class LoginActivity : AppCompatActivity() {
+ private lateinit var binding : ActivityLoginBinding
+ private val viewModel: MemberViewModel by viewModels()
+ private lateinit var activityResultLauncher : ActivityResultLauncher
+ private lateinit var googleSignInRequest: GoogleSignInClient
+ private lateinit var gso : GoogleSignInOptions
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_login)
+ binding.login = this
+ binding.lifecycleOwner = this
+
+ gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
+ .requestIdToken(BuildConfig.GOOGLE_SERVER_ID)
+ .requestEmail()
+ .build()
+ googleSignInRequest = GoogleSignIn.getClient(this, gso)
+ activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
+ if(it.resultCode == Activity.RESULT_OK) {
+ val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
+ try {
+ val account = task.result
+ viewModel.getUser(account.idToken!!)
+ viewModel.userLiveData.observe(this){user->
+ Log.d("activityResultLauncher", "Login Success\nidToken : ${account.idToken}\nid : ${account.id}\nemail : ${account.email}\nuid : ${user.uid}")
+ sendUid(user.uid)
+ }
+ } catch (e: Exception){
+ Log.e("activityResultLauncher", "Login Failed\nError : ${e.stackTrace}\n${e.message}")
+ }
+ }
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+ viewModel.currentUserLiveData.observe(this) { user ->
+ if (user != null) {
+ Log.d("onStart", "viewModel.currentUserLiveData.value != null")
+ autoLogin()
+ } else {
+ Log.d("onStart", "viewModel.currentUserLiveData.value == null")
+ }
+ }
+ }
+
+ private fun sendUid(uid : String){
+ lifecycleScope.launch {
+ val loginRequest = LoginRequest(uid)
+ val code = viewModel.getTokens(this@LoginActivity, loginRequest)
+ if(code == EXISTING_MEMBER){
+ Log.d("sendUid", "Existing member")
+ moveMain()
+ }else if(code == NEW_MEMBER){
+ Log.d("sendUid", "New member")
+ moveSignUp()
+ }else{
+ Log.e("sendUid", "Login failed")
+ Toast.makeText(this@LoginActivity, "[ë¡œê·¸ì¸ ì‹¤íŒ¨] HowAboutTrip 로그ì¸ì— 실패했습니다.\n해당 오류가 지ì†ë 경우 문ì˜í•˜ì‹œê¸°ë¥¼ ë°”ëžë‹ˆë‹¤.", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ private fun autoLogin() {
+ googleSignInRequest.silentSignIn().addOnCompleteListener(this) { task ->
+ if (task.isSuccessful){
+ try {
+ val account = task.result
+ viewModel.getUser(account.idToken!!)
+ viewModel.userLiveData.observe(this){user->
+ Log.d("autoLogin", "Auto Login Success\nidToken : ${account.idToken}\nid : ${account.id}\nemail : ${account.email}\nuid : ${user.uid}")
+ sendUid(user.uid)
+ }
+ } catch (e: Exception) {
+ Log.e("autoLogin", "Auto Login Failed\nError : ${e.stackTrace}\n${e.message}")
+ }
+ } else{
+ Log.e("autoLogin", "Auto Login Failed\nError : ${task.exception}")
+ }
+ }
+ }
+ fun login(){
+ activityResultLauncher.launch(googleSignInRequest.signInIntent)
+ binding.lottie.pauseAnimation()
+ }
+
+ private fun moveSignUp(){
+ viewModel.tokensLiveData.observe(this){
+ startActivity(Intent(this, SignUpActivity::class.java))
+ finish()
+ }
+ }
+
+ private fun moveMain(){
+ viewModel.tokensLiveData.observe(this){
+ startActivity(Intent(this, MainActivity::class.java))
+ finish()
+ }
+ }
+
+ companion object{
+ const val EXISTING_MEMBER = 200
+ const val NEW_MEMBER = 201
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/MainActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/MainActivity.kt
new file mode 100644
index 00000000..c2664fbc
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/MainActivity.kt
@@ -0,0 +1,46 @@
+package com.project.how.view.activity
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import androidx.databinding.DataBindingUtil
+import com.project.how.R
+import com.project.how.databinding.ActivityMainBinding
+import com.project.how.view.fragment.CalendarFragment
+import com.project.how.view.fragment.MypageFragment
+import com.project.how.view.fragment.PictureFragment
+import com.project.how.view.fragment.TicketFragment
+
+class MainActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityMainBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding= DataBindingUtil.setContentView(this, R.layout.activity_main)
+ binding.main = this
+ binding.lifecycleOwner = this
+
+ supportFragmentManager.beginTransaction().add(R.id.fragment, CalendarFragment()).commitAllowingStateLoss()
+ binding.menu.menu.getItem(2).isEnabled = false
+ binding.menu.selectedItemId = R.id.menu_calendar
+ binding.menu.setOnItemSelectedListener {
+ when(it.itemId){
+ R.id.menu_ticket->{
+ supportFragmentManager.beginTransaction().replace(R.id.fragment, TicketFragment())
+ .commitAllowingStateLoss()
+ }
+ R.id.menu_calendar->{
+ supportFragmentManager.beginTransaction().replace(R.id.fragment, CalendarFragment())
+ .commitAllowingStateLoss()
+ }
+ R.id.menu_picture->{
+ supportFragmentManager.beginTransaction().replace(R.id.fragment, PictureFragment())
+ .commitAllowingStateLoss()
+ }
+ R.id.menu_mypage->{
+ supportFragmentManager.beginTransaction().replace(R.id.fragment, MypageFragment())
+ .commitAllowingStateLoss()
+ }
+ }
+ true
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SignUpActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SignUpActivity.kt
new file mode 100644
index 00000000..d296d9d0
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SignUpActivity.kt
@@ -0,0 +1,157 @@
+package com.project.how.view.activity
+
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.telephony.PhoneNumberFormattingTextWatcher
+import android.util.Log
+import android.widget.Toast
+import androidx.activity.viewModels
+import androidx.databinding.DataBindingUtil
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.GridLayoutManager
+import com.google.android.material.bottomsheet.BottomSheetDialog
+import com.project.how.R
+import com.project.how.adapter.CalendarAdapter
+import com.project.how.data_class.dto.AuthRecreateRequest
+import com.project.how.databinding.ActivitySignUpBinding
+import com.project.how.databinding.CalendarBottomSheetBinding
+import com.project.how.view_model.CalendarViewModel
+import com.project.how.view_model.MemberViewModel
+import kotlinx.coroutines.launch
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+class SignUpActivity : AppCompatActivity(), CalendarAdapter.OnItemClickListener {
+ private lateinit var binding : ActivitySignUpBinding
+ private lateinit var calendarBinding : CalendarBottomSheetBinding
+ private val calenderViewModel : CalendarViewModel by viewModels()
+ private val memberViewModel : MemberViewModel by viewModels()
+ private lateinit var days : List
+ private lateinit var adapter : CalendarAdapter
+ private var selectedDay : LocalDate? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_sign_up)
+ calendarBinding = CalendarBottomSheetBinding.inflate(layoutInflater)
+ binding.signUp = this
+ binding.lifecycleOwner = this
+
+ lifecycleScope.launch {
+ memberViewModel.init(this@SignUpActivity)
+ }
+
+ binding.phone.addTextChangedListener(PhoneNumberFormattingTextWatcher())
+ }
+
+ fun sendInfo(){
+ val name = binding.name.text.toString()
+ val phone = binding.phone.text.toString()
+ val birth = binding.birth.text.toString()
+
+ Log.d("sendInfo", "IF Before\nname : $name\t${name.length}\nphone : $phone\t${phone.length}\nbirth : $birth\t${birth.length}")
+
+ if(name.isNotEmpty() && phone.length == 13 && birth.length == 8){
+ val n = name.trim()
+ val p = phone
+ val bDate = LocalDate.parse(birth, DateTimeFormatter.ofPattern("yyyyMMdd"))
+ val b = bDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
+ Log.d("sendInfo", "IF After\nname : $n\t${n.length}\nphone : $p\t${p.length}\nbirth : $b\t${b .length}")
+ memberViewModel.tokensLiveData.value?.let { memberViewModel.getInfoSignUp(this, it.accessToken, n, p, b) }
+ memberViewModel.memberInfoLiveData.observe(this){ info ->
+ moveMainActivity()
+ }
+ }else{
+ Toast.makeText(this, "[필수] ëª¨ë“ í•ëª©ì€ 필수로 ìž…ë ¥í•˜ì…”ì•¼ 합니다.\nëª¨ë“ í•ëª©ì´ ì •í•´ì§„ 형ì‹ì— 맞춰서 작성ë˜ì—ˆëŠ”지 확ì¸í•˜ì„¸ìš”.", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ private fun moveMainActivity() {
+ val intent = Intent(this, MainActivity::class.java)
+ startActivity(intent)
+ finish()
+ }
+
+// test용 코드
+// fun authRecreate(){
+// memberViewModel.tokensLiveData.value?.let {
+// memberViewModel.authRecreate(this, AuthRecreateRequest(it.refreshToken))
+// }
+// }
+
+// ìº˜ë¦°ë” í…ŒìŠ¤íŠ¸ìš© 코드
+// fun setCalenderBottomSheetView() {
+// initializeCalendarBottomSheet()
+// observeCalendarData()
+// }
+//
+// private fun initializeCalendarBottomSheet() {
+// calendarBinding = CalendarBottomSheetBinding.inflate(layoutInflater)
+// val bottomSheetDialog = BottomSheetDialog(this)
+// bottomSheetDialog.setContentView(calendarBinding.root)
+// bottomSheetDialog.show()
+//
+//
+// calenderViewModel.selectedDate.observe(this@SignUpActivity) { sd ->
+// Log.d("selectedData observe", "initializeCalendarBottom() 시작")
+// days = listOf()
+// adapter = CalendarAdapter(days, sd, this)
+// calendarBinding.days.layoutManager = GridLayoutManager(this, 7)
+// calendarBinding.days.adapter = adapter
+// }
+//
+// calendarBinding.left.setOnClickListener{ minusMonth() }
+// calendarBinding.right.setOnClickListener { plusMonth() }
+// calendarBinding.reset.setOnClickListener { resetDay() }
+// calendarBinding.confirm.setOnClickListener { }
+// }
+//
+// private fun observeCalendarData() {
+// lifecycleScope.launch {
+// calenderViewModel.init().collect { updatedDays ->
+// calenderViewModel.selectedDate.observe(this@SignUpActivity) { sd ->
+// Log.d("selectedData observe", "observeCalendarData() 시작")
+// adapter.update(updatedDays, sd)
+// calendarBinding.month.text = sd.month.value.toString()
+// calendarBinding.year.text = sd.year.toString()
+// }
+// }
+// }
+// }
+//
+// private fun minusMonth(){
+// lifecycleScope.launch {
+// calenderViewModel.minusSelectedDate().collect { updatedDays ->
+// calenderViewModel.selectedDate.observe(this@SignUpActivity) { sd ->
+// Log.d("selectedData observe", "left.setOnClickListener() 시작")
+// adapter.update(updatedDays, sd)
+// }
+// }
+// }
+// }
+//
+//
+// private fun resetDay() {
+// selectedDay = null
+// adapter.resetSelected()
+// }
+//
+// private fun plusMonth(){
+// lifecycleScope.launch {
+// calenderViewModel.plusSelectedDate().collect { updatedDays ->
+// calenderViewModel.selectedDate.observe(this@SignUpActivity) { sd ->
+// Log.d("selectedData observe", "right.setOnClickListener() 시작")
+// adapter.update(updatedDays, sd)
+// }
+// }
+// }
+// }
+//
+// override fun onItemClickListener(data: Int, selected: MutableList, position: Int, sd : LocalDate) {
+// adapter.resetSelected()
+// selected[position] = !selected[position]
+// selectedDay = sd
+// }
+
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt
new file mode 100644
index 00000000..fda55d68
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt
@@ -0,0 +1,57 @@
+package com.project.how.view.activity
+
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.viewModels
+import androidx.databinding.DataBindingUtil
+import androidx.lifecycle.lifecycleScope
+import com.project.how.R
+import com.project.how.databinding.ActivitySplashBinding
+import com.project.how.view_model.MemberViewModel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+class SplashActivity : AppCompatActivity() {
+ private lateinit var binding : ActivitySplashBinding
+ private val memberViewModel: MemberViewModel by viewModels()
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_splash)
+ binding.splash = this
+
+ lifecycleScope.launch {
+ memberViewModel.init(this@SplashActivity)
+ }
+
+ memberViewModel.tokensSaveLiveData.observe(this@SplashActivity){saveCheck->
+ Log.d("tokensSaveLiveData observe", "start\nsaveCheck : $saveCheck")
+ if (saveCheck){
+ getMemberInfo()
+ memberViewModel.memberInfoLiveData.observe(this){
+ Log.d("tokenSaveLiveData observe", "memberInfoLiveData\nname : ${it.name}\nphone : ${it.phone}\nbirth : ${it.birth}")
+ moveMain()
+ }
+ }else{
+ moveLogin()
+ }
+ }
+ }
+
+ private fun getMemberInfo() {
+ memberViewModel.tokensLiveData.value?.let { memberViewModel.getInfo(this, it.accessToken) }
+ }
+
+ private fun moveLogin(){
+ val intent = Intent(this@SplashActivity, LoginActivity::class.java)
+ startActivity(intent)
+ finish()
+ }
+
+ private fun moveMain(){
+ val intent = Intent(this@SplashActivity, MainActivity::class.java)
+ startActivity(intent)
+ finish()
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/CalendarFragment.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/CalendarFragment.kt
new file mode 100644
index 00000000..b0182f6c
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/CalendarFragment.kt
@@ -0,0 +1,35 @@
+package com.project.how.view.fragment
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.project.how.R
+import com.project.how.databinding.FragmentCalendarBinding
+
+class CalendarFragment : Fragment() {
+ private var _binding : FragmentCalendarBinding? = null
+ private val binding : FragmentCalendarBinding
+ get() = _binding!!
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_calendar, container, false)
+ binding.calendar = this
+ binding.lifecycleOwner = this
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/MypageFragment.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/MypageFragment.kt
new file mode 100644
index 00000000..094eb9f4
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/MypageFragment.kt
@@ -0,0 +1,36 @@
+package com.project.how.view.fragment
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.project.how.R
+import com.project.how.databinding.FragmentMypageBinding
+
+class MypageFragment : Fragment() {
+ private var _binding : FragmentMypageBinding? = null
+ private val binding : FragmentMypageBinding
+ get() = _binding!!
+ var name = "닉네임 예시"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_mypage, container, false)
+ binding.mypage = this
+ binding.lifecycleOwner = this
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/PictureFragment.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/PictureFragment.kt
new file mode 100644
index 00000000..f240796f
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/PictureFragment.kt
@@ -0,0 +1,35 @@
+package com.project.how.view.fragment
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.project.how.R
+import com.project.how.databinding.FragmentPictureBinding
+
+class PictureFragment : Fragment() {
+ private var _binding : FragmentPictureBinding? = null
+ private val binding : FragmentPictureBinding
+ get() = _binding!!
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_picture, container, false)
+ binding.picture = this
+ binding.lifecycleOwner = this
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/TicketFragment.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/TicketFragment.kt
new file mode 100644
index 00000000..a7d23145
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/TicketFragment.kt
@@ -0,0 +1,35 @@
+package com.project.how.view.fragment
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.project.how.R
+import com.project.how.databinding.FragmentTicketBinding
+
+class TicketFragment : Fragment() {
+ private var _binding : FragmentTicketBinding? = null
+ private val binding : FragmentTicketBinding
+ get() = _binding!!
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_ticket, container, false)
+ binding.ticket = this
+ binding.lifecycleOwner = this
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt
new file mode 100644
index 00000000..fd367f46
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt
@@ -0,0 +1,20 @@
+package com.project.how.view_model
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.ViewModel
+import com.project.how.model.CalendarRepository
+import kotlinx.coroutines.flow.Flow
+import java.time.LocalDate
+
+class CalendarViewModel : ViewModel() {
+ private var calendarRepository : CalendarRepository = CalendarRepository()
+ private val _selectedDate = calendarRepository.selectedDate
+ val selectedDate : LiveData
+ get() = _selectedDate
+
+ fun init() : Flow> = calendarRepository.init()
+
+ fun plusSelectedDate() : Flow> = calendarRepository.plusSelectedDate()
+
+ fun minusSelectedDate() : Flow> = calendarRepository.minusSelectedDate()
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/MemberViewModel.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/MemberViewModel.kt
new file mode 100644
index 00000000..aea4a5aa
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/MemberViewModel.kt
@@ -0,0 +1,190 @@
+package com.project.how.view_model
+
+import android.content.Context
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.google.firebase.auth.FirebaseUser
+import com.project.how.R
+import com.project.how.data_class.MemberInfo
+import com.project.how.data_class.dto.LoginRequest
+import com.project.how.data_class.Tokens
+import com.project.how.data_class.dto.AuthRecreateRequest
+import com.project.how.data_class.dto.EmptyResponse
+import com.project.how.data_class.dto.GetInfoResponse
+import com.project.how.data_class.dto.SignUpRequest
+import com.project.how.model.MemberRepository
+import com.project.how.network.client.MemberRetrofit
+import kotlinx.coroutines.launch
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.HttpException
+import retrofit2.Response
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
+import kotlin.coroutines.suspendCoroutine
+
+class MemberViewModel : ViewModel() {
+ private var memberRepository : MemberRepository = MemberRepository()
+ private val _currentUserLiveData = memberRepository.currentUserLiveData
+ private val _userLiveData = memberRepository.userLiveData
+ private val _tokensLiveData = memberRepository.tokensLiveData
+ private val _tokensSaveLiveData = memberRepository.tokensSaveLiveData
+ private val _infoLiveData = memberRepository.memberInfoLiveData
+ val currentUserLiveData : LiveData
+ get() = _currentUserLiveData
+ val userLiveData: LiveData
+ get() = _userLiveData
+ val tokensLiveData : LiveData
+ get() = _tokensLiveData
+ val tokensSaveLiveData : LiveData
+ get() = _tokensSaveLiveData
+ val memberInfoLiveData : LiveData
+ get() = _infoLiveData
+
+ private var authRecreateCount = 0
+
+ init {
+ Log.d("LoginViewModel init", "checkCurrentUser start")
+ memberRepository.checkCurrentUser()
+ Log.d("LoginViewModel init", "checkCurrentUser end")
+ authRecreateCount = 0
+ }
+
+ fun getUser(idToken: String) {
+ memberRepository.getUser(idToken)
+ }
+
+ suspend fun init(context: Context){
+ Log.d("init", "LoginViewModel init start")
+ memberRepository.init(context)
+ }
+
+ fun authRecreate(context: Context, arr: AuthRecreateRequest) {
+ MemberRetrofit.getApiService()!!
+ .authRecreate(arr)
+ .enqueue(object : Callback{
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ viewModelScope.launch {
+ val result = response.body().toString()
+ val accessToken = response.headers()[ACCESS_TOKEN]
+ val refreshToken = response.headers()[REFRESH_TOKEN]
+ Log.d(
+ "authRecreate success",
+ "code : ${response.code()}\nresult : ${result}\naccessToken : ${accessToken}\nrefreshToken : $refreshToken"
+ )
+ memberRepository.getTokens(context, accessToken!!, refreshToken!!)
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ Log.d("authRecreate onFailure", "${t.message}")
+ }
+
+ })
+ }
+
+ suspend fun getTokens(context : Context, lr: LoginRequest) : Int = suspendCoroutine{ continuation ->
+ Log.d("getTokens", "loginRequest : ${lr.uid}")
+ MemberRetrofit.getApiService()!!
+ .login(lr)
+ .enqueue(object : Callback{
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if (response.isSuccessful) {
+ viewModelScope.launch {
+ val result = response.body().toString()
+ val accessToken = response.headers()[ACCESS_TOKEN]
+ val refreshToken = response.headers()[REFRESH_TOKEN]
+ Log.d("getTokens success", "code : ${response.code()}\nresult : ${result}\naccessToken : ${accessToken}\nrefreshToken : $refreshToken")
+ memberRepository.getTokens(context, accessToken!!, refreshToken!!)
+ continuation.resume(response.code())
+ }
+ } else {
+ Log.d("getTokens response is not success", "code : ${response.code()}\nError : ${response.code()}")
+ continuation.resumeWithException(HttpException(response))
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ Log.d("getTokens onFailure", "${t.message}")
+ continuation.resume(ON_FAILURE)
+ }
+ })
+ }
+
+ fun getInfoSignUp(context : Context, accessToken : String, name : String, birth : String, phone : String){
+ val si = SignUpRequest(name, birth, phone)
+ MemberRetrofit.getApiService()!!
+ .signUp(context.getString(R.string.bearer_token, accessToken), si)
+ .enqueue(object : Callback{
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if (response.isSuccessful){
+ memberRepository.getInfo(MemberInfo(name, birth, phone))
+ Log.d("getInfoSignUp success", "code : ${response.code()}")
+ }else{
+ Log.d("getInfoSignUp response is not success", "code : ${response.code()}")
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ Log.d("getInfoSignUp onFailure", "${t.message}")
+ }
+ })
+ }
+
+ fun getInfo(context: Context, accessToken: String){
+ MemberRetrofit.getApiService()!!
+ .getInfo(context.resources.getString(R.string.bearer_token, accessToken))
+ .enqueue(object : Callback{
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if(response.isSuccessful){
+ val result = response.body()
+ if(result != null){
+ val name = result.name
+ val birth = result.birth
+ val phone = result.phone
+ memberRepository.getInfo(MemberInfo(name, birth, phone))
+ Log.d("getInfo success", "code : ${response.code()}\nname : ${name}\nbirth : ${birth}\nphone : $phone")
+ }else{
+ Log.d("getInfo result is null", "code : ${response.code()}\n message : ${response.message()}")
+ }
+ }else if(response.code() == BAD_REQUEST){
+ if (authRecreateCount<2){
+ tokensLiveData.value
+ ?.let { AuthRecreateRequest(it.refreshToken) }
+ ?.let { refreshToken->
+ authRecreate(context, refreshToken)
+ authRecreateCount++}
+ Log.d("getInfo Bad Request", "code : ${response.code()}\nExecute authRecreate $authRecreateCount")
+ }
+ }else{
+ Log.d("getInfo response is not success", "code : ${response.code()}")
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ Log.d("getInfo onFailure", "${t.message}")
+ }
+ })
+ }
+
+ companion object{
+ private const val ON_FAILURE = 99999
+ private const val ACCESS_TOKEN = "Access-Token"
+ private const val REFRESH_TOKEN = "Refresh-Token"
+ private const val BAD_REQUEST = 400
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/arrow_left.png b/android/HowAboutTrip/app/src/main/res/drawable/arrow_left.png
new file mode 100644
index 00000000..ee9a8bb1
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/arrow_left.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/arrow_right.png b/android/HowAboutTrip/app/src/main/res/drawable/arrow_right.png
new file mode 100644
index 00000000..e5c71245
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/arrow_right.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/black_oval_day_background.xml b/android/HowAboutTrip/app/src/main/res/drawable/black_oval_day_background.xml
new file mode 100644
index 00000000..01daec93
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/black_oval_day_background.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/black_oval_fab.xml b/android/HowAboutTrip/app/src/main/res/drawable/black_oval_fab.xml
new file mode 100644
index 00000000..9408d3c4
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/black_oval_fab.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/black_round_rectangle.xml b/android/HowAboutTrip/app/src/main/res/drawable/black_round_rectangle.xml
new file mode 100644
index 00000000..06d4a793
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/black_round_rectangle.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/google_login.png b/android/HowAboutTrip/app/src/main/res/drawable/google_login.png
new file mode 100644
index 00000000..27e88b87
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/google_login.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/gray_round_rectangle.xml b/android/HowAboutTrip/app/src/main/res/drawable/gray_round_rectangle.xml
new file mode 100644
index 00000000..76ef59ea
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/gray_round_rectangle.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/ic_launcher_background.xml b/android/HowAboutTrip/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..07d5da9c
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/ic_launcher_foreground.xml b/android/HowAboutTrip/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 00000000..2b068d11
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_ai_calendar.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_ai_calendar.png
new file mode 100644
index 00000000..5163f51c
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_ai_calendar.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_ai_calendar_size_fixed.xml b/android/HowAboutTrip/app/src/main/res/drawable/icon_ai_calendar_size_fixed.xml
new file mode 100644
index 00000000..bb7c30e1
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/icon_ai_calendar_size_fixed.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_alarm_new.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_alarm_new.png
new file mode 100644
index 00000000..a774821c
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_alarm_new.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_alarm_none.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_alarm_none.png
new file mode 100644
index 00000000..805347d6
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_alarm_none.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar.xml b/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar.xml
new file mode 100644
index 00000000..52667557
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar_bold.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar_bold.png
new file mode 100644
index 00000000..127f5634
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar_bold.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar_linear.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar_linear.png
new file mode 100644
index 00000000..d4ef6fdb
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_calendar_linear.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage.xml b/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage.xml
new file mode 100644
index 00000000..e875b68d
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage_bold.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage_bold.png
new file mode 100644
index 00000000..942837af
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage_bold.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage_linear.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage_linear.png
new file mode 100644
index 00000000..d8523603
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_mypage_linear.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_picture.xml b/android/HowAboutTrip/app/src/main/res/drawable/icon_picture.xml
new file mode 100644
index 00000000..3f9c43d6
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/icon_picture.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_picture_bold.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_picture_bold.png
new file mode 100644
index 00000000..190b3164
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_picture_bold.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_picture_linear.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_picture_linear.png
new file mode 100644
index 00000000..92a3b7c7
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_picture_linear.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket.xml b/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket.xml
new file mode 100644
index 00000000..80be4f3a
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket_bold.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket_bold.png
new file mode 100644
index 00000000..1e28c77d
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket_bold.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket_linear.png b/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket_linear.png
new file mode 100644
index 00000000..b105e752
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/icon_ticket_linear.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/logo.png b/android/HowAboutTrip/app/src/main/res/drawable/logo.png
new file mode 100644
index 00000000..62d14b26
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/drawable/logo.png differ
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/white_oval_day_background.xml b/android/HowAboutTrip/app/src/main/res/drawable/white_oval_day_background.xml
new file mode 100644
index 00000000..26913ec2
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/white_oval_day_background.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/white_rectangle_top_shadow.xml b/android/HowAboutTrip/app/src/main/res/drawable/white_rectangle_top_shadow.xml
new file mode 100644
index 00000000..eef7a6a7
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/white_rectangle_top_shadow.xml
@@ -0,0 +1,85 @@
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/drawable/white_round_bottom_sheet_backgroud.xml b/android/HowAboutTrip/app/src/main/res/drawable/white_round_bottom_sheet_backgroud.xml
new file mode 100644
index 00000000..bb7f3008
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/drawable/white_round_bottom_sheet_backgroud.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/font/blinker_semibold.ttf b/android/HowAboutTrip/app/src/main/res/font/blinker_semibold.ttf
new file mode 100644
index 00000000..408a9cf0
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/font/blinker_semibold.ttf differ
diff --git a/android/HowAboutTrip/app/src/main/res/font/bm_hanna.ttf b/android/HowAboutTrip/app/src/main/res/font/bm_hanna.ttf
new file mode 100644
index 00000000..cc8cf496
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/font/bm_hanna.ttf differ
diff --git a/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_bold.ttf b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_bold.ttf
new file mode 100644
index 00000000..6cf639eb
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_bold.ttf differ
diff --git a/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_medium.ttf b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_medium.ttf
new file mode 100644
index 00000000..5311c8a3
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_medium.ttf differ
diff --git a/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_regular.ttf b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_regular.ttf
new file mode 100644
index 00000000..1b14d324
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_regular.ttf differ
diff --git a/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_semi_bold.ttf b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_semi_bold.ttf
new file mode 100644
index 00000000..616bb095
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/font/noto_sans_kr_semi_bold.ttf differ
diff --git a/android/HowAboutTrip/app/src/main/res/layout/activity_login.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 00000000..038709f2
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..cc7b6ff2
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/activity_sign_up.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_sign_up.xml
new file mode 100644
index 00000000..68eea381
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/activity_sign_up.xml
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/activity_splash.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_splash.xml
new file mode 100644
index 00000000..d6b7f38c
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/activity_splash.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/calendar_bottom_sheet.xml b/android/HowAboutTrip/app/src/main/res/layout/calendar_bottom_sheet.xml
new file mode 100644
index 00000000..c21aebda
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/calendar_bottom_sheet.xml
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/calendar_day_item.xml b/android/HowAboutTrip/app/src/main/res/layout/calendar_day_item.xml
new file mode 100644
index 00000000..aa09fa0e
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/calendar_day_item.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/fragment_calendar.xml b/android/HowAboutTrip/app/src/main/res/layout/fragment_calendar.xml
new file mode 100644
index 00000000..615abe6f
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/fragment_calendar.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/fragment_mypage.xml b/android/HowAboutTrip/app/src/main/res/layout/fragment_mypage.xml
new file mode 100644
index 00000000..07702150
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/fragment_mypage.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/fragment_picture.xml b/android/HowAboutTrip/app/src/main/res/layout/fragment_picture.xml
new file mode 100644
index 00000000..2fc16171
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/fragment_picture.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/layout/fragment_ticket.xml b/android/HowAboutTrip/app/src/main/res/layout/fragment_ticket.xml
new file mode 100644
index 00000000..d40a6e23
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/layout/fragment_ticket.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/menu/main_bottom_navigation_menu.xml b/android/HowAboutTrip/app/src/main/res/menu/main_bottom_navigation_menu.xml
new file mode 100644
index 00000000..4148ef88
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/menu/main_bottom_navigation_menu.xml
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/android/HowAboutTrip/app/src/main/res/mipmap-anydpi/ic_launcher.xml
new file mode 100644
index 00000000..6f3b755b
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/mipmap-anydpi/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/android/HowAboutTrip/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
new file mode 100644
index 00000000..6f3b755b
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/HowAboutTrip/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/android/HowAboutTrip/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/android/HowAboutTrip/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/android/HowAboutTrip/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/HowAboutTrip/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/android/HowAboutTrip/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/HowAboutTrip/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/android/HowAboutTrip/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/android/HowAboutTrip/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/android/HowAboutTrip/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/android/HowAboutTrip/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/android/HowAboutTrip/app/src/main/res/raw/login_animation.json b/android/HowAboutTrip/app/src/main/res/raw/login_animation.json
new file mode 100644
index 00000000..5e60cb5b
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/raw/login_animation.json
@@ -0,0 +1 @@
+{"v":"5.6.9","fr":30,"ip":0,"op":120,"w":1920,"h":1080,"nm":"Scene - 3","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":2,"ty":4,"nm":"F_hand_1","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.792],"y":[-0.042]},"o":{"x":[0.622],"y":[0]},"t":0,"s":[-41]},{"i":{"x":[0.379],"y":[1]},"o":{"x":[0.174],"y":[0.325]},"t":12.409,"s":[-31.005]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":26.728,"s":[0]},{"i":{"x":[0.797],"y":[-0.791]},"o":{"x":[0.615],"y":[0]},"t":70.136,"s":[0]},{"i":{"x":[0.359],"y":[1]},"o":{"x":[0.17],"y":[0.298]},"t":80.636,"s":[-5.538]},{"t":94,"s":[-41]}],"ix":10},"p":{"a":0,"k":[455.912,193.405,0],"ix":2},"a":{"a":0,"k":[305.733,61.809,0],"ix":1},"s":{"a":0,"k":[520,520,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.628,-2.676],[-5.109,-7.881],[-0.02,2.767]],"o":[[-3.225,1.302],[5.109,7.879],[0.022,-2.768]],"v":[[-8.81,-17.279],[-4.319,12.076],[12.013,15.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.944999964097,0.957000014361,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[313.494,77.481],"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":"Group 101","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"F_hand_2","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.769],"y":[0.241]},"o":{"x":[0.461],"y":[0]},"t":0.954,"s":[11]},{"i":{"x":[0.6],"y":[0.822]},"o":{"x":[0.44],"y":[0.298]},"t":8.591,"s":[4.26]},{"i":{"x":[0.484],"y":[1]},"o":{"x":[0.198],"y":[-0.456]},"t":16.228,"s":[-28.468]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27.682,"s":[-19]},{"i":{"x":[0.685],"y":[0.749]},"o":{"x":[0.671],"y":[0]},"t":71.091,"s":[-19]},{"i":{"x":[0.482],"y":[1]},"o":{"x":[0.195],"y":[-0.797]},"t":84.454,"s":[16.441]},{"t":94.9541015625,"s":[11]}],"ix":10},"p":{"a":0,"k":[325.302,93.385,0],"ix":2},"a":{"a":0,"k":[557.672,357.602,0],"ix":1},"s":{"a":0,"k":[19.231,19.231,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.884,0],[0.017,0.002],[-0.01,0.069],[-0.069,-0.014],[-2.946,0.43],[-0.009,-0.068],[0.068,-0.011]],"o":[[-1.588,0],[-0.068,-0.011],[0.01,-0.067],[0.027,0.004],[0.072,-0.01],[0.011,0.068],[-1.068,0.155]],"v":[[-0.131,0.231],[-2.854,0.068],[-2.959,-0.075],[-2.818,-0.179],[2.817,-0.221],[2.958,-0.115],[2.853,0.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[301.769,100.383],"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":"Group 95","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[435.296,394.012],"ix":2},"a":{"a":0,"k":[301.768,100.387],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 95","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.005,0],[0.008,0.063],[-0.069,0.009],[-0.745,0.566],[-0.043,-0.057],[0.054,-0.042],[0.083,-0.01]],"o":[[-0.062,0],[-0.008,-0.069],[0.019,-0.003],[0.055,-0.043],[0.041,0.055],[-0.799,0.607],[-0.005,0.001]],"v":[[-1.389,0.553],[-1.513,0.444],[-1.404,0.304],[1.304,-0.51],[1.48,-0.486],[1.456,-0.311],[-1.374,0.552]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[299.974,99.29],"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":"Group 96","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[425.94,388.349],"ix":2},"a":{"a":0,"k":[299.969,99.298],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 96","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.039,0],[0.022,0.015],[-0.039,0.056],[-1.767,0.632],[-0.023,-0.066],[0.065,-0.023],[0.015,-0.022]],"o":[[-0.025,0],[-0.056,-0.04],[0.067,-0.095],[0.062,-0.023],[0.024,0.065],[-1.692,0.604],[-0.025,0.035]],"v":[[-1.675,1.589],[-1.747,1.568],[-1.778,1.394],[1.634,-1.566],[1.793,-1.49],[1.718,-1.33],[-1.572,1.536]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[299.991,97.702],"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":"Group 97","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[426.053,380.093],"ix":2},"a":{"a":0,"k":[299.991,97.71],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 97","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.053,0],[0.013,0.004],[-0.021,0.066],[-1.876,1.155],[-0.035,-0.059],[0.059,-0.036],[0.013,-0.04]],"o":[[-0.013,0],[-0.065,-0.021],[0.055,-0.166],[0.06,-0.036],[0.036,0.058],[-1.798,1.107],[-0.017,0.053]],"v":[[-1.587,2.722],[-1.626,2.717],[-1.707,2.559],[1.52,-2.687],[1.691,-2.645],[1.65,-2.473],[-1.469,2.636]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[299.597,95.759],"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":"Group 98","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[424,369.991],"ix":2},"a":{"a":0,"k":[299.596,95.768],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 98","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.016,1.674],[-4.814,2.018],[0.805,-1.548],[9.112,5.318]],"o":[[-0.071,-7.786],[4.814,-2.019],[-0.806,1.547],[0,0]],"v":[[-14.231,2.898],[3.784,-9.759],[13.497,-0.812],[-12.848,6.46]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000020027,0.944999992847,0.957000017166,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[311.729,94.457],"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":"Group 100","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[485.38,357.602],"ix":2},"a":{"a":0,"k":[311.4,93.385],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 100","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"F_arm","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.792],"y":[3.888]},"o":{"x":[0.622],"y":[0]},"t":1.909,"s":[25]},{"i":{"x":[0.5],"y":[0.756]},"o":{"x":[0.237],"y":[0.142]},"t":14.318,"s":[27.198]},{"i":{"x":[0.574],"y":[1]},"o":{"x":[0.253],"y":[-12.833]},"t":21,"s":[-0.302]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":28.637,"s":[0]},{"i":{"x":[0.806],"y":[1.229]},"o":{"x":[0.576],"y":[0]},"t":72.045,"s":[0]},{"i":{"x":[0.502],"y":[0.859]},"o":{"x":[0.273],"y":[0.083]},"t":81.591,"s":[-21.76]},{"i":{"x":[0.538],"y":[1]},"o":{"x":[0.227],"y":[-1.132]},"t":87.318,"s":[29.343]},{"t":95.9091796875,"s":[25]}],"ix":10},"p":{"a":0,"k":[428.089,381.24,0],"ix":2},"a":{"a":0,"k":[428.089,381.24,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.05,0],[0.015,0.006],[-0.026,0.064],[-1.168,0.91],[-0.043,-0.054],[0.055,-0.042],[0.009,-0.022]],"o":[[-0.016,0],[-0.064,-0.025],[0.036,-0.092],[0.053,-0.043],[0.042,0.055],[-1.114,0.868],[-0.019,0.049]],"v":[[-1.013,1.683],[-1.059,1.674],[-1.129,1.512],[0.938,-1.64],[1.113,-1.619],[1.091,-1.443],[-0.897,1.604]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[292.173,103.529],"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":"Group 102","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[385.402,409.892],"ix":2},"a":{"a":0,"k":[292.173,103.441],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 102","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.052,0],[0.014,0.005],[-0.022,0.065],[-1.577,1.613],[-0.049,-0.049],[0.048,-0.05],[0.006,-0.02]],"o":[[-0.013,0],[-0.065,-0.021],[0.008,-0.023],[0.049,-0.048],[0.049,0.048],[-1.537,1.571],[-0.018,0.053]],"v":[[-1.143,2.01],[-1.184,2.004],[-1.263,1.847],[1.057,-1.96],[1.234,-1.961],[1.236,-1.784],[-1.025,1.924]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[291.396,103.154],"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":"Group 103","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[381.365,408.437],"ix":2},"a":{"a":0,"k":[291.397,103.161],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 103","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.048,0],[0.016,0.008],[-0.027,0.064],[-0.04,0.043],[-0.05,-0.048],[0.047,-0.051],[0.134,-0.307]],"o":[[-0.017,0],[-0.063,-0.027],[0.179,-0.409],[0.048,-0.047],[0.05,0.047],[-0.266,0.283],[-0.021,0.047]],"v":[[-0.569,0.846],[-0.619,0.836],[-0.684,0.672],[0.483,-0.793],[0.66,-0.798],[0.665,-0.621],[-0.454,0.772]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[291.098,101.531],"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":"Group 104","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[379.817,400.001],"ix":2},"a":{"a":0,"k":[291.099,101.539],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 104","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.269,0.469],[-0.19,0.456],[-0.002,0.006],[-0.212,0.482],[-0.967,0.637],[-0.907,0.207],[-0.721,0.328],[-2.418,1.528],[0.264,0.192],[1.256,0.918],[0.168,-0.111],[0.061,-0.063],[3.018,-1.062],[1.365,-1.851],[-0.383,0.519],[-0.914,0.54],[-0.009,-0.029],[0.505,-1.412]],"o":[[0.147,0.361],[0.002,-0.004],[0.086,0.413],[0.439,-0.996],[0.804,-0.529],[0.777,-0.177],[2.605,-1.186],[0.255,-0.163],[-1.257,-0.919],[-0.205,-0.15],[-0.069,0.024],[-2.263,2.282],[-2.151,0.758],[-0.38,0.514],[0.756,-1.024],[0.006,0.03],[-1.028,1.08],[-0.202,0.567]],"v":[[-7.156,5.588],[-6.256,5.65],[-6.248,5.635],[-5.325,5.779],[-3.476,3.073],[-0.667,2.285],[1.507,1.56],[9.079,-2.562],[9.135,-3.356],[5.365,-6.111],[4.767,-6.119],[4.57,-5.994],[-3.844,-0.843],[-9.019,2.867],[-8.268,3.527],[-5.75,1.284],[-5.737,1.372],[-8.005,5.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917999982834,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 4')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[297.408,99.452],"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":"Group 105","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[413.089,388.74],"ix":2},"a":{"a":0,"k":[297.498,99.373],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 105","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Backpack_front","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-3.812,"ix":10},"p":{"a":0,"k":[495.657,240.788,0],"ix":2},"a":{"a":0,"k":[137.842,71.746,0],"ix":1},"s":{"a":0,"k":[-515,515,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.739,4.767],[-1.363,-1.371],[4.375,-4.377],[5.244,-1.252],[-1.88,0.448],[-4.014,6.689]],"o":[[-1.363,-1.371],[4.87,4.899],[-3.911,3.913],[-1.877,0.449],[7.233,-1.727],[3.318,-5.529]],"v":[[7.841,-13.998],[5.719,-11.877],[3.943,5.092],[-10.703,12.027],[-9.906,14.92],[8.977,3.52]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.246999987434,0.258999992819,0.380000005984,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[138.01,71.483],"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":"Group 72","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":3,"nm":"NULL CONTROL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[369.84,456.109,0],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[95,95,100],"ix":6}},"ao":0,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Body","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.792],"y":[1.308]},"o":{"x":[0.622],"y":[0]},"t":0,"s":[-8]},{"i":{"x":[0.379],"y":[1]},"o":{"x":[0.174],"y":[0.072]},"t":12,"s":[-13.903]},{"i":{"x":[0.47],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":26.728,"s":[12]},{"i":{"x":[0.3],"y":[1]},"o":{"x":[0.526],"y":[0]},"t":71.091,"s":[12]},{"t":94.9541015625,"s":[-8]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[68.691,-56.785,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.468,"y":0.468},"o":{"x":0.47,"y":0.47},"t":27,"s":[121.691,-56.785,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[121.691,-56.785,0],"to":[0,0,0],"ti":[0,0,0]},{"t":95,"s":[68.691,-56.785,0]}],"ix":2},"a":{"a":0,"k":[449.149,359.824,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[10.296,6.959],[0.731,-11.342],[0,0],[-17.135,4.666]],"o":[[0,0],[-0.732,11.343],[0,0],[0,0]],"v":[[-2.682,-21.688],[-6.98,1.607],[-18.142,16.305],[18.142,17.022]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000002623,0.513999998569,0.885999977589,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 6')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[307.366,81.891],"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":"Group 106","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[464.405,290.649],"ix":2},"a":{"a":0,"k":[307.366,80.509],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 106","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-17.355,5.01],[9.024,2.914],[2.236,-0.507],[0.334,-0.161],[0.326,-3.88],[1.074,-3.578],[0,0]],"o":[[0,0],[-2.752,-0.889],[-0.327,0.074],[-2.682,1.292],[-0.592,7.043],[-1.074,3.579],[0,0]],"v":[[20.691,19.263],[0.578,-21.892],[-7.03,-22.464],[-9.028,-21.774],[-13.857,-14.014],[-16.344,7.098],[-20.691,17.296]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 8')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[304.817,79.649],"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":"Group 117","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[451.149,281.842],"ix":2},"a":{"a":0,"k":[304.817,78.816],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 117","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Legs","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51.309,176.785,0],"ix":2},"a":{"a":0,"k":[466.532,593.394,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0.015,0],[0.022,0.08],[-0.096,0.026],[-5,5.777],[-0.075,-0.063],[0.065,-0.075],[0.139,-0.038]],"o":[[-0.079,0],[-0.026,-0.096],[0.139,-0.039],[0.065,-0.075],[0.075,0.066],[-5.071,5.861],[-0.016,0.004]],"v":[[-9.505,5.042],[-9.679,4.909],[-9.553,4.688],[9.368,-4.96],[9.622,-4.979],[9.64,-4.724],[-9.457,5.035]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0.012,-0.01],[0.068,0.048],[-0.057,0.081],[-0.166,7.638],[-0.098,-0.001],[0.002,-0.099],[0.083,-0.118]],"o":[[-0.061,0.05],[-0.081,-0.057],[0.082,-0.119],[0.002,-0.099],[0.1,0.003],[-0.167,7.748],[-0.01,0.013]],"v":[[-1.903,2.374],[-2.122,2.382],[-2.166,2.132],[6.252,-17.368],[6.436,-17.544],[6.612,-17.359],[-1.87,2.338]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0.012,-0.01],[0.068,0.048],[-0.057,0.081],[-0.166,7.638],[-0.098,-0.001],[0.002,-0.099],[0.083,-0.118]],"o":[[-0.061,0.05],[-0.081,-0.057],[0.082,-0.119],[0.002,-0.099],[0.1,0.003],[-0.167,7.748],[-0.01,0.013]],"v":[[-1.903,2.374],[-2.122,2.382],[-2.166,2.132],[6.252,-17.368],[6.436,-17.544],[6.612,-17.359],[-1.87,2.338]],"c":true}]},{"t":95,"s":[{"i":[[0.015,0],[0.022,0.08],[-0.096,0.026],[-5,5.777],[-0.075,-0.063],[0.065,-0.075],[0.139,-0.038]],"o":[[-0.079,0],[-0.026,-0.096],[0.139,-0.039],[0.065,-0.075],[0.075,0.066],[-5.071,5.861],[-0.016,0.004]],"v":[[-9.505,5.042],[-9.679,4.909],[-9.553,4.688],[9.368,-4.96],[9.622,-4.979],[9.64,-4.724],[-9.457,5.035]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[321.386,159.659],"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":"Group 87","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[537.304,702.28],"ix":2},"a":{"a":0,"k":[321.385,159.669],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 87","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0.012,0],[0.017,0.085],[-0.097,0.02],[-7.889,5.404],[-0.057,-0.084],[0.082,-0.055],[0.122,-0.025]],"o":[[-0.084,0],[-0.021,-0.097],[0.121,-0.026],[0.082,-0.057],[0.056,0.082],[-7.949,5.447],[-0.013,0.002]],"v":[[-10.092,4.205],[-10.268,4.062],[-10.129,3.848],[9.982,-4.148],[10.233,-4.102],[10.186,-3.852],[-10.055,4.201]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0.009,-0.008],[0.067,0.055],[-0.062,0.077],[-2.629,9.194],[-0.098,-0.028],[0.027,-0.095],[0.078,-0.097]],"o":[[-0.065,0.054],[-0.078,-0.061],[0.077,-0.097],[0.027,-0.096],[0.095,0.027],[-2.648,9.265],[-0.009,0.01]],"v":[[0.125,-1.385],[-0.102,-1.384],[-0.131,-1.636],[10.257,-20.623],[10.479,-20.748],[10.602,-20.525],[0.151,-1.412]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0.009,-0.008],[0.067,0.055],[-0.062,0.077],[-2.629,9.194],[-0.098,-0.028],[0.027,-0.095],[0.078,-0.097]],"o":[[-0.065,0.054],[-0.078,-0.061],[0.077,-0.097],[0.027,-0.096],[0.095,0.027],[-2.648,9.265],[-0.009,0.01]],"v":[[0.125,-1.385],[-0.102,-1.384],[-0.131,-1.636],[10.257,-20.623],[10.479,-20.748],[10.602,-20.525],[0.151,-1.412]],"c":true}]},{"t":95,"s":[{"i":[[0.012,0],[0.017,0.085],[-0.097,0.02],[-7.889,5.404],[-0.057,-0.084],[0.082,-0.055],[0.122,-0.025]],"o":[[-0.084,0],[-0.021,-0.097],[0.121,-0.026],[0.082,-0.057],[0.056,0.082],[-7.949,5.447],[-0.013,0.002]],"v":[[-10.092,4.205],[-10.268,4.062],[-10.129,3.848],[9.982,-4.148],[10.233,-4.102],[10.186,-3.852],[-10.055,4.201]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[324.721,165.585],"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":"Group 88","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[554.628,733.107],"ix":2},"a":{"a":0,"k":[324.717,165.598],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 88","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0.047,0],[0.035,0.034],[3.909,0.39],[0.035,-0.004],[0.01,0.098],[-0.098,0.01],[-4.287,-0.427],[-3.445,-3.375],[0.069,-0.071]],"o":[[-0.045,0],[-3.37,-3.3],[-4.25,-0.425],[-0.106,-0.004],[-0.011,-0.1],[0.036,-0.003],[3.969,0.397],[0.071,0.07],[-0.036,0.036]],"v":[[10.281,2.844],[10.155,2.793],[-2.49,-2.056],[-10.271,-2.112],[-10.469,-2.272],[-10.31,-2.471],[-2.461,-2.417],[10.407,2.535],[10.41,2.79]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0.047,-0.004],[0.037,0.031],[3.928,0.075],[0.035,-0.007],[0.018,0.097],[-0.097,0.018],[-4.307,-0.082],[-3.706,-3.086],[0.063,-0.076]],"o":[[-0.045,0.004],[-3.625,-3.018],[-4.27,-0.081],[-0.106,0.005],[-0.019,-0.099],[0.036,-0.006],[3.988,0.076],[0.076,0.064],[-0.033,0.039]],"v":[[10.035,3.839],[9.905,3.797],[-3.089,-0.017],[-10.85,0.554],[-11.06,0.411],[-10.917,0.199],[-3.09,-0.379],[10.135,3.52],[10.159,3.774]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0.047,-0.004],[0.037,0.031],[3.928,0.075],[0.035,-0.007],[0.018,0.097],[-0.097,0.018],[-4.307,-0.082],[-3.706,-3.086],[0.063,-0.076]],"o":[[-0.045,0.004],[-3.625,-3.018],[-4.27,-0.081],[-0.106,0.005],[-0.019,-0.099],[0.036,-0.006],[3.988,0.076],[0.076,0.064],[-0.033,0.039]],"v":[[10.035,3.839],[9.905,3.797],[-3.089,-0.017],[-10.85,0.554],[-11.06,0.411],[-10.917,0.199],[-3.09,-0.379],[10.135,3.52],[10.159,3.774]],"c":true}]},{"t":95,"s":[{"i":[[0.047,0],[0.035,0.034],[3.909,0.39],[0.035,-0.004],[0.01,0.098],[-0.098,0.01],[-4.287,-0.427],[-3.445,-3.375],[0.069,-0.071]],"o":[[-0.045,0],[-3.37,-3.3],[-4.25,-0.425],[-0.106,-0.004],[-0.011,-0.1],[0.036,-0.003],[3.969,0.397],[0.071,0.07],[-0.036,0.036]],"v":[[10.281,2.844],[10.155,2.793],[-2.49,-2.056],[-10.271,-2.112],[-10.469,-2.272],[-10.31,-2.471],[-2.461,-2.417],[10.407,2.535],[10.41,2.79]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[293.104,162.888],"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":"Group 89","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[390.22,719.592],"ix":2},"a":{"a":0,"k":[293.1,162.998],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 89","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0.046,0],[0.035,0.035],[0.124,-0.024],[0.018,0.097],[-0.097,0.018],[-8.167,-8.211],[0.071,-0.07]],"o":[[-0.046,0],[-8.03,-8.072],[-0.097,0.023],[-0.019,-0.098],[0.127,-0.024],[0.07,0.071],[-0.035,0.035]],"v":[[10.374,4.259],[10.245,4.206],[-10.342,-1.548],[-10.553,-1.69],[-10.411,-1.901],[10.501,3.952],[10.5,4.207]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0.046,-0.004],[0.038,0.032],[0.122,-0.034],[0.026,0.095],[-0.095,0.026],[-8.802,-7.526],[0.065,-0.076]],"o":[[-0.046,0.004],[-8.654,-7.399],[-0.095,0.031],[-0.027,-0.096],[0.125,-0.034],[0.076,0.065],[-0.032,0.038]],"v":[[10.246,5.304],[10.114,5.26],[-10.87,1.184],[-11.092,1.059],[-10.967,0.837],[10.349,4.986],[10.368,5.241]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0.046,-0.004],[0.038,0.032],[0.122,-0.034],[0.026,0.095],[-0.095,0.026],[-8.802,-7.526],[0.065,-0.076]],"o":[[-0.046,0.004],[-8.654,-7.399],[-0.095,0.031],[-0.027,-0.096],[0.125,-0.034],[0.076,0.065],[-0.032,0.038]],"v":[[10.246,5.304],[10.114,5.26],[-10.87,1.184],[-11.092,1.059],[-10.967,0.837],[10.349,4.986],[10.368,5.241]],"c":true}]},{"t":95,"s":[{"i":[[0.046,0],[0.035,0.035],[0.124,-0.024],[0.018,0.097],[-0.097,0.018],[-8.167,-8.211],[0.071,-0.07]],"o":[[-0.046,0],[-8.03,-8.072],[-0.097,0.023],[-0.019,-0.098],[0.127,-0.024],[0.07,0.071],[-0.035,0.035]],"v":[[10.374,4.259],[10.245,4.206],[-10.342,-1.548],[-10.553,-1.69],[-10.411,-1.901],[10.501,3.952],[10.5,4.207]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[291.833,167.612],"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":"Group 90","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[383.625,748.872],"ix":2},"a":{"a":0,"k":[291.832,168.629],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 90","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.887,-3.219],[-1.75,2.278]],"o":[[-1.098,1.873],[1.124,-1.461]],"v":[[-8.123,-1.565],[8.097,2.506]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.231000006199,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 9')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[282.892,186.975],"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":"Group 118","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[337.08,845.875],"ix":2},"a":{"a":0,"k":[282.881,187.284],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 118","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.034,-0.619],[0,0],[-1.195,1.13],[-0.019,0.325],[0,0],[0,0]],"o":[[0,0],[0,0],[1.123,-1.057],[0.012,-0.018],[-2.443,-2.776],[-2.009,1.434]],"v":[[-8.228,-1.986],[-2.984,0.682],[6.845,2.82],[8.216,-1.143],[8.224,-1.174],[-0.215,-3.663]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000020027,0.944999992847,0.957000017166,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[284.142,186.668],"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":"Group 119","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[343.631,841.075],"ix":2},"a":{"a":0,"k":[284.141,186.361],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 119","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.882,2.313],[-0.32,1.809],[0,0],[-0.533,2.348],[1.604,0.16],[0.761,-0.779],[0.154,-0.106],[2.034,-0.619],[0.19,-0.347]],"o":[[0.775,-0.969],[0.011,-0.017],[0.244,-1.406],[-3.589,-1.394],[-0.568,1.819],[-0.12,0.128],[-2.008,1.433],[-0.554,0.147],[-0.989,1.76]],"v":[[6.866,5.905],[8.238,1.944],[8.246,1.913],[10.345,-6.549],[3.12,-8.219],[0.215,-0.926],[-0.194,-0.577],[-8.207,1.1],[-9.356,1.827]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999974728,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 10')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[284.121,183.582],"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":"Group 120","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[345.982,822.258],"ix":2},"a":{"a":0,"k":[284.593,182.742],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 120","np":1,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.043,-1.212],[-1.087,2.568],[5.741,1.431]],"o":[[0.09,2.568],[0.792,-1.874],[-6.884,-1.716]],"v":[[-10.285,-2.369],[9.536,2.86],[1.108,-3.712]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000003576,0.090000003576,0.11400000006,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 11')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[290.299,179.732],"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":"Group 121","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[373.997,804.376],"ix":2},"a":{"a":0,"k":[289.98,179.303],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 121","np":1,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[-5.944,-7.796],[-2.14,7.763],[-2.483,6.991],[-2.061,7.547],[2.74,5.953],[0.304,-0.119],[4.908,-5.236],[0.72,-3.567],[1.114,-5.026],[3.45,-9.558],[0.177,-9.283]],"o":[[0.249,0.549],[1.973,-7.162],[2.619,-7.373],[1.671,-6.116],[-0.176,-0.385],[-5.03,-4.089],[-2.608,2.781],[-1.019,5.046],[-2.204,9.935],[-3.126,8.66],[4.158,-0.972]],"v":[[-1.566,45.583],[3.806,21.418],[11.699,0.588],[18.684,-21.863],[18.648,-40.26],[17.806,-40.585],[0.308,-40.896],[-3.416,-30.497],[-6.536,-15.372],[-15.288,13.626],[-21.388,40.355]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[-5.944,-7.796],[-0.777,8.015],[-1.249,7.313],[-0.739,7.788],[3.719,5.396],[0.279,-0.169],[3.94,-5.998],[0.099,-3.638],[0.238,-5.143],[1.762,-10.008],[0.177,-9.283]],"o":[[0.249,0.549],[0.717,-7.394],[1.318,-7.713],[0.599,-6.312],[-0.239,-0.349],[-5.656,-3.167],[-2.093,3.187],[-0.14,5.146],[-0.47,10.166],[-1.597,9.067],[4.158,-0.972]],"v":[[-1.566,45.583],[2.922,22.486],[7.131,0.612],[10.167,-22.704],[6.981,-40.823],[6.096,-40.999],[-11.197,-38.308],[-13.085,-27.425],[-13.568,-11.989],[-17.225,18.079],[-21.388,40.355]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[-5.944,-7.796],[-0.777,8.015],[-1.249,7.313],[-0.739,7.788],[3.719,5.396],[0.279,-0.169],[3.94,-5.998],[0.099,-3.638],[0.238,-5.143],[1.762,-10.008],[0.177,-9.283]],"o":[[0.249,0.549],[0.717,-7.394],[1.318,-7.713],[0.599,-6.312],[-0.239,-0.349],[-5.656,-3.167],[-2.093,3.187],[-0.14,5.146],[-0.47,10.166],[-1.597,9.067],[4.158,-0.972]],"v":[[-1.566,45.583],[2.922,22.486],[7.131,0.612],[10.167,-22.704],[6.981,-40.823],[6.096,-40.999],[-11.197,-38.308],[-13.085,-27.425],[-13.568,-11.989],[-17.225,18.079],[-21.388,40.355]],"c":true}]},{"t":95,"s":[{"i":[[-5.944,-7.796],[-2.14,7.763],[-2.483,6.991],[-2.061,7.547],[2.74,5.953],[0.304,-0.119],[4.908,-5.236],[0.72,-3.567],[1.114,-5.026],[3.45,-9.558],[0.177,-9.283]],"o":[[0.249,0.549],[1.973,-7.162],[2.619,-7.373],[1.671,-6.116],[-0.176,-0.385],[-5.03,-4.089],[-2.608,2.781],[-1.019,5.046],[-2.204,9.935],[-3.126,8.66],[4.158,-0.972]],"v":[[-1.566,45.583],[3.806,21.418],[11.699,0.588],[18.684,-21.863],[18.648,-40.26],[17.806,-40.585],[0.308,-40.896],[-3.416,-30.497],[-6.536,-15.372],[-15.288,13.626],[-21.388,40.355]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[301.401,137.007],"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":"Group 122","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[430.663,587.889],"ix":2},"a":{"a":0,"k":[300.878,137.671],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 122","np":1,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[-2.23,6]],"o":[[0,0],[0,0],[0,0],[2.23,-6]],"v":[[5.77,-16.969],[-5.77,10.189],[-3.042,16.969],[0,4.355]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0,0],[0,0],[0,0],[-1.169,6.293]],"o":[[0,0],[0,0],[0,0],[1.169,-6.293]],"v":[[-1.255,-17.518],[-7.973,11.215],[-2.125,14.543],[-3.287,4.479]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0,0],[0,0],[0,0],[-1.169,6.293]],"o":[[0,0],[0,0],[0,0],[1.169,-6.293]],"v":[[-1.255,-17.518],[-7.973,11.215],[-2.125,14.543],[-3.287,4.479]],"c":true}]},{"t":95,"s":[{"i":[[0,0],[0,0],[0,0],[-2.23,6]],"o":[[0,0],[0,0],[0,0],[2.23,-6]],"v":[[5.77,-16.969],[-5.77,10.189],[-3.042,16.969],[0,4.355]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.231000006199,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 9')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[311.881,140.614],"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":"Group 123","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[487.882,603.195],"ix":2},"a":{"a":0,"k":[311.881,140.614],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 123","np":1,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[3.479,-16.634],[-3.479,8.643],[-1.962,16.634]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-6.773,-13.622],[-9.299,12.473],[-6.436,20.086]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-6.773,-13.622],[-9.299,12.473],[-6.436,20.086]],"c":true}]},{"t":95,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[3.479,-16.634],[-3.479,8.643],[-1.962,16.634]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.231000006199,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 9')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[295.149,119.795],"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":"Group 124","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[400.876,494.934],"ix":2},"a":{"a":0,"k":[295.149,119.795],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 124","np":1,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0,0],[0.25,-10.125],[0,0],[0.82,0.981],[2.7,5.924],[0,0]],"o":[[0,0],[-0.25,10.125],[0,0],[-0.821,-0.981],[-2.7,-5.926],[0,0]],"v":[[1.212,-29.646],[0.474,-0.012],[9.401,28.167],[5.063,28.665],[-3.63,15.08],[-9.401,1.363]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0,0],[-6.966,-7.352],[0,0],[1.235,0.332],[5.858,2.841],[0,0]],"o":[[0,0],[6.966,7.352],[0,0],[-1.235,-0.332],[-5.859,-2.842],[0,0]],"v":[[-6.459,-29.979],[0.246,-1.171],[21.891,15.014],[18.895,18.122],[3.857,12.453],[-11.603,2.389]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0,0],[-6.966,-7.352],[0,0],[1.235,0.332],[5.858,2.841],[0,0]],"o":[[0,0],[6.966,7.352],[0,0],[-1.235,-0.332],[-5.859,-2.842],[0,0]],"v":[[-6.459,-29.979],[0.246,-1.171],[21.891,15.014],[18.895,18.122],[3.857,12.453],[-11.603,2.389]],"c":true}]},{"t":95,"s":[{"i":[[0,0],[0.25,-10.125],[0,0],[0.82,0.981],[2.7,5.924],[0,0]],"o":[[0,0],[-0.25,10.125],[0,0],[-0.821,-0.981],[-2.7,-5.926],[0,0]],"v":[[1.212,-29.646],[0.474,-0.012],[9.401,28.167],[5.063,28.665],[-3.63,15.08],[-9.401,1.363]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203999996185,0.216000005603,0.317999988794,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 12')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[315.512,149.441],"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":"Group 125","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[506.762,647.415],"ix":2},"a":{"a":0,"k":[315.512,149.118],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 125","np":1,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[3.693,-1.903],[-0.043,-0.071],[0.987,2.706],[0,0],[0.071,0.157],[1.86,-2.032]],"o":[[0.014,0.086],[1.03,1.903],[0,0],[-0.028,-0.157],[-0.344,0.974],[-2.405,2.634]],"v":[[-6.455,4.967],[-6.369,5.182],[5.468,-6.598],[5.468,-6.612],[5.311,-7.085],[2.276,-2.219]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[1.933,-3.677],[-0.074,-0.037],[2.361,1.65],[0,0],[0.148,0.088],[0.354,-2.732]],"o":[[0.061,0.062],[1.935,0.968],[0,0],[-0.113,-0.113],[0.277,0.995],[-0.459,3.537]],"v":[[12.508,-12.418],[12.702,-12.291],[15.638,-28.731],[15.63,-28.742],[15.23,-29.04],[15.536,-23.313]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[1.933,-3.677],[-0.074,-0.037],[2.361,1.65],[0,0],[0.148,0.088],[0.354,-2.732]],"o":[[0.061,0.062],[1.935,0.968],[0,0],[-0.113,-0.113],[0.277,0.995],[-0.459,3.537]],"v":[[12.508,-12.418],[12.702,-12.291],[15.638,-28.731],[15.63,-28.742],[15.23,-29.04],[15.536,-23.313]],"c":true}]},{"t":95,"s":[{"i":[[3.693,-1.903],[-0.043,-0.071],[0.987,2.706],[0,0],[0.071,0.157],[1.86,-2.032]],"o":[[0.014,0.086],[1.03,1.903],[0,0],[-0.028,-0.157],[-0.344,0.974],[-2.405,2.634]],"v":[[-6.455,4.967],[-6.369,5.182],[5.468,-6.598],[5.468,-6.612],[5.311,-7.085],[2.276,-2.219]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.231000006199,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 9')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[335.31,184.693],"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":"Group 126","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[607.299,828.029],"ix":2},"a":{"a":0,"k":[334.846,183.852],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 126","np":1,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[-6.143,6.879],[-0.309,-0.619],[-2.956,-7.245],[-3.297,-6.657],[0.551,0.244],[1.778,1.856],[0.608,1.513],[4.972,8.878],[0.025,0.046]],"o":[[0.326,0.609],[3.488,7.004],[2.803,6.869],[3.574,7.216],[0.9,2.638],[-4.978,-5.795],[-3.79,-9.427],[-0.025,-0.045],[3.077,-8.6]],"v":[[-9.022,-38.4],[-8.068,-36.558],[1.671,-15.157],[9.653,5.639],[21.739,27.245],[3.47,36.544],[-9.779,12.54],[-22.561,-14.921],[-22.638,-15.056]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[-4.874,7.829],[-0.41,-0.557],[-3.389,-7.053],[-3.026,-1.631],[0.58,-0.164],[2.521,0.5],[3.287,2.8],[6.419,7.895],[0.033,0.041]],"o":[[0.425,0.544],[4.636,6.303],[3.278,6.821],[5.508,2.968],[2.376,1.458],[-7.125,-1.82],[-7.735,-6.589],[-0.032,-0.04],[1.559,-9]],"v":[[-19.414,-37.007],[-18.159,-35.356],[-5.708,-15.838],[3.399,-2.47],[25.762,6.435],[17.302,26.001],[-10.98,11.488],[-28.732,-11.556],[-28.831,-11.676]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[-4.874,7.829],[-0.41,-0.557],[-3.389,-7.053],[-3.026,-1.631],[0.58,-0.164],[2.521,0.5],[3.287,2.8],[6.419,7.895],[0.033,0.041]],"o":[[0.425,0.544],[4.636,6.303],[3.278,6.821],[5.508,2.968],[2.376,1.458],[-7.125,-1.82],[-7.735,-6.589],[-0.032,-0.04],[1.559,-9]],"v":[[-19.414,-37.007],[-18.159,-35.356],[-5.708,-15.838],[3.399,-2.47],[25.762,6.435],[17.302,26.001],[-10.98,11.488],[-28.732,-11.556],[-28.831,-11.676]],"c":true}]},{"t":95,"s":[{"i":[[-6.143,6.879],[-0.309,-0.619],[-2.956,-7.245],[-3.297,-6.657],[0.551,0.244],[1.778,1.856],[0.608,1.513],[4.972,8.878],[0.025,0.046]],"o":[[0.326,0.609],[3.488,7.004],[2.803,6.869],[3.574,7.216],[0.9,2.638],[-4.978,-5.795],[-3.79,-9.427],[-0.025,-0.045],[3.077,-8.6]],"v":[[-9.022,-38.4],[-8.068,-36.558],[1.671,-15.157],[9.653,5.639],[21.739,27.245],[3.47,36.544],[-9.779,12.54],[-22.561,-14.921],[-22.638,-15.056]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[317.105,141.561],"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":"Group 127","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[512.792,603.973],"ix":2},"a":{"a":0,"k":[316.672,140.764],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 127","np":1,"cix":2,"bm":0,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[0,0],[-0.213,-4.239],[0,0],[0,0],[0,0]],"o":[[0,0],[0.212,4.237],[0,0],[0,0],[0,0]],"v":[[-2.134,-19.336],[-6.811,6.807],[-4.216,19.336],[4.693,8.461],[7.024,-17.72]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[0,0],[-0.935,-4.14],[0,0],[0,0],[0,0]],"o":[[0,0],[0.934,4.138],[0,0],[0,0],[0,0]],"v":[[-13.267,-15.735],[-13.398,10.822],[-8.696,22.721],[-1.781,10.481],[-3.968,-15.713]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[0,0],[-0.935,-4.14],[0,0],[0,0],[0,0]],"o":[[0,0],[0.934,4.138],[0,0],[0,0],[0,0]],"v":[[-13.267,-15.735],[-13.398,10.822],[-8.696,22.721],[-1.781,10.481],[-3.968,-15.713]],"c":true}]},{"t":95,"s":[{"i":[[0,0],[-0.213,-4.239],[0,0],[0,0],[0,0]],"o":[[0,0],[0.212,4.237],[0,0],[0,0],[0,0]],"v":[[-2.134,-19.336],[-6.811,6.807],[-4.216,19.336],[4.693,8.461],[7.024,-17.72]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203999996185,0.216000005603,0.317999988794,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 12')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[297.793,117.093],"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":"Group 128","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[415.159,480.884],"ix":2},"a":{"a":0,"k":[297.896,117.093],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 128","np":1,"cix":2,"bm":0,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[-1.476,-10.707],[-8.069,-4.967],[-0.224,0.218],[-1.782,6.718],[-0.586,7.834],[4.88,3.871],[5.115,-2.249],[0.244,-0.63],[0.07,-0.185],[-0.06,-0.228]],"o":[[1.181,8.568],[0.272,0.167],[5.041,-4.901],[2.013,-7.586],[0.443,-5.911],[-4.826,-3.828],[-0.275,-0.414],[-0.072,0.185],[-0.225,0.164],[-3.683,10.2]],"v":[[-12.392,5.897],[-1.614,30.842],[-0.746,30.73],[8.936,12.75],[13.425,-10.931],[7.662,-27.181],[-7.93,-27.271],[-9.27,-27.097],[-9.475,-26.539],[-9.704,-25.912]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[-3.288,-10.296],[-8.8,-3.512],[-0.183,0.253],[-0.606,6.924],[0.763,7.819],[5.471,2.978],[4.654,-3.092],[0.133,-0.662],[0.037,-0.194],[-0.098,-0.214]],"o":[[2.631,8.239],[0.297,0.118],[4.127,-5.692],[0.684,-7.819],[-0.576,-5.9],[-5.41,-2.945],[-0.342,-0.361],[-0.039,0.195],[-0.194,0.2],[-1.882,10.68]],"v":[[-19.17,9.955],[-4.279,32.686],[-3.443,32.427],[3.016,13.054],[3.383,-11.045],[-5.078,-26.068],[-20.455,-23.487],[-21.745,-23.086],[-21.852,-22.501],[-21.97,-21.844]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[-3.288,-10.296],[-8.8,-3.512],[-0.183,0.253],[-0.606,6.924],[0.763,7.819],[5.471,2.978],[4.654,-3.092],[0.133,-0.662],[0.037,-0.194],[-0.098,-0.214]],"o":[[2.631,8.239],[0.297,0.118],[4.127,-5.692],[0.684,-7.819],[-0.576,-5.9],[-5.41,-2.945],[-0.342,-0.361],[-0.039,0.195],[-0.194,0.2],[-1.882,10.68]],"v":[[-19.17,9.955],[-4.279,32.686],[-3.443,32.427],[3.016,13.054],[3.383,-11.045],[-5.078,-26.068],[-20.455,-23.487],[-21.745,-23.086],[-21.852,-22.501],[-21.97,-21.844]],"c":true}]},{"t":95,"s":[{"i":[[-1.476,-10.707],[-8.069,-4.967],[-0.224,0.218],[-1.782,6.718],[-0.586,7.834],[4.88,3.871],[5.115,-2.249],[0.244,-0.63],[0.07,-0.185],[-0.06,-0.228]],"o":[[1.181,8.568],[0.272,0.167],[5.041,-4.901],[2.013,-7.586],[0.443,-5.911],[-4.826,-3.828],[-0.275,-0.414],[-0.072,0.185],[-0.225,0.164],[-3.683,10.2]],"v":[[-12.392,5.897],[-1.614,30.842],[-0.746,30.73],[8.936,12.75],[13.425,-10.931],[7.662,-27.181],[-7.93,-27.271],[-9.27,-27.097],[-9.475,-26.539],[-9.704,-25.912]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[303.218,116.872],"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":"Group 129","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[443.704,483.385],"ix":2},"a":{"a":0,"k":[303.385,117.574],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 129","np":1,"cix":2,"bm":0,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[-0.186,-0.516],[-0.043,-0.071],[0.987,2.706],[0,0],[0.071,0.157],[0.245,0.172],[0,0],[0,0],[0.802,-2.018]],"o":[[0.014,0.086],[1.03,1.903],[0,0],[-0.028,-0.157],[-0.587,-1.331],[0,-0.014],[-2.003,4.323],[0.171,2.161],[-0.357,0.759]],"v":[[-6.362,6.348],[-6.276,6.563],[5.561,-5.217],[5.561,-5.231],[5.404,-5.704],[2.869,-8.452],[2.855,-8.466],[-3.628,-2.526],[-6.048,4.387]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[-0.448,-0.316],[-0.074,-0.037],[2.361,1.65],[0,0],[0.147,0.089],[0.299,0],[0,0],[0,0],[-0.501,-2.113]],"o":[[0.061,0.062],[1.935,0.968],[0,0],[-0.113,-0.113],[-1.244,-0.753],[-0.008,-0.011],[0.84,4.69],[1.38,1.672],[0.143,0.826]],"v":[[12.601,-11.037],[12.795,-10.91],[15.731,-27.35],[15.723,-27.361],[15.323,-27.659],[11.67,-28.455],[11.651,-28.458],[9.749,-19.874],[11.733,-12.823]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[-0.448,-0.316],[-0.074,-0.037],[2.361,1.65],[0,0],[0.147,0.089],[0.299,0],[0,0],[0,0],[-0.501,-2.113]],"o":[[0.061,0.062],[1.935,0.968],[0,0],[-0.113,-0.113],[-1.244,-0.753],[-0.008,-0.011],[0.84,4.69],[1.38,1.672],[0.143,0.826]],"v":[[12.601,-11.037],[12.795,-10.91],[15.731,-27.35],[15.723,-27.361],[15.323,-27.659],[11.67,-28.455],[11.651,-28.458],[9.749,-19.874],[11.733,-12.823]],"c":true}]},{"t":95,"s":[{"i":[[-0.186,-0.516],[-0.043,-0.071],[0.987,2.706],[0,0],[0.071,0.157],[0.245,0.172],[0,0],[0,0],[0.802,-2.018]],"o":[[0.014,0.086],[1.03,1.903],[0,0],[-0.028,-0.157],[-0.587,-1.331],[0,-0.014],[-2.003,4.323],[0.171,2.161],[-0.357,0.759]],"v":[[-6.362,6.348],[-6.276,6.563],[5.561,-5.217],[5.561,-5.231],[5.404,-5.704],[2.869,-8.452],[2.855,-8.466],[-3.628,-2.526],[-6.048,4.387]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000020027,0.944999992847,0.957000017166,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[335.217,183.312],"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":"Group 130","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[607.087,820.848],"ix":2},"a":{"a":0,"k":[334.805,182.471],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 130","np":1,"cix":2,"bm":0,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.345,"y":1},"o":{"x":0.556,"y":0},"t":0,"s":[{"i":[[1.014,2.805],[1.385,1.206],[0,0],[1.737,1.665],[0.574,-2.633],[-0.276,-1.053],[-0.012,-0.186],[0.516,-2.063],[-0.199,-0.342]],"o":[[-0.43,-1.163],[-0.009,-0.018],[-1.081,-0.933],[-2.573,0.886],[1.267,1.424],[0.048,0.169],[0.194,2.46],[-0.161,0.55],[0.999,1.754]],"v":[[5.912,-3.321],[3.598,-6.506],[3.576,-6.529],[-0.637,-10.27],[-6.925,-6.529],[-2.994,-1.107],[-2.905,-0.576],[-5.593,7.158],[-5.564,8.516]],"c":true}]},{"i":{"x":0.468,"y":1},"o":{"x":0.47,"y":0},"t":27,"s":[{"i":[[2.452,1.698],[1.826,0.193],[0,0],[2.4,0.174],[-1.04,-2.486],[-0.83,-0.704],[-0.119,-0.144],[-0.761,-1.986],[-0.358,-0.169]],"o":[[-1.019,-0.706],[-0.018,-0.01],[-1.421,-0.144],[-1.416,2.324],[1.855,0.439],[0.136,0.111],[1.57,1.904],[0.184,0.543],[1.825,0.863]],"v":[[16.122,-25.232],[12.399,-26.513],[12.368,-26.519],[5.994,-28.427],[3.767,-20.495],[10.098,-18.309],[10.475,-17.925],[12.71,-10.049],[13.513,-8.954]],"c":true}]},{"i":{"x":0.302,"y":1},"o":{"x":0.525,"y":0},"t":71,"s":[{"i":[[2.452,1.698],[1.826,0.193],[0,0],[2.4,0.174],[-1.04,-2.486],[-0.83,-0.704],[-0.119,-0.144],[-0.761,-1.986],[-0.358,-0.169]],"o":[[-1.019,-0.706],[-0.018,-0.01],[-1.421,-0.144],[-1.416,2.324],[1.855,0.439],[0.136,0.111],[1.57,1.904],[0.184,0.543],[1.825,0.863]],"v":[[16.122,-25.232],[12.399,-26.513],[12.368,-26.519],[5.994,-28.427],[3.767,-20.495],[10.098,-18.309],[10.475,-17.925],[12.71,-10.049],[13.513,-8.954]],"c":true}]},{"t":95,"s":[{"i":[[1.014,2.805],[1.385,1.206],[0,0],[1.737,1.665],[0.574,-2.633],[-0.276,-1.053],[-0.012,-0.186],[0.516,-2.063],[-0.199,-0.342]],"o":[[-0.43,-1.163],[-0.009,-0.018],[-1.081,-0.933],[-2.573,0.886],[1.267,1.424],[0.048,0.169],[0.194,2.46],[-0.161,0.55],[0.999,1.754]],"v":[[5.912,-3.321],[3.598,-6.506],[3.576,-6.529],[-0.637,-10.27],[-6.925,-6.529],[-2.994,-1.107],[-2.905,-0.576],[-5.593,7.158],[-5.564,8.516]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999974728,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 10')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[334.496,181.368],"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":"Group 131","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[603.007,811.053],"ix":2},"a":{"a":0,"k":[334.021,180.587],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 131","np":1,"cix":2,"bm":0,"ix":18,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Head","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.792],"y":[0.802]},"o":{"x":[0.622],"y":[0]},"t":1.909,"s":[-13]},{"i":{"x":[0.379],"y":[1]},"o":{"x":[0.174],"y":[-0.874]},"t":14.318,"s":[3.657]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":28.637,"s":[0]},{"i":{"x":[0.797],"y":[0.806]},"o":{"x":[0.615],"y":[0]},"t":73,"s":[0]},{"i":{"x":[0.359],"y":[1]},"o":{"x":[0.17],"y":[-1.048]},"t":83.5,"s":[-16.195]},{"t":96.86328125,"s":[-13]}],"ix":10},"p":{"a":0,"k":[296.372,53.87,0],"ix":2},"a":{"a":0,"k":[407.236,152.124,0],"ix":1},"s":{"a":0,"k":[19.231,19.231,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.345,0.772],[0.459,-0.611],[-0.381,-0.769],[0,0],[-0.817,1.088],[-1.676,-0.294],[0,-0.045]],"o":[[0,-0.176],[-2.242,-0.4],[-0.761,1.015],[0,0],[-0.42,-0.852],[1.027,-1.368],[4.553,0.809],[0,0]],"v":[[4.725,2.818],[0.325,-2.278],[-3.683,-0.688],[-4.331,2.343],[-4.556,2.455],[-3.882,-0.838],[0.369,-2.524],[4.975,2.818]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[302.722,43.201],"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":"Group 109","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[440.841,97.224],"ix":2},"a":{"a":0,"k":[302.835,43.312],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 109","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.548,0.457],[0.176,-0.146],[-0.483,-0.221],[0.376,0.464],[-0.143,-0.176],[0.774,0.104]],"o":[[0.174,-0.145],[-0.272,0.228],[0.432,0.198],[-0.143,-0.175],[0.556,0.686],[-0.958,-0.128]],"v":[[-0.433,-0.867],[-0.183,-0.616],[-0.36,0.524],[0.43,-0.262],[0.68,-0.513],[-0.278,0.908]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.827000021935,0.340999990702,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 13')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[299.076,52.96],"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":"Group 110","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[421.174,147.406],"ix":2},"a":{"a":0,"k":[299.053,52.963],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 110","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.917,-0.269],[1.61,0.023]],"o":[[0,0],[0.917,0.268],[-1.611,-0.022]],"v":[[-0.827,-0.481],[0.738,-1.129],[-0.044,1.375]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999974728,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 10')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[299.063,51.153],"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":"Group 111","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[421.962,138.506],"ix":2},"a":{"a":0,"k":[299.204,51.251],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 111","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.347,-0.05],[0,0],[-0.591,0.712],[0.002,0.015],[0,0],[0.944,-1.138]],"o":[[0,0],[1.272,-0.047],[0.873,-1.052],[0,0],[0.009,0.063],[-0.639,0.769]],"v":[[-1.963,1.959],[-1.972,1.709],[0.836,0.564],[1.507,-1.923],[1.754,-1.959],[1.029,0.725]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[300.247,50.77],"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":"Group 112","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[426.882,136.003],"ix":2},"a":{"a":0,"k":[300.15,50.77],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 112","np":1,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.667,-1.646],[-0.202,0.044],[-2.149,0.732],[0.948,1.897],[2.409,-1.011]],"o":[[0.191,0.189],[1.365,1.711],[2.114,-0.72],[-1.206,-2.411],[-1.995,0.837]],"v":[[-3.895,1.147],[-3.283,1.331],[2.564,4.042],[4.615,-1.396],[-2.605,-3.762]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[302.771,45.761],"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":"Group 113","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[441.147,110.096],"ix":2},"a":{"a":0,"k":[302.894,45.788],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 113","np":1,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.161,1.084],[-0.156,0.221],[-0.46,0.267],[-0.521,-0.058],[0.614,-3.023],[1.151,0.987],[0.125,0.682],[-0.004,0.463],[0.172,0.04],[0.141,-0.376],[0.217,-0.105],[0.199,0.048],[0.328,-0.188]],"o":[[0.037,-0.257],[-0.054,-0.457],[0.457,-0.265],[2.729,-0.928],[-0.198,0.972],[-0.572,-0.49],[-0.086,-0.473],[-0.127,0.057],[-0.425,-0.099],[-0.084,0.225],[-0.181,0.087],[-0.341,-0.082],[-0.872,0.5]],"v":[[-4.026,-0.961],[-3.72,-1.693],[-3.116,-2.883],[-1.613,-3.13],[3.573,1.393],[1.131,3.072],[0.335,0.766],[0.209,-0.634],[-0.234,-0.59],[-0.7,-0.419],[-1.122,0.052],[-1.673,0.125],[-2.257,0.189]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[297.712,48.809],"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":"Group 114","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[413.189,125.91],"ix":2},"a":{"a":0,"k":[297.517,48.829],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 114","np":1,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-3.131],[3.399,0.357],[-0.536,0.135]],"o":[[0,0],[-3.4,-0.358],[0.537,-0.133]],"v":[[4.227,-1.051],[-0.827,3.825],[-0.559,-3.78]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999974728,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 10')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[295.887,50.984],"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":"Group 115","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[409.492,137.099],"ix":2},"a":{"a":0,"k":[296.806,50.98],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 115","np":1,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Neck","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.324],"y":[1]},"o":{"x":[0.568],"y":[0]},"t":1.909,"s":[7]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":28.637,"s":[0]},{"i":{"x":[0.304],"y":[1]},"o":{"x":[0.559],"y":[0]},"t":73,"s":[0]},{"t":96.86328125,"s":[7]}],"ix":10},"p":{"a":0,"k":[416.764,172.966,0],"ix":2},"a":{"a":0,"k":[298.205,57.878,0],"ix":1},"s":{"a":0,"k":[520,520,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.134,-0.895],[-1.985,0.476],[0.073,0.169],[0.347,1.694]],"o":[[0,0],[0.04,0.274],[2.163,-0.519],[-0.45,-1.041],[-0.403,-1.968]],"v":[[-2.999,-1.997],[-1.657,2.521],[1.272,4.342],[2.802,2.033],[1.295,-1.997]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999968884,0.243000000598,0.447000002394,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 10')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[297.387,55.24],"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":"Group 116","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"B_hand_1","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.324],"y":[1]},"o":{"x":[0.568],"y":[0]},"t":1.909,"s":[-44]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":28.637,"s":[0]},{"i":{"x":[0.304],"y":[1]},"o":{"x":[0.559],"y":[0]},"t":73,"s":[0]},{"t":96.86328125,"s":[-44]}],"ix":10},"p":{"a":0,"k":[402.958,203.172,0],"ix":2},"a":{"a":0,"k":[295.55,63.687,0],"ix":1},"s":{"a":0,"k":[520,520,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.018,-1.024],[5.228,-3.744],[0.423,-1.494],[-2.138,0.679],[-8.594,10.266]],"o":[[-6.551,2.223],[-1.597,1.144],[2.589,5.848],[1.497,-0.476],[5.041,-6.021]],"v":[[7.88,-13.592],[-12.603,-0.704],[-17.843,5.484],[-10.818,15.894],[7.235,0.345]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.894117647059,0.917647058824,0.937254901961,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 14')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[286.196,73.764],"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":"Group 134","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"B_hand_2","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.805],"y":[1.881]},"o":{"x":[0.59],"y":[0]},"t":3.818,"s":[-45]},{"i":{"x":[0.497],"y":[1]},"o":{"x":[0.183],"y":[0.142]},"t":15.272,"s":[-56.217]},{"i":{"x":[0.538],"y":[1]},"o":{"x":[0.517],"y":[0]},"t":26.728,"s":[9]},{"i":{"x":[0.538],"y":[1]},"o":{"x":[0.416],"y":[0]},"t":34.675,"s":[-14]},{"i":{"x":[0.549],"y":[1]},"o":{"x":[0.409],"y":[0]},"t":42.621,"s":[-2]},{"i":{"x":[0.538],"y":[1]},"o":{"x":[0.416],"y":[0]},"t":51.363,"s":[-14]},{"i":{"x":[0.549],"y":[1]},"o":{"x":[0.409],"y":[0]},"t":59.311,"s":[-2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.416],"y":[0]},"t":68.053,"s":[-14]},{"i":{"x":[0.304],"y":[1]},"o":{"x":[0.559],"y":[0]},"t":76,"s":[-2]},{"t":98.7724609375,"s":[-45]}],"ix":10},"p":{"a":0,"k":[274.777,89.579,0],"ix":2},"a":{"a":0,"k":[294.939,337.811,0],"ix":1},"s":{"a":0,"k":[19.231,19.231,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.01,0],[0.015,0.057],[-0.001,0.027],[-0.06,0.002],[0.003,-0.068],[-0.711,-2.89],[0.068,-0.017]],"o":[[-0.056,0],[-0.719,-2.927],[0.003,-0.069],[0.068,0.004],[-0.002,0.028],[0.016,0.067],[-0.009,0.003]],"v":[[0.352,2.945],[0.23,2.85],[-0.359,-2.826],[-0.228,-2.945],[-0.109,-2.814],[0.474,2.79],[0.381,2.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[260.723,68.861],"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":"Group 91","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[222.142,230.075],"ix":2},"a":{"a":0,"k":[260.777,68.861],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 91","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.03,0],[0.025,0.026],[0.018,0.081],[-0.067,0.015],[-0.016,-0.067],[-0.635,-0.686],[0.051,-0.047]],"o":[[-0.034,0],[-0.681,-0.736],[-0.015,-0.068],[0.071,-0.015],[0.004,0.019],[0.047,0.051],[-0.024,0.022]],"v":[[0.55,1.469],[0.458,1.429],[-0.674,-1.304],[-0.579,-1.454],[-0.429,-1.359],[0.642,1.259],[0.635,1.436]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[261.612,66.966],"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":"Group 92","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[226.48,220.257],"ix":2},"a":{"a":0,"k":[261.612,66.972],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 92","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.018,0],[0.021,0.046],[0.024,0.013],[-0.033,0.06],[-0.061,-0.037],[-0.798,-1.698],[0.063,-0.029]],"o":[[-0.047,0],[-0.765,-1.626],[-0.06,-0.033],[0.034,-0.062],[0.1,0.057],[0.03,0.063],[-0.017,0.008]],"v":[[1.611,1.662],[1.498,1.59],[-1.673,-1.408],[-1.721,-1.579],[-1.55,-1.626],[1.724,1.485],[1.664,1.65]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[263.194,66.832],"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":"Group 93","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[234.71,219.573],"ix":2},"a":{"a":0,"k":[263.194,66.841],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 93","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.026,0],[0.025,0.033],[0.041,0.009],[-0.015,0.068],[-0.07,-0.014],[-1.33,-1.757],[0.054,-0.042]],"o":[[-0.038,0],[-1.275,-1.683],[-0.067,-0.015],[0.016,-0.066],[0.171,0.038],[0.041,0.054],[-0.023,0.017]],"v":[[2.728,1.46],[2.628,1.411],[-2.759,-1.202],[-2.854,-1.352],[-2.704,-1.446],[2.827,1.261],[2.803,1.436]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827000021935,0.878000020981,0.917999982834,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[265.092,66.257],"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":"Group 94","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[244.565,216.566],"ix":2},"a":{"a":0,"k":[265.089,66.263],"ix":1},"s":{"a":0,"k":[520,520],"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":"Layer 9/1 Outlines - Group 94","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.587,0.534],[-3.411,-3.951],[1.721,0.287],[-2.233,10.311]],"o":[[7.38,-2.479],[3.411,3.952],[-1.722,-0.286],[0,0]],"v":[[-7.918,-11.511],[9.698,1.696],[4.202,13.702],[-10.876,-9.092]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.894117647059,0.917647058824,0.937254901961,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 14')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[270.478,75.885],"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":"Group 133","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[295.065,337.936],"ix":2},"a":{"a":0,"k":[274.801,89.603],"ix":1},"s":{"a":0,"k":[520,520],"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":"B_hand_1","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"B_arm","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[-21]},{"i":{"x":[0.769],"y":[2.233]},"o":{"x":[0.461],"y":[0]},"t":3.818,"s":[-21]},{"i":{"x":[0.592],"y":[1.151]},"o":{"x":[0.425],"y":[0.317]},"t":11.454,"s":[-16.08]},{"i":{"x":[0.752],"y":[1.14]},"o":{"x":[0.243],"y":[0.087]},"t":18.137,"s":[-46.923]},{"i":{"x":[0.703],"y":[1.267]},"o":{"x":[0.262],"y":[0.153]},"t":31.05,"s":[14.997]},{"i":{"x":[0.709],"y":[1.242]},"o":{"x":[0.269],"y":[0.246]},"t":38.829,"s":[-21.152]},{"i":{"x":[0.709],"y":[1.042]},"o":{"x":[0.279],"y":[0.25]},"t":46.609,"s":[14.437]},{"i":{"x":[0.699],"y":[1.066]},"o":{"x":[0.271],"y":[0.056]},"t":55.254,"s":[-22.27]},{"i":{"x":[0.706],"y":[0.997]},"o":{"x":[0.275],"y":[0.093]},"t":63.897,"s":[8.163]},{"i":{"x":[0.797],"y":[1.549]},"o":{"x":[0.33],"y":[0.017]},"t":72.542,"s":[-9.47]},{"i":{"x":[0.359],"y":[1]},"o":{"x":[0.17],"y":[0.275]},"t":85.409,"s":[6.181]},{"t":98.7724609375,"s":[-21]}],"ix":10},"p":{"a":0,"k":[225,217.163,0],"ix":2},"a":{"a":0,"k":[554.462,371.754,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.572,-0.295],[0.66,-0.794],[0.865,-0.849],[-0.46,0.451],[-0.694,0.845],[-0.964,0.498]],"o":[[-0.915,0.472],[-0.777,0.932],[-0.461,0.451],[0.78,-0.766],[0.684,-0.834],[0.572,-0.295]],"v":[[2.222,-2.56],[-0.166,-0.674],[-2.837,1.697],[-2.131,2.404],[0.335,0.29],[2.726,-1.697]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917999982834,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 4')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[191.133,62.112],"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":"Group 55","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[567.135,346.341],"ix":2},"a":{"a":0,"k":[191.128,62.076],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 55","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.511,0],[0.799,0.195],[0.08,0.417],[-0.309,0.22],[-0.184,-0.086],[0.049,-0.104],[0.102,0.049],[1.696,-1.2],[-0.027,-0.042],[-0.836,0.175],[0.989,0.163],[-0.019,0.114],[-0.109,-0.015],[-0.178,-0.46],[0.075,-0.096]],"o":[[-0.923,0],[-1.135,-0.275],[-0.048,-0.251],[1.893,-1.343],[0.105,0.049],[-0.05,0.107],[-0.043,-0.021],[-0.288,0.205],[0.46,0.702],[-0.353,-0.2],[-0.115,-0.019],[0.019,-0.115],[1.001,0.166],[0.042,0.108],[-0.118,0.149]],"v":[[1.392,1.734],[-1.644,1.347],[-3.449,0.318],[-3.056,-0.391],[3.347,0.353],[3.448,0.632],[3.168,0.734],[-2.813,-0.047],[-3.01,0.297],[1.977,1.288],[-0.488,0.648],[-0.661,0.406],[-0.42,0.232],[2.465,1.204],[2.413,1.525]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.671000003815,0.764999985695,0.838999986649,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 15')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[194.208,49.967],"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":"Group 56","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[583.019,286.25],"ix":2},"a":{"a":0,"k":[194.212,50.408],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 56","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.424,3.044],[0.801,0.083],[0.788,-1.288],[-0.071,-0.216],[-0.009,-0.025],[-0.243,-0.113]],"o":[[-0.209,-1.501],[-1.04,-0.108],[-0.113,0.184],[0.008,0.027],[-0.082,0.253],[0.921,0.427]],"v":[[3.576,-0.526],[0.108,-2.156],[-3.874,-1.23],[-3.928,-0.624],[-3.897,-0.556],[-3.692,0.16]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.893999993801,0.917999982834,0.936999976635,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 14')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[194.425,50.933],"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":"Group 57","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[583.14,286.138],"ix":2},"a":{"a":0,"k":[194.236,50.386],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 57","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.596,9.876],[0.131,0.052],[0.166,-0.09],[2.09,1.29],[-0.11,-0.456],[1.335,-9.612],[0.002,-0.134],[0.003,-0.171],[-0.188,0.024],[-1.97,-0.851],[0.063,0.358]],"o":[[0.016,-0.255],[-0.071,-0.16],[-2.126,1.138],[-0.255,-0.157],[2.239,9.277],[-0.05,0.078],[-0.003,0.171],[-0.004,0.252],[2.025,-0.259],[0.266,0.114],[-1.706,-9.729]],"v":[[3.484,-14.68],[3.264,-15.134],[2.899,-15.299],[-3.482,-15.483],[-4.002,-14.919],[-2.619,13.784],[-2.708,14.096],[-2.716,14.609],[-2.362,15.109],[3.612,15.527],[4.048,14.911]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000020027,0.944999992847,0.957000017166,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[194.566,65.811],"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":"Group 58","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[584.937,365.623],"ix":2},"a":{"a":0,"k":[194.585,65.82],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 58","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.011,0],[0.016,0.056],[-0.067,0.017],[-0.024,0.017],[-0.042,-0.058],[0.056,-0.04],[1.395,-0.383]],"o":[[-0.055,0],[-0.018,-0.066],[1.351,-0.372],[0.055,-0.041],[0.04,0.055],[-0.097,0.072],[-0.011,0.004]],"v":[[-1.884,1.191],[-2.005,1.099],[-1.917,0.946],[1.808,-1.15],[1.983,-1.122],[1.955,-0.949],[-1.851,1.186]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[195.355,63.466],"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":"Group 108","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[588.896,353.544],"ix":2},"a":{"a":0,"k":[195.354,63.475],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 108","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.008,0],[0.012,0.06],[-0.068,0.014],[-0.027,0.025],[-0.047,-0.051],[0.051,-0.047],[1.871,-0.366]],"o":[[-0.059,0],[-0.013,-0.068],[1.803,-0.352],[0.051,-0.046],[0.046,0.051],[-0.112,0.101],[-0.008,0.001]],"v":[[-2.294,1.551],[-2.417,1.45],[-2.318,1.303],[2.207,-1.505],[2.384,-1.496],[2.375,-1.319],[-2.27,1.549]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[195.24,62.318],"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":"Group 109","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[588.303,347.625],"ix":2},"a":{"a":0,"k":[195.238,62.325],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 109","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.01,0],[0.015,0.058],[-0.067,0.016],[-0.02,0.018],[-0.046,-0.048],[0.051,-0.047],[2.212,-0.541]],"o":[[-0.056,0],[-0.016,-0.066],[2.151,-0.526],[0.052,-0.047],[0.047,0.051],[-0.085,0.078],[-0.01,0.003]],"v":[[-2.129,1.349],[-2.251,1.253],[-2.159,1.103],[2.043,-1.302],[2.22,-1.296],[2.213,-1.119],[-2.099,1.345]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[194.539,61.513],"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":"Group 110","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[584.7,343.481],"ix":2},"a":{"a":0,"k":[194.539,61.521],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 110","np":1,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.306,0.02],[-0.021,0.031],[0.308,-0.465],[0.023,-0.03],[0.443,-0.345],[1.984,-0.218],[-0.469,0.231],[0.498,-0.252],[0.072,-0.073],[1.318,-2.189],[0.207,-0.372],[-0.085,-0.113],[-0.592,-0.411],[-0.065,-0.011],[-0.191,0.477],[-0.014,0.016],[-1.926,1.534],[0.397,-0.124],[0.005,0.001],[-0.006,0.005],[-0.126,0.163]],"o":[[0.022,-0.029],[0.306,-0.464],[-0.021,0.033],[-0.078,-0.28],[-0.129,0.1],[0.316,-0.32],[0.499,-0.245],[-0.079,0.04],[-2.18,1.346],[-0.242,0.339],[-0.074,0.134],[0.429,0.577],[0.059,0.041],[-0.06,0.449],[0.511,-1.277],[2.33,-0.788],[0.389,-0.31],[-0.005,-0.001],[0.006,-0.005],[0.122,-0.08],[0.244,-0.314]],"v":[[5.443,-4.121],[5.513,-4.206],[4.655,-4.808],[4.579,-4.725],[3.67,-4.95],[-0.245,-3.2],[1.075,-4.278],[0.729,-5.072],[-0.06,-4.616],[-5.381,1.054],[-6.061,2.115],[-5.999,2.547],[-3.751,4.561],[-3.562,4.631],[-2.74,4.847],[-0.944,1.385],[5.557,-1.741],[5.149,-2.61],[5.134,-2.616],[5.151,-2.632],[5.891,-3.342]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917999982834,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 4')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[192.088,65.027],"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":"Group 111","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[571.747,361.503],"ix":2},"a":{"a":0,"k":[192.024,65.02],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 111","np":1,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Backpack_back","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-3.812,"ix":10},"p":{"a":0,"k":[479.857,231.512,0],"ix":2},"a":{"a":0,"k":[282.361,396.838,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.468,0],[0.195,0.063],[-0.221,1.318],[-1.183,0],[0,0],[-0.322,-0.388],[0.009,-0.05],[0.136,0.029],[-0.022,0.136],[0.481,0.578],[0.45,0.01],[0,0],[0.161,-0.96],[-0.971,-0.312],[-0.21,0.567],[0.241,0.102],[0.064,-0.585],[-0.065,-0.03],[0.057,-0.126],[0.127,0.06],[-0.068,0.618],[-0.592,0.124],[-0.215,-0.345],[0.659,-0.847]],"o":[[-0.156,0],[-1.051,-0.338],[0.2,-1.194],[0,0],[0.602,0.013],[0.627,0.756],[-0.023,0.136],[-0.136,-0.023],[0.002,-0.01],[-0.226,-0.271],[0,0],[-0.896,0],[-0.142,0.843],[0.547,0.174],[0.364,-0.986],[-0.261,0.061],[-0.048,0.444],[0.125,0.057],[-0.057,0.126],[-0.324,-0.147],[0.077,-0.699],[0.131,-0.031],[0.432,0.691],[-0.184,0.236]],"v":[[-0.127,2.601],[-0.653,2.512],[-2.018,-0.213],[0.183,-2.601],[0.22,-2.601],[1.613,-1.997],[2.044,-0.016],[1.757,0.189],[1.551,-0.098],[1.227,-1.679],[0.209,-2.101],[0.184,-2.101],[-1.525,-0.131],[-0.501,2.036],[0.626,1.455],[0.411,-1.067],[-0.184,0.083],[-0.065,0.796],[0.059,1.127],[-0.272,1.251],[-0.681,0.029],[0.33,-1.554],[0.924,-1.23],[0.827,2.125]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.671000003815,0.764999985695,0.838999986649,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 15')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[131.507,56.204],"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":"Group 59","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[260.109,316.1],"ix":2},"a":{"a":0,"k":[131.512,56.204],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 59","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.105,1.147],[1.141,-1.044],[0.075,-0.183],[0.041,-0.232],[-1.11,-1.027],[-0.785,1.503]],"o":[[-1.271,-1.321],[-0.181,0.164],[-0.155,0.165],[-0.254,1.446],[1.505,1.395],[0.678,-1.3]],"v":[[2.006,-2.824],[-2.166,-2.341],[-2.545,-1.816],[-2.857,-1.221],[-1.666,2.75],[2.231,1.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000020027,0.944999992847,0.957000017166,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[131.413,56.224],"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":"Group 60","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[259.216,315.803],"ix":2},"a":{"a":0,"k":[131.338,56.146],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 60","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.906,3.446],[-11.906,3.446],[-11.906,-3.446],[11.906,-3.446]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.827000021935,0.340999990702,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 13')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[143.59,56.15],"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":"Group 112","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[322.315,315.821],"ix":2},"a":{"a":0,"k":[143.59,56.15],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 112","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,4.032],[3.167,0.695],[3,-2.19],[0.042,-0.026],[2.965,-6.774],[-6.977,-3.205],[-2.642,1.85],[-2.478,2.989],[-2.253,3.325]],"o":[[-0.266,-3.935],[-3.385,-0.744],[-0.042,0.013],[-6.313,3.885],[-2.599,5.943],[2.835,1.301],[3.198,-2.24],[2.565,-3.095],[2.126,-3.138]],"v":[[17.947,-11.853],[10.049,-16.837],[-0.451,-16.355],[-0.576,-16.309],[-14.685,0.178],[-11.243,16.915],[-2.39,16.695],[6.036,8.373],[13.176,-1.333]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337000012398,0.356999993324,0.509999990463,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 16')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[134.073,73.079],"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":"Group 113","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[276.77,403.736],"ix":2},"a":{"a":0,"k":[134.747,73.221],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 113","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.813,1.405],[0.07,0.003],[0.014,0.002],[0.613,-2.726],[-2.984,-1.042],[-0.724,2.354]],"o":[[-0.074,-0.036],[-0.013,-0.003],[-3.343,-0.418],[-0.568,2.522],[2.892,1.01],[0.752,-2.443]],"v":[[1.739,-6.53],[1.523,-6.586],[1.485,-6.598],[-3.281,-0.814],[-1.568,6.006],[2.99,1.591]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[119.953,77.347],"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":"Group 114","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[200.379,423.881],"ix":2},"a":{"a":0,"k":[119.913,77.132],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 114","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.635,0.099],[1.538,-0.57],[0.831,-1.122],[-0.281,-1.294],[-1.134,-0.283],[-0.097,0.053],[-0.281,0.003],[-0.512,0.575],[-0.046,2.593],[-0.073,-0.011]],"o":[[-1.548,-0.241],[-1.365,0.506],[-0.704,0.951],[0.272,1.256],[0.136,0.035],[0.306,0.106],[0.864,-0.007],[1.659,-1.867],[0.072,0.011],[0.629,0.098]],"v":[[4.793,-3.878],[-0.259,-4.207],[-3.378,-1.235],[-5.147,2.368],[-2.357,4.648],[-2.009,4.604],[-1.12,4.774],[0.804,3.208],[4.309,-2.949],[4.527,-2.914]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[126.183,64.376],"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":"Group 115","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[232.591,359.065],"ix":2},"a":{"a":0,"k":[126.168,64.547],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 115","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[282.361,396.857],"ix":2},"a":{"a":0,"k":[282.361,396.857],"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":"Backpack_back","np":4,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.92],[1.409,0],[0,1.92],[-1.409,0]],"o":[[0,1.92],[-1.409,0],[0,-1.92],[1.409,0]],"v":[[7.552,17.664],[5,21.14],[2.448,17.664],[5,14.187]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.827000021935,0.340999990702,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 13')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[246.814,50.007],"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":"Group 42","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[357.917,224.689],"ix":2},"a":{"a":0,"k":[246.814,50.007],"ix":1},"s":{"a":0,"k":[515,515],"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":"Layer 4/Office management 2 Outlines - Group 42","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Pin 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.696],"y":[0]},"t":17.429,"s":[-60]},{"i":{"x":[0.476],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":31.755,"s":[15]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":42.897,"s":[-6]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":52.448,"s":[3]},{"i":{"x":[0.661],"y":[1]},"o":{"x":[0.278],"y":[0]},"t":66,"s":[0]},{"i":{"x":[0.835],"y":[2.049]},"o":{"x":[0.67],"y":[0]},"t":78,"s":[3]},{"i":{"x":[0.329],"y":[1]},"o":{"x":[0.165],"y":[0.164]},"t":90.5,"s":[-14.015]},{"t":99,"s":[60]}],"ix":10},"p":{"a":0,"k":[1263.712,569.783,0],"ix":2},"a":{"a":0,"k":[149.712,367.783,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.81,0.81,0.667],"y":[-0.187,-0.187,1]},"o":{"x":[0.549,0.549,0.333],"y":[0,0,0]},"t":14,"s":[0,0,100]},{"i":{"x":[0.542,0.542,0.667],"y":[1,1,1]},"o":{"x":[0.332,0.332,0.333],"y":[0.315,0.315,0]},"t":23.143,"s":[22.458,22.458,100]},{"i":{"x":[0.476,0.476,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":28.326,"s":[106,106,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":39.469,"s":[97,97,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":49.021,"s":[101,101,100]},{"i":{"x":[0.424,0.424,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":60.571,"s":[100,100,100]},{"i":{"x":[0.835,0.835,0.667],"y":[-1.277,-1.277,1]},"o":{"x":[0.67,0.67,0.333],"y":[0,0,0]},"t":80,"s":[100,100,100]},{"i":{"x":[0.666,0.666,0.667],"y":[1,1,1]},"o":{"x":[0.165,0.165,0.333],"y":[0.147,0.147,0]},"t":90.5,"s":[89.024,89.024,100]},{"t":96,"s":[0,0,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.638],[3.641,0],[0,3.637],[-3.637,0]],"o":[[0,3.637],[-3.637,0],[0,-3.638],[3.641,0]],"v":[[6.586,0],[-0.002,6.589],[-6.586,0],[-0.002,-6.589]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 4')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[246.87,90.027],"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":"Group 66","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[149.653,257.256],"ix":2},"a":{"a":0,"k":[246.87,90.027],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 66","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.642,0],[0,3.637],[-3.637,0],[0,-3.638]],"o":[[-3.637,0],[0,-3.638],[3.642,0],[0,3.637]],"v":[[-0.002,2.194],[-6.585,-4.394],[-0.002,-10.983],[6.585,-4.394]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[4.904,4.905],[4.909,-4.908],[-3.81,-5.799],[0,0],[-2.301,3.411]],"o":[[-4.909,-4.908],[-4.904,4.905],[2.301,3.489],[0,0],[3.875,-5.755]],"v":[[8.886,-12.285],[-8.886,-12.285],[-8.886,5.484],[-0.002,17.193],[8.886,5.484]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999974728,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[246.87,94.421],"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":"Group 67","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[149.712,282.896],"ix":2},"a":{"a":0,"k":[246.881,95.034],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 67","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Pin 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.696],"y":[0]},"t":3.429,"s":[-60]},{"i":{"x":[0.476],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":17.755,"s":[15]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":28.897,"s":[-6]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":38.448,"s":[3]},{"i":{"x":[0.661],"y":[1]},"o":{"x":[0.278],"y":[0]},"t":52,"s":[0]},{"i":{"x":[0.835],"y":[0.314]},"o":{"x":[0.67],"y":[0]},"t":64,"s":[3]},{"i":{"x":[0.329],"y":[1]},"o":{"x":[0.165],"y":[0.402]},"t":79.429,"s":[27.985]},{"t":91,"s":[60]}],"ix":10},"p":{"a":0,"k":[1508.379,428.795,0],"ix":2},"a":{"a":0,"k":[394.379,226.795,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.81,0.81,0.667],"y":[-0.187,-0.187,1]},"o":{"x":[0.549,0.549,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.542,0.542,0.667],"y":[1,1,1]},"o":{"x":[0.332,0.332,0.333],"y":[0.315,0.315,0]},"t":9.143,"s":[22.458,22.458,100]},{"i":{"x":[0.476,0.476,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":14.326,"s":[106,106,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":25.469,"s":[97,97,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":35.021,"s":[101,101,100]},{"i":{"x":[0.424,0.424,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":46.571,"s":[100,100,100]},{"i":{"x":[0.835,0.835,0.667],"y":[-1.169,-1.169,1]},"o":{"x":[0.67,0.67,0.333],"y":[0,0,0]},"t":66.571,"s":[100,100,100]},{"i":{"x":[0.666,0.666,0.667],"y":[1,1,1]},"o":{"x":[0.165,0.165,0.333],"y":[0.161,0.161,0]},"t":79.429,"s":[89.024,89.024,100]},{"t":87.142578125,"s":[0,0,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.369],[4.374,0],[0,4.368],[-4.369,0]],"o":[[0,4.368],[-4.369,0],[0,-4.369],[4.374,0]],"v":[[7.912,0],[-0.003,7.913],[-7.912,0],[-0.003,-7.913]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 4')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[294.654,58.146],"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":"Group 68","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[394.309,94.026],"ix":2},"a":{"a":0,"k":[294.654,58.146],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 68","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.374,0],[0,4.368],[-4.369,0],[0,-4.369]],"o":[[-4.369,0],[0,-4.369],[4.374,0],[0,4.368]],"v":[[-0.002,2.635],[-7.911,-5.278],[-0.002,-13.192],[7.911,-5.278]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.891,5.892],[5.897,-5.896],[-4.578,-6.965],[0,0],[-2.763,4.098]],"o":[[-5.896,-5.896],[-5.891,5.892],[2.763,4.192],[0,0],[4.656,-6.913]],"v":[[10.674,-14.757],[-10.675,-14.757],[-10.675,6.587],[-0.002,20.653],[10.674,6.587]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913999974728,0.243000000715,0.446999996901,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 5')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[294.654,63.424],"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":"Group 69","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[394.379,124.825],"ix":2},"a":{"a":0,"k":[294.668,64.161],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 69","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"mask","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1402.467,482.199,0],"ix":2},"a":{"a":0,"k":[273.982,94.508,0],"ix":1},"s":{"a":0,"k":[512,512,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,29.039],[29.039,0],[0,-29.039],[-29.038,0]],"o":[[0,-29.039],[-29.038,0],[0,29.039],[29.039,0]],"v":[[52.58,0],[-0.001,-52.579],[-52.58,0],[-0.001,52.579]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.944999964097,0.957000014361,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 6')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[273.982,94.508],"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":"Group 81","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Land","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1395.345,488.782,0],"ix":2},"a":{"a":0,"k":[281.345,286.782,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.512,-0.019],[1.596,-0.378],[0.651,-0.123],[1.096,1.354],[2.824,-0.975],[2.734,0.39],[2.106,0.969],[-0.13,-2.704],[-0.04,-0.457],[0.164,-0.676],[-0.092,-0.68],[-0.881,-1.086],[0.035,-0.11],[-2.197,0.34],[-4.431,1.183],[-0.413,2.407]],"o":[[-1.617,0.019],[-0.675,0.16],[-2.043,0.386],[-1.745,-2.157],[-2.379,0.821],[-2.291,-0.327],[-1.51,-0.695],[0.023,0.48],[0.064,0.736],[-0.159,0.653],[0.19,1.405],[-0.072,0.061],[-1.436,4.561],[4.536,-0.705],[1.744,-0.464],[0.448,-2.613]],"v":[[15.292,0.437],[10.53,0.048],[8.61,0.902],[4.377,-1.06],[-2.432,-3.602],[-9.134,-1.788],[-15.711,-3.619],[-19.855,-2.456],[-19.442,-1.131],[-19.901,0.938],[-20.084,2.815],[-18.125,6.503],[-18.294,6.749],[-0.794,9.038],[12.624,6.005],[19.728,2.822]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[277.676,141.928],"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":"Group 73","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[301.598,525.152],"ix":2},"a":{"a":0,"k":[276.546,142.35],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 73","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.431,0.054],[0.009,0.04],[3.752,-0.596],[1.037,0.042],[1.271,-0.892],[-3.295,-3.702],[0.84,-2.171],[-0.977,-0.84],[0.955,-1.862],[1.858,-0.854],[-0.069,-1.871],[-0.299,0.019],[-3.067,4.342],[-1.393,2.405],[-3.249,1.968]],"o":[[-0.001,-0.038],[-0.65,-3.134],[-0.148,-0.812],[-1.848,-0.078],[-2.441,1.711],[2.391,2.685],[-0.523,1.35],[1.427,1.225],[-0.979,1.906],[-1.591,0.732],[0.009,0.274],[5.541,-0.37],[1.597,-2.263],[1.826,-3.153],[0.476,-0.289]],"v":[[12.153,-6.881],[12.152,-6.993],[6.132,-13.64],[4.353,-15.069],[-0.681,-11.572],[-5.932,-5.232],[-7.376,-0.207],[-6.116,2.969],[-4.951,7.307],[-9.484,11.111],[-12.202,14.592],[-11.666,15.128],[0.373,7.448],[5.933,1.822],[12.37,-5.888]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[314.291,123.066],"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":"Group 74","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[488.545,426.569],"ix":2},"a":{"a":0,"k":[313.059,123.096],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 74","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.313,1.159],[0.303,0.455],[0.373,-0.182],[0.062,-0.006],[0.093,-0.24],[0.035,-0.091],[0.003,-0.01],[-0.176,-1.214],[0.556,-0.8],[0.351,-0.773],[-2.43,0.797],[-0.191,0.945],[-0.862,0.779],[-0.218,0.449]],"o":[[-0.146,-0.535],[-0.019,-0.338],[-0.057,-0.002],[-0.26,0.025],[-0.035,0.091],[-0.003,0.009],[-0.834,0.837],[0.117,0.809],[-0.455,0.653],[-0.674,1.481],[0.938,-0.306],[0.207,-1.019],[0.345,-0.312],[0.577,-1.194]],"v":[[2.114,-3.965],[1.571,-5.652],[0.754,-6.102],[0.588,-6.111],[0.07,-5.717],[-0.036,-5.444],[-0.04,-5.418],[-1.386,-2.315],[-1.388,-0.466],[-2.766,1.204],[-0.746,5.487],[1.08,3.29],[1.921,1.29],[2.863,0.407]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[295.295,106.852],"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":"Group 75","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[397.468,341.979],"ix":2},"a":{"a":0,"k":[295.271,106.574],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 75","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.206,3.048],[1.936,0.896],[3.054,0.754],[1.396,0.1],[0.984,0.874],[0.407,0.281],[0.862,-0.151],[1.134,-0.08],[0.88,-0.105],[0.581,-1.285],[0.807,-2.281],[-2.042,-2.368],[-0.391,-0.602],[0.371,-0.865],[-0.309,-0.692],[-0.916,-0.223],[-1.516,0.55],[-0.289,0.06],[-1.182,-0.025],[-0.751,-2.508],[-0.19,-2.631],[1.169,-1.224],[0.175,-0.485],[0.019,-0.253],[-0.331,-0.552],[-0.488,-0.971],[0.712,-1.647],[-0.489,-0.938],[-1.147,1.126],[-0.497,1.56],[-2.142,2.081],[0.267,0.202],[-0.903,1.229],[-0.404,1.397],[0.212,1.204],[-0.692,1.669]],"o":[[0.159,-2.346],[-2.855,-1.321],[-1.381,-0.341],[-1.336,-0.096],[-0.363,-0.322],[-0.716,-0.493],[-1.004,0.176],[-0.88,0.062],[-1.467,0.176],[-2.167,-0.678],[-1.136,3.209],[0.503,0.508],[0.288,0.962],[0.042,0.731],[0.395,0.884],[1.895,0.461],[0.325,-0.118],[0.791,-0.542],[2.739,0.061],[0.757,2.533],[0.142,1.983],[-0.029,0.462],[-0.103,0.226],[0.079,0.459],[0.506,0.847],[0.854,1.7],[-0.38,0.878],[1.211,2.318],[1.168,-1.145],[0.822,-2.581],[0.272,-0.265],[-2.053,-1.554],[0.854,-1.164],[0.337,-1.168],[-0.293,-1.672],[1.01,-2.439]],"v":[[19.249,-14.093],[15.564,-19.011],[6.298,-22.146],[2.251,-22.447],[-1.199,-23.955],[-2.209,-25.011],[-4.357,-25.479],[-7.133,-24.786],[-9.781,-24.791],[-13.175,-22.712],[-18.272,-19.666],[-15.904,-11.373],[-14.564,-9.709],[-14.689,-6.969],[-14.484,-5.337],[-12.335,-3.64],[-8.076,-5.049],[-7.159,-5.309],[-4.284,-6.195],[0.702,-1.962],[2.412,6.179],[-0.23,10.477],[-0.529,11.899],[-0.713,12.615],[-0.361,13.619],[1.496,15.765],[1.332,20.657],[0.994,23.312],[6.724,21.852],[9.297,17.712],[11.782,10.57],[11.673,9.726],[13.61,4.425],[15.636,0.587],[15.898,-3.059],[14.401,-8.367]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[278.395,94.719],"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":"Group 76","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[312.573,277.94],"ix":2},"a":{"a":0,"k":[278.69,94.066],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 76","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.542,0.819],[1.284,0.409],[-1.514,2.473],[-0.613,0.612],[-0.94,0.061],[-0.104,0.013],[-1.036,0.817],[-0.413,0.384],[-0.232,0.621],[-0.192,0.382],[-0.221,0.678],[0.85,-0.004],[0.448,-0.219],[0.348,-0.276],[0.049,-0.024],[0.106,-0.226],[1.263,-0.455],[0.453,-0.298],[0.779,0.4],[0.519,0.122],[0.356,0.03],[0.198,1.355],[-0.164,0.325],[-0.471,0.751],[0.258,0.123],[0.973,0.455],[1.391,-0.981],[2.492,-4.636],[1.677,-2.321],[0.543,-2.344],[-0.635,-1.66],[-0.274,-0.426],[-1.776,-0.721],[-0.822,-1.255],[1.798,-2.073],[-0.241,-1.263],[-0.743,-0.979],[-0.384,-1.636],[0.807,-1.495],[-1.437,-1.338],[-1.297,-1.537],[-0.741,-0.72],[0.445,-2.258],[-4.601,-1.984],[0.295,3.2],[0.005,0.966],[-0.696,1.093],[-0.757,1.075],[0.769,2.415],[-0.78,1.982],[-0.728,1.13],[0.547,1.798],[1.317,0.443],[0.925,0.143],[0.788,0.316],[0.545,0.764],[1.567,1.099],[0.96,0.185],[0.388,0.126],[-0.443,1.566],[1.294,1.342],[1.086,1.113],[0.121,0.123],[-1.62,1.457],[-0.354,-0.605],[-1.606,-0.569],[-1.164,-0.57],[-0.717,0.311],[-1.067,1.468],[-1.835,0.521],[-1.217,0.518],[-0.307,0.515],[-0.904,1.651]],"o":[[-1.191,-0.633],[-1.611,-0.514],[-0.089,-0.624],[0.641,-0.639],[0.097,-0.014],[1.279,-0.165],[0.439,-0.346],[0.465,-0.433],[0.148,-0.398],[0.302,-0.602],[0.167,-0.875],[-0.492,0.237],[-0.529,0.397],[-0.046,0.036],[-0.125,0.176],[-0.543,1.161],[-0.259,0.436],[-0.738,0.484],[-0.413,-0.212],[-0.327,-0.076],[-1.178,-0.101],[-0.059,-0.399],[0.274,-1.238],[0.195,-0.312],[0.092,-0.975],[-1.816,-0.851],[-4.359,3.075],[-1.359,2.526],[-1.385,1.919],[-0.402,1.736],[0.169,0.443],[1.591,1.056],[1.335,0.541],[1.638,2.5],[-0.209,1.32],[0.568,1.103],[0.983,1.295],[0.44,1.879],[-0.905,1.679],[1.504,1.399],[0.671,0.795],[1.691,1.642],[-0.716,3.64],[2.527,1.089],[-0.083,-0.898],[-0.008,-1.298],[0.706,-1.111],[1.454,-2.065],[-0.573,-1.8],[0.494,-1.255],[0.924,-1.43],[-0.465,-1.532],[-0.888,-0.299],[-0.867,-0.132],[-0.948,-0.38],[-1.113,-1.56],[-0.804,-0.562],[-0.392,-0.076],[-3.028,-0.988],[0.522,-1.847],[-1.081,-1.118],[-0.121,-0.123],[-1.234,-0.912],[0.767,0.13],[0.883,1.508],[1.495,0.531],[0.703,0.345],[1.857,-0.805],[1.166,-1.607],[1.316,-0.375],[0.588,-0.25],[0.962,-1.618],[0.722,-1.317]],"v":[[14.764,-24.981],[10.809,-26.304],[5.918,-29.84],[6.659,-31.782],[9.119,-32.752],[9.41,-32.796],[13.285,-33.997],[14.458,-35.221],[15.542,-36.351],[15.888,-37.502],[16.903,-39.209],[16.098,-40.92],[14.68,-40.274],[13.29,-39.127],[13.145,-39.053],[12.797,-38.451],[10.691,-35.949],[9.678,-34.812],[7.338,-34.706],[6.28,-35.432],[5.066,-35.386],[2.015,-37.411],[2.204,-38.489],[3.949,-41.904],[3.714,-42.631],[2.429,-44.912],[-2.846,-43.205],[-12.557,-31.429],[-17.13,-24.281],[-20.474,-17.984],[-20.096,-12.826],[-19.413,-11.528],[-14.419,-8.761],[-10.876,-6.482],[-12.666,1.238],[-12.596,5.113],[-10.638,8.256],[-7.867,12.545],[-9.439,17.055],[-8.998,21.548],[-6.374,26.327],[-4.068,28.399],[-2.373,33.984],[-0.314,44.674],[5.973,40.989],[5.552,38.618],[6.617,35.324],[9.018,32.188],[10.193,25.861],[9.518,20.761],[11.833,17.416],[13.952,11.141],[9.549,8.411],[6.825,7.755],[3.812,7.456],[1.81,5.097],[-2.489,1.015],[-4.937,-0.144],[-6.35,-0.248],[-7.399,-3.438],[-8.944,-7.354],[-12.221,-10.675],[-12.585,-11.045],[-12.007,-14.597],[-10.126,-12.145],[-6.91,-9.456],[-3.616,-7.919],[-1.501,-7.928],[1.586,-12.227],[6.82,-15.12],[11.051,-15.559],[12.202,-16.926],[14.979,-21.86]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[238.473,88.501],"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":"Group 77","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[111.938,259.931],"ix":2},"a":{"a":0,"k":[239.503,90.549],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 77","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.38,-1.525],[0.971,-1.312],[-0.089,-0.554],[-0.594,0.214],[-0.557,0.525],[-0.337,0.284],[-0.684,0.917],[-0.071,0.739],[-0.356,0.953],[-0.258,0.409],[1.378,1.003],[0.97,-0.321],[0.411,-1.082]],"o":[[-0.402,1.614],[-0.295,0.398],[0.148,0.926],[0.608,-0.218],[0.252,-0.327],[0.842,-0.71],[0.46,-0.615],[0.089,-0.928],[0.117,-0.31],[0.827,-1.309],[-0.934,-0.679],[-0.887,0.846],[-0.072,1.436]],"v":[[-1.208,0.106],[-3.785,4.229],[-5.103,6.389],[-2.799,7.369],[-1.003,5.917],[-0.134,4.995],[2.743,2.883],[3.226,1.165],[3.254,-1.821],[4.27,-3.154],[3.815,-6.904],[0.888,-7.262],[-0.93,-4.331]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[266.224,49.835],"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":"Group 78","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[248.149,51.394],"ix":2},"a":{"a":0,"k":[266.107,49.819],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 78","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.142,0.352],[0.618,0.356],[0.318,2.197],[1.906,1.369],[0.294,0.882],[-1.094,0.618],[0.689,1.999],[1.704,3.817],[0.991,0.761],[1.427,2.527],[2.626,2.196],[1.893,-1.069],[0.036,-0.104],[1.957,0],[1.753,0.633],[1.11,-1.618],[0.3,-0.355],[1.373,0.167],[0.786,-0.437],[0.235,-0.592],[0.085,-0.581],[1.835,-0.466],[-0.1,-0.268],[-0.463,-0.492],[-1.26,-0.089],[0.058,-0.537],[1.179,-0.991],[0.495,-0.208],[-0.302,-0.934],[0.009,-0.206],[-4.067,-2.918],[-0.678,-0.455],[-2.622,-0.298],[-1.732,-1.481],[-0.88,-1.951],[-1.784,-0.45],[-1.947,-4.094],[0.03,-0.181],[-0.747,-0.529],[-0.675,-0.713],[0.027,-1.331],[-1.59,-2.675],[-1.791,0.939],[-0.19,0.374],[-0.014,0.277],[-0.52,0.473],[-0.094,0.292],[0.021,0.87],[-0.115,1.787]],"o":[[-0.303,-0.749],[-2.274,-1.312],[-0.347,-2.408],[-0.83,-0.597],[-0.645,-1.936],[2.088,-1.178],[-1.362,-3.952],[-0.489,-1.096],[-1.686,-1.294],[-1.447,-2.564],[-2.235,-1.869],[-0.124,0.07],[-1.71,0.94],[-2.008,0],[-1.825,-0.659],[-0.282,0.413],[-0.965,1.141],[-0.86,-0.104],[-0.55,0.306],[-0.231,0.584],[-0.262,1.808],[-0.263,0.068],[0.285,0.763],[1.247,0.058],[0.467,0.034],[-0.173,1.605],[-0.494,0.208],[-0.724,0.77],[-0.147,0.556],[4.656,0.484],[0.673,0.483],[4.185,2.807],[2.171,0.246],[1.746,1.493],[0.542,1.201],[2.211,0.559],[0.095,0.203],[0.476,0.698],[0.777,0.551],[1.013,1.068],[-0.057,2.962],[0.731,1.232],[0.42,-0.22],[0.014,-0.276],[0.072,-0.741],[0.127,-0.265],[0.291,-0.885],[-0.087,-3.433],[0.024,-0.374]],"v":[[28.518,16.92],[26.963,15.768],[24.671,10.917],[20.914,5.69],[17.632,3.263],[20.58,0.909],[21.791,-4.149],[17.132,-15.888],[15.186,-19.195],[10.374,-21.666],[8.246,-30.638],[0.586,-28.124],[0.361,-27.852],[-5.154,-26.031],[-10.186,-28.053],[-15.04,-26.487],[-15.72,-24.965],[-20.424,-23.434],[-23.022,-23.135],[-24.182,-21.836],[-24.243,-20.046],[-27.284,-16.503],[-27.66,-15.843],[-26.561,-14.298],[-22.814,-14.263],[-21.863,-13.312],[-23.688,-10.616],[-25.171,-9.992],[-25.804,-7.435],[-25.967,-6.417],[-10.987,-6.002],[-9.217,-4.214],[-4.21,-3.51],[0.82,-1.772],[4.039,3.157],[9.243,9.504],[15.16,9.545],[15.231,10.122],[16.912,11.953],[19.343,13.46],[20.302,17.269],[21.525,25.446],[25.956,28.256],[26.703,27.317],[26.746,26.487],[27.635,24.667],[28.039,23.858],[27.956,21.327],[28.567,18.023]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[298.802,71.123],"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":"Group 79","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[415.736,161.807],"ix":2},"a":{"a":0,"k":[298.839,71.384],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 79","np":1,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.197,0.398],[0.45,-0.055],[0.674,0.447],[0.378,0.294],[-0.173,-0.257],[-0.482,-0.707],[-0.777,-0.291],[-0.304,1.424],[0.212,0.538]],"o":[[-0.754,0.411],[-0.874,0.107],[-0.444,-0.294],[0.184,0.192],[0.518,0.668],[0.455,0.668],[1.252,0.467],[0.126,-0.583],[-0.158,-0.405]],"v":[[2.192,-2.198],[0.055,-0.951],[-2.025,-1.616],[-3.255,-2.497],[-2.719,-1.831],[-1.603,0.527],[0.097,2.031],[3.128,0.66],[2.864,-1.01]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[309.069,83.866],"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":"Group 80","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[467.898,224.989],"ix":2},"a":{"a":0,"k":[309.027,83.724],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 80","np":1,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Stand","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1435.256,611.852,0],"ix":2},"a":{"a":0,"k":[321.256,409.852,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[19.198,2.787],[0,0],[0,0]],"o":[[0,0],[-19.198,2.787],[0,0],[0,0],[0,0]],"v":[[28.948,4.404],[28.948,4.404],[-28.948,4.404],[-4.448,-7.191],[4.448,-7.191]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 7')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[273.442,191.238],"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":"Group 70","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[285.702,773.676],"ix":2},"a":{"a":0,"k":[273.442,190.89],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 70","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[11.398,12.338],[1.348,-0.761],[0,-15.906],[11.714,-11.714],[16.307,-0.178],[11.855,11.666],[1.067,-1.115],[-17.637,-0.001],[-0.251,0.002],[-12.392,12.392],[0,17.798]],"o":[[-1.179,1.021],[10.842,11.539],[0,16.567],[-11.534,11.534],[-16.618,0.202],[-1.068,1.105],[12.563,12.391],[0.251,0],[17.52,-0.19],[12.586,-12.585],[0,-16.894]],"v":[[39.041,-55.893],[35.287,-53.164],[52.093,-10.741],[33.928,33.116],[-9.247,51.277],[-53.416,33.468],[-56.706,36.702],[-9.949,55.893],[-9.197,55.889],[37.188,36.377],[56.706,-10.741]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 7')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[282.664,103.613],"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":"Group 71","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[332.919,326.821],"ix":2},"a":{"a":0,"k":[282.664,103.613],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 71","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.457,0],[0,2.456],[0,0],[2.457,0],[0,-2.457],[0,0]],"o":[[2.457,0],[0,0],[0,-2.457],[-2.457,0],[0,0],[0,2.456]],"v":[[0.001,18.7],[4.449,14.252],[4.449,-14.251],[0.001,-18.7],[-4.449,-14.251],[-4.449,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[273.442,174.414],"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":"Group 72","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[285.701,689.319],"ix":2},"a":{"a":0,"k":[273.442,174.414],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 72","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,29.039],[29.039,0],[0,-29.039],[-29.038,0]],"o":[[0,-29.039],[-29.038,0],[0,29.039],[29.039,0]],"v":[[52.58,0],[-0.001,-52.579],[-52.58,0],[-0.001,52.579]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000020027,0.944999992847,0.957000017166,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 6')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[273.982,94.508],"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":"Group 81","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[288.467,280.199],"ix":2},"a":{"a":0,"k":[273.982,94.508],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 81","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-45.347,44.718],[-47.403,42.532],[45.347,-44.718],[47.403,-42.532]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.165000006557,0.168999999762,0.234999999404,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 2')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[277.019,97.385],"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":"Group 82","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[304.018,294.932],"ix":2},"a":{"a":0,"k":[277.019,97.385],"ix":1},"s":{"a":0,"k":[512,512],"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":"Layer 7/Office management 2 Outlines - Group 82","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Plant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1704.537,891.319,0],"ix":2},"a":{"a":0,"k":[332.98,174.414,0],"ix":1},"s":{"a":0,"k":[512,512,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.235,0.449],[5.042,-0.657],[3.385,-3.127],[-1.221,2.376],[0.254,-0.243],[2.048,-5.95],[0.627,-3.484],[1.468,4.058],[5.91,5.06],[-1.339,-3.719],[-0.694,-5.568],[5.395,4.948],[4.28,-1.192],[-6.856,-6.129],[-0.374,-0.656],[3.565,0.597],[-0.133,-0.22],[-10.225,-1.43],[-5.802,-3.146],[-0.394,0.175],[0.347,0.281],[6.171,-1.692],[4.51,-3.097],[-1.589,1.524]],"o":[[-1.139,-2.17],[-4.139,0.538],[1.245,-2.419],[2.851,-5.55],[-4.5,4.322],[-1.158,3.364],[-0.018,0.102],[-2.713,-7.496],[-0.33,-0.282],[1.907,5.289],[-0.781,-2.217],[-5.702,-5.232],[-0.449,0.125],[2.466,2.204],[-1.027,-1.27],[-13.838,-2.321],[-0.023,0.315],[9.119,1.277],[0.059,0.19],[18.372,-8.145],[-4.657,-3.766],[-5.216,1.428],[1.148,-1.835],[17.399,-16.682]],"v":[[37.845,7.737],[23.596,-0.913],[5.788,11.531],[10.936,1.02],[16.581,-16.772],[6.174,-1.408],[3.213,12.174],[2.177,-3.315],[-12.379,-21.392],[-3.508,-2.113],[0.05,14.285],[-7.711,-3.301],[-30.471,-8.422],[-11.279,0.496],[-3.654,13.665],[-15.131,3.875],[-37.946,11.117],[-16.419,9.384],[1.293,21.322],[3.508,21.5],[34.549,16.204],[19.002,11.246],[4.606,19.103],[8.268,13.72]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.573000021542,0.808000033509,1,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 8')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[333.03,174.325],"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":"Group 65","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Cloud 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[925.909,225.169,0],"ix":2},"a":{"a":0,"k":[180.904,44.306,0],"ix":1},"s":{"a":0,"k":[512,512,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.683,0.48],[0.089,0.164],[2.134,0.587],[0.19,0.076],[1.377,1.182],[2.563,-1.921],[5.042,-0.717],[-0.124,-4.231],[1.276,-3.149],[-0.38,-0.181],[-0.517,0],[0,0]],"o":[[-0.001,-0.152],[-1.013,-1.889],[-0.368,-0.102],[-2.211,-0.884],[-2.799,-2.403],[-0.355,-3.456],[-4.669,0.663],[-2.957,-0.322],[-0.208,0.514],[0.102,0.386],[0,0],[1.058,0]],"v":[[18.457,5.486],[18.339,5.01],[13.781,1.034],[10.672,0.909],[8.606,-1.094],[0.779,-1.444],[-5.396,-6.588],[-12.251,2.185],[-18.932,5.524],[-18.511,6.595],[-17.593,7.304],[17.907,7.304]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.944999964097,0.957000014361,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 6')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[180.976,44.011],"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":"Group 83","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Cloud 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[708.913,52.106,0],"ix":2},"a":{"a":0,"k":[138.522,10.505,0],"ix":1},"s":{"a":0,"k":[512,512,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.065,0],[0,0],[5.536,-1.708],[0.728,1.782],[1.783,0.498],[2.551,-2.009],[4.813,-0.218],[0.128,-4.785],[2.64,-0.902],[1.685,-0.741],[2.02,-2.161],[-0.314,-1.06],[-0.76,-0.593],[0,0],[-0.316,0.32]],"o":[[0,0],[-4.554,-3.678],[0.52,-1.671],[-0.745,-1.82],[-3.26,-0.912],[-0.929,-4.4],[-5.097,0.233],[-2.677,-0.732],[-2.283,0.779],[-2.283,1.004],[-0.877,0.938],[0.433,0.834],[0,0],[0.452,0.273],[0.694,-0.474]],"v":[[33.522,7.939],[33.438,7.939],[17.636,4.793],[18.254,-0.223],[13.699,-3.604],[4.377,-2.074],[-5.093,-9.994],[-13.851,-0.387],[-22.129,-0.512],[-26.714,3.3],[-33.652,4.699],[-34.442,7.787],[-32.595,9.939],[32.787,9.939],[34.062,9.766]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.944999964097,0.957000014361,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 6')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[138.571,10.462],"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":"Group 84","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Spruce_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[336.467,561.683,0],"ix":2},"a":{"a":0,"k":[418.467,533.683,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.439,0.582],[3.829,12.566],[0.382,-0.82],[-0.002,-0.303],[-0.053,0.086],[-1.877,1.033],[0.395,-1.044],[-0.725,0.477],[-1.039,0.925],[0.062,-1.413],[-0.606,0.566],[-0.98,1.474],[-0.655,-1.255],[-0.26,0.768],[-0.073,1.534],[-3.227,-0.547],[0.206,0.792],[0,0],[-2.823,-0.298]],"o":[[-7.919,-10.475],[-0.231,-0.757],[-5.57,11.935],[-0.595,1.075],[1.877,-1.033],[-0.181,1.094],[-0.258,0.811],[1.197,-0.788],[-0.062,1.413],[-0.041,0.902],[1.347,-1.26],[0.545,1.291],[0.421,0.808],[0.536,-1.587],[2.721,1.627],[0.738,0.124],[0,0],[2.372,1.262],[0.713,0.075]],"v":[[19.447,15.09],[1.76,-19.554],[-0.067,-19.793],[-19.291,15.707],[-17.387,16.406],[-11.757,13.305],[-12.608,16.513],[-11.139,17.642],[-7.813,15.083],[-8,19.323],[-6.293,20.03],[-2.852,15.984],[-1.076,19.805],[0.752,19.566],[1.635,15.029],[10.412,18.242],[11.642,17.012],[10.946,14.332],[18.584,16.595]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[86.217,23.519],"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":"Group 7","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[436.902,196.111],"ix":2},"a":{"a":0,"k":[86.324,23.528],"ix":1},"s":{"a":0,"k":[495,495],"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":"Layer 8/Summer camping 20 Outlines - Group 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.731,0.491],[3.306,8.604],[5.833,2.761],[3.15,-4.247],[1.748,-2.81],[2.292,-4.055],[-0.843,0.189],[-2.573,1.782],[0.603,-1.176],[-0.877,0.284],[-2.429,2.605],[0.463,-2.482],[-0.713,0.823],[-0.788,1.573],[-0.474,-1.45],[-0.38,0.837],[-0.476,1.762],[-1.678,-2.19],[0.133,1.116],[0,0],[-1.8,-1.077],[0.15,0.82],[0.066,0.988],[-3.123,-1.1],[0.064,0.625],[0.064,0.615],[-1.891,-0.798],[0.159,0.658],[0.493,2.049],[-3.871,-0.498]],"o":[[-7.761,-5.213],[-2.112,-5.493],[-4.874,-2.308],[-1.969,2.655],[-2.576,4.143],[-0.442,0.784],[3.201,-0.715],[-0.465,1.212],[-0.375,0.732],[3.529,-1.144],[0.208,2.395],[-0.166,0.892],[1.229,-1.419],[0.365,1.464],[0.242,0.741],[0.776,-1.707],[1.258,2.402],[0.515,0.674],[0,0],[1.498,1.374],[0.803,0.481],[-0.198,-1.088],[1.855,2.449],[0.572,0.201],[-0.063,-0.616],[1.291,1.338],[0.748,0.316],[-0.492,-2.049],[2.763,2.398],[1.07,0.137]],"v":[[30.429,15.777],[14.396,-5.959],[5.169,-20.335],[-8.16,-16.87],[-13.104,-8.191],[-30.717,15.137],[-29.588,16.606],[-21.013,12.887],[-22.607,16.464],[-21.477,17.934],[-12.956,11.998],[-13.328,19.146],[-11.656,20.119],[-8.665,15.69],[-7.418,20.053],[-5.59,20.293],[-3.731,15.124],[0.645,21.969],[2.508,21.465],[1.729,14.898],[6.625,18.552],[8.094,17.423],[7.706,14.355],[14.797,19.923],[16.063,18.958],[15.872,17.112],[20.6,20.261],[21.829,19.031],[20.353,12.884],[29.924,17.641]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000002623,0.513999998569,0.885999977589,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[85.887,46.78],"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":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[434.798,313.677],"ix":2},"a":{"a":0,"k":[85.899,47.278],"ix":1},"s":{"a":0,"k":[495,495],"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":"Layer 8/Summer camping 20 Outlines - Group 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.61,0.729],[5.627,10.498],[0.166,0.221],[3.979,1.923],[0.035,0.013],[2.708,0.49],[3.221,0.159],[2.029,-1.189],[1.132,-2.348],[1.854,-3.819],[7.842,-4.457],[-0.938,-0.08],[-3.38,1.162],[0.856,-0.78],[-0.888,0.119],[-3.155,2.371],[0.577,-1.206],[-0.892,0.305],[-2.992,1.93],[0.396,-1.686],[-0.763,0.503],[-1.799,2.578],[-1.366,-2.123],[-0.109,0.962],[-0.578,1.529],[-3.247,-1.333],[0.309,0.688],[0.394,1.509],[-4.246,-0.43],[0.403,0.594],[0.438,0.734],[-3.307,0.144],[0.453,0.66],[0.757,1.003],[-4.716,-1.32]],"o":[[-7.589,-9.064],[0.062,-0.231],[-2.637,-3.525],[-0.036,-0.017],[-2.576,-1.218],[-3.176,-0.575],[-2.232,-0.109],[-2.432,1.424],[-1.844,3.824],[-3.852,7.936],[-0.92,0.522],[3.726,0.322],[-0.69,0.871],[-0.824,0.751],[4.076,-0.551],[-0.391,1.139],[-0.345,0.721],[3.411,-1.162],[-0.237,1.671],[-0.19,0.8],[2.704,-1.78],[0.918,2.292],[0.569,0.886],[0.114,-1.653],[2.106,2.635],[0.906,0.372],[-0.673,-1.498],[3.323,2.377],[0.742,0.074],[-0.486,-0.719],[2.684,1.525],[0.703,-0.031],[-0.716,-1.04],[4.751,1.189],[1.024,0.287]],"v":[[42.192,17.846],[19.784,-10.67],[19.663,-11.368],[9.961,-19.429],[9.858,-19.456],[1.643,-21.837],[-7.978,-22.826],[-15.714,-22.543],[-20.243,-14.455],[-25.775,-2.982],[-41.882,15.934],[-41.378,17.797],[-30.832,16.536],[-33.137,18.998],[-32.163,20.67],[-21.362,16.276],[-22.787,19.74],[-21.658,21.208],[-12.099,16.6],[-13.038,21.573],[-11.57,22.701],[-4.882,16.228],[-1.5,22.799],[0.363,22.294],[1.403,17.52],[9.304,23.36],[10.434,21.891],[8.87,17.421],[20.108,21.588],[20.971,20.083],[19.594,17.903],[28.366,20.332],[29.229,18.827],[27.015,15.769],[41.219,19.517]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[87.513,72.574],"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":"Group 9","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[442.964,439.493],"ix":2},"a":{"a":0,"k":[87.548,72.696],"ix":1},"s":{"a":0,"k":[495,495],"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":"Layer 8/Summer camping 20 Outlines - Group 9","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.624,0.534],[3.818,8.406],[2.649,2.905],[3.556,0.907],[10.504,-0.151],[3.92,-7.223],[12.505,-8.825],[-1.049,-0.013],[-4.658,1.794],[0.95,-1.499],[-0.729,-0.024],[-4.244,3.173],[0.871,-2.21],[-0.678,0.259],[-3.579,3.504],[-0.49,-2.368],[-0.531,0.448],[-1.684,3.189],[-2.369,-2.781],[-0.316,0.401],[-0.993,3.099],[-4,-2.495],[0.603,0.826],[0.404,2.79],[-5.777,-0.998],[0.465,0.808],[0.358,2.039],[-4.703,-1.552],[0.211,0.708],[0.562,1.886],[-4.985,-0.638]],"o":[[-7.166,-6.122],[-1.604,-3.527],[-2.59,-2.84],[-10.173,-2.593],[-7.625,0.109],[-11.388,10.005],[-0.782,0.551],[5.081,0.062],[-0.618,1.616],[-0.421,0.664],[5.557,0.187],[-0.59,2.273],[-0.268,0.684],[4.742,-1.808],[0.872,2.221],[0.166,0.796],[2.811,-2.367],[2.371,2.781],[0.323,0.378],[2.076,-2.631],[2.896,3.638],[0.808,0.505],[-1.741,-2.388],[4.45,3.622],[0.83,0.144],[-1.111,-1.93],[3.89,2.952],[0.725,0.24],[-0.561,-1.887],[4.61,1.87],[0.852,0.109]],"v":[[56.458,17.148],[41.669,-5.824],[35.943,-16.744],[25.536,-21.238],[-5.727,-25.016],[-25.46,-16.306],[-56.299,16.744],[-55.794,18.607],[-41.305,16.009],[-43.633,20.643],[-42.77,22.148],[-28.501,16.587],[-30.68,23.292],[-29.449,24.522],[-17.063,16.634],[-15.048,23.436],[-13.376,23.877],[-6.71,15.638],[0.398,23.982],[1.813,23.982],[6.368,15.513],[16.639,24.662],[18.007,23.294],[14.811,15.614],[30.109,22.554],[31.24,21.086],[29.078,15.277],[41.9,22.011],[43.132,20.781],[41.447,15.12],[55.751,18.855]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000002623,0.513999998569,0.885999977589,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[82.474,103.779],"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":"Group 10","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[417.796,592.781],"ix":2},"a":{"a":0,"k":[82.464,103.663],"ix":1},"s":{"a":0,"k":[495,495],"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":"Layer 8/Summer camping 20 Outlines - Group 10","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.618,0.903],[5.623,13.358],[0.479,-0.014],[25.821,-2.676],[-0.775,-0.343],[10.123,-9.507],[-0.713,-0.188],[-5.283,2.574],[1.08,-2.641],[-0.659,0.129],[-4.333,4.642],[0.33,-2.518],[-0.595,0.298],[-3.132,3.103],[-0.414,-2.263],[-0.509,0.328],[-1.654,4.162],[-2.561,-3.278],[-0.051,0.766],[-0.245,3.67],[-3.397,-3.017],[-0.212,0.755],[-1.066,1.244],[-1.709,-1.403],[-1.906,-2.227],[0.032,0.834],[-0.308,2.913],[-4.13,-2.425],[-0.033,0.747],[-0.828,2.947],[-4.233,-2.566],[-0.009,0.746],[-1.094,3.16],[-3.667,-1.325],[0.333,0.714],[0.008,2.487],[-2.275,-1.066]],"o":[[-8.067,-11.781],[-0.17,-0.402],[-25.945,0.815],[-1.084,0.113],[-7.368,11.759],[-0.548,0.516],[5.869,1.548],[-1.282,2.54],[-0.316,0.77],[6.404,-1.256],[-0.329,2.518],[-0.106,0.815],[3.999,-2.002],[0.414,2.262],[0.114,0.625],[3.926,-2.523],[1.327,3.829],[0.582,0.745],[0.245,-3.67],[2.592,3.669],[0.555,0.493],[0.438,-1.56],[1.469,-1.713],[2.264,1.859],[0.565,0.659],[-0.109,-2.964],[2.938,3.676],[0.677,0.397],[0.131,-3.112],[3.066,3.801],[0.657,0.398],[0.039,-3.394],[3.353,1.964],[0.9,0.325],[-1.131,-2.419],[1.922,1.499],[0.818,0.385]],"v":[[65.141,13.229],[40.057,-25.766],[39.092,-26.499],[-38.475,-17.029],[-38.943,-15.103],[-65.21,16.852],[-64.768,18.523],[-47.809,16.954],[-51.35,24.718],[-50.122,25.949],[-33.913,16.968],[-34.902,24.52],[-33.396,25.383],[-22.788,17.788],[-21.548,24.575],[-20.079,25.173],[-11.704,15.126],[-5.906,25.699],[-4.199,24.992],[-3.465,13.982],[5.475,23.985],[7.146,23.544],[9.008,18.896],[12.044,18.847],[18.039,25.854],[19.746,25.148],[20.039,16.39],[30.565,25.501],[32.072,24.637],[33.524,15.627],[44.393,25.126],[45.897,24.261],[47.591,14.531],[58.067,19.45],[59.199,17.981],[57.561,10.781],[63.772,14.597]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.250999987125,0.575999975204,0.964999973774,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 3')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[82.692,137.506],"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":"Group 11","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[418.467,759.438],"ix":2},"a":{"a":0,"k":[82.599,137.331],"ix":1},"s":{"a":0,"k":[495,495],"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":"Layer 8/Summer camping 20 Outlines - Group 11","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.802,10.04],[0.301,2.281],[0.895,0.716],[1.422,-0.02],[0,0],[0.094,-0.038],[0.068,-0.001],[-0.475,-0.006],[2.609,-13.538],[-0.261,-0.018],[-7.03,0.785],[0.043,0.257]],"o":[[-0.184,-2.293],[-0.144,-1.091],[-1.201,-0.959],[0,0],[-0.098,-0.037],[-0.069,0.001],[-0.48,0.007],[0.215,13.784],[-0.043,0.229],[7.365,0.507],[0.261,-0.029],[-1.65,-9.935]],"v":[[7.054,-10.219],[6.542,-17.132],[5.194,-20.059],[0.796,-20.783],[-6.459,-20.688],[-6.762,-20.684],[-6.966,-20.68],[-6.975,-19.929],[-10.749,20.032],[-10.384,20.51],[10.386,20.232],[10.749,19.756]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.24699999392,0.259000003338,0.379999995232,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 7')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[82.463,159.349],"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":"Group 12","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[417.794,868.539],"ix":2},"a":{"a":0,"k":[82.463,159.371],"ix":1},"s":{"a":0,"k":[495,495],"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":"Layer 8/Summer camping 20 Outlines - Group 12","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Floor","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[942.484,1007.751,0],"ix":2},"a":{"a":0,"k":[184.141,197.155,0],"ix":1},"s":{"a":0,"k":[512,512,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-2.593],[101.561,0],[0,2.593],[-101.56,0]],"o":[[0,2.593],[-101.56,0],[0,-2.593],[101.561,0]],"v":[[183.892,-0.001],[-0.001,4.694],[-183.892,-0.001],[-0.001,-4.694]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.944999964097,0.957000014361,1],"ix":4,"x":"var $bm_rt;\ntry {\n $bm_rt = thisComp.layer('Controller')('Effects')('Color 6')('ADBE Color Control-0001');\n} catch (e) {\n $bm_rt = value;\n}"},"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":[184.141,197.155],"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":"Group 85","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Woman (scene 3)","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[747,667.5,0],"ix":2},"a":{"a":0,"k":[400,450,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":900,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"BG elements (scene 3)","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[957.5,538,0],"ix":2},"a":{"a":0,"k":[949.5,516,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1899,"h":1032,"ip":0,"op":120,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/raw/sign_up_animation.json b/android/HowAboutTrip/app/src/main/res/raw/sign_up_animation.json
new file mode 100644
index 00000000..f86e393f
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/raw/sign_up_animation.json
@@ -0,0 +1 @@
+{"v":"5.7.12","fr":30,"ip":0,"op":90,"w":252,"h":252,"nm":"main","ddd":0,"assets":[],"fonts":{"list":[{"fName":"Montserrat-Bold","fFamily":"Montserrat","fStyle":"Bold","ascent":74.1989135742188}]},"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[100]},{"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":100,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":110,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":130,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":145,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":155,"s":[100]},{"t":160,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-2.63],[2.566,0],[0,2.63],[-2.566,0]],"o":[[0,2.63],[-2.566,0],[0,-2.63],[2.566,0]],"v":[[-44.259,-59.35],[-48.904,-54.589],[-53.55,-59.35],[-48.904,-64.111]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.890196084976,0.945098042488,0.984313726425,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":100,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":110,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":130,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":145,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":155,"s":[0]},{"t":160,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-2.63],[2.566,0],[0,2.63],[-2.566,0]],"o":[[0,2.63],[-2.566,0],[0,-2.63],[2.566,0]],"v":[[-56.928,-59.35],[-61.573,-54.589],[-66.219,-59.35],[-61.573,-64.111]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.890196084976,0.945098042488,0.984313726425,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[100]},{"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":100,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":110,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":130,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":145,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":155,"s":[100]},{"t":160,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-2.63],[2.566,0],[0,2.63],[-2.566,0]],"o":[[0,2.63],[-2.566,0],[0,-2.63],[2.566,0]],"v":[[-69.597,-59.35],[-74.242,-54.589],[-78.888,-59.35],[-74.242,-64.111]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.890196084976,0.945098042488,0.984313726425,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.088],[3.088,0],[0,3.088],[-3.088,0]],"o":[[0,3.088],[-3.088,0],[0,-3.088],[3.088,0]],"v":[[-87.118,-9.954],[-92.71,-4.362],[-98.302,-9.954],[-92.71,-15.546]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"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":[137.345,174.696,0],"to":[-9.333,-7.333,0],"ti":[9.333,7.333,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"t":15,"s":[81.345,130.696,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":20,"s":[81.345,130.696,0],"to":[11.833,6.5,0],"ti":[-11.833,-6.5,0]},{"t":27,"s":[152.345,169.696,0]}],"ix":2,"l":2},"a":{"a":0,"k":[10.345,17.696,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":15,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":18,"s":[110,110,100]},{"t":21,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.233,-1.568],[0,0],[-2.153,3.171],[0,0],[0,0],[-2.174,1.654],[0,0]],"o":[[-1.059,0.884],[0,0],[0.564,3.792],[0,0],[0,0],[1.507,2.278],[0,0],[0,0]],"v":[[11.869,18.693],[10.393,22.526],[16.754,65.315],[24.398,67.06],[30.261,58.425],[46.769,83.381],[53.569,84.534],[59.311,80.165]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.240553642722,0.28746511422,0.309803921569,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":"Group 1","np":2,"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],[1.794,2.059],[0,0],[0,0],[3.504,1.555],[0,0],[1.158,-0.966],[0,0]],"o":[[2.174,-1.654],[0,0],[0,0],[3.631,-1.23],[0,0],[-1.584,-0.703],[0,0],[0,0]],"v":[[64.511,76.208],[65.213,69.348],[45.563,46.783],[55.448,43.434],[55.805,35.602],[16.262,18.06],[11.869,18.693],[59.311,80.165]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588235294,0.352941176471,0.392156892664,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":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":5,"nm":"|||||||||||||","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[77.157,143.452,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"t":{"d":{"k":[{"s":{"s":26.6488609313965,"f":"Montserrat-Bold","t":"|","ca":0,"j":0,"tr":0,"lh":31.9786331176758,"ls":0,"fc":[0.071,0.2,0.294]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[{"nm":"Animator 1","s":{"t":0,"xe":{"a":0,"k":0,"ix":7},"ne":{"a":0,"k":0,"ix":8},"a":{"a":0,"k":100,"ix":4},"b":1,"rn":0,"sh":1,"s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":17,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[100]},{"t":23,"s":[0]}],"ix":1},"r":1},"a":{"o":{"a":0,"k":0,"ix":9}}}]},"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":5,"nm":"ABCD36","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[77.157,143.452,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"t":{"d":{"k":[{"s":{"s":26.6488609313965,"f":"Montserrat-Bold","t":"FB5D01","ca":0,"j":0,"tr":0,"lh":31.9786331176758,"ls":0,"fc":[0.071,0.2,0.294]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[{"nm":"Animator 1","s":{"t":0,"xe":{"a":0,"k":0,"ix":7},"ne":{"a":0,"k":0,"ix":8},"a":{"a":0,"k":100,"ix":4},"b":1,"rn":0,"sh":1,"s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":23,"s":[0]},{"t":68,"s":[100]}],"ix":1},"r":1},"a":{"o":{"a":0,"k":0,"ix":9}}}]},"ip":23,"op":173,"st":23,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.096,11.694],[1.436,3.137],[6.626,7.822],[34.572,0],[0,-62.394],[-62.394,0],[-20.723,24.463],[-4.608,13.156],[0,13.093]],"o":[[-1.15,-3.283],[-4.321,-9.433],[-20.723,-24.463],[-62.394,0],[0,62.394],[34.572,0],[8.829,-10.423],[4.096,-11.694],[0,-13.093]],"v":[[106.625,-37.348],[102.739,-46.977],[86.221,-72.965],[0,-112.974],[-112.974,0],[0,112.974],[86.221,72.965],[106.625,37.348],[112.974,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","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":"Group 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.458,0],[0,0],[0,-3.457],[0,0],[-3.458,0],[0,0],[0,3.457],[0,0]],"o":[[0,0],[-3.458,0],[0,0],[0,3.457],[0,0],[3.458,0],[0,0],[0,-3.457]],"v":[[64.802,-17.804],[-53.181,-17.804],[-59.451,-11.534],[-59.451,25.836],[-53.181,32.106],[64.802,32.106],[71.071,25.836],[71.071,-11.534]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","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":"Group 2","np":1,"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.623,0],[0,0],[0,2.623],[0,0],[-2.623,0],[0,0],[0,-2.623],[0,0]],"o":[[0,0],[-2.623,0],[0,0],[0,-2.623],[0,0],[2.623,0],[0,0],[0,2.623]],"v":[[70.881,36.666],[-59.261,36.666],[-64.011,31.916],[-64.011,-17.614],[-59.261,-22.364],[70.881,-22.364],[75.631,-17.614],[75.631,31.916]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960790157,0.96862745285,1,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":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.111,0],[0,0],[0,-6.263],[0,0],[0,0],[0,0]],"o":[[0,0],[-6.111,0],[0,0],[0,0],[0,0],[0,-6.263]],"v":[[95.561,-72.965],[-80.408,-72.965],[-91.472,-61.625],[-91.472,-46.977],[106.625,-46.977],[106.625,-61.625]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.070588238537,0.20000000298,0.29411765933,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":"Group 1","np":2,"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],[-6.111,0],[0,0],[0,6.263],[0,0],[0,0]],"o":[[0,6.263],[0,0],[6.111,0],[0,0],[0,0],[0,0]],"v":[[-91.472,61.625],[-80.408,72.965],[95.561,72.965],[106.625,61.625],[106.625,-46.977],[-91.472,-46.977]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.309803932905,0.674509823322,0.972549021244,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":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","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":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"++++","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[101.537,37.094,0],"ix":2,"l":2},"a":{"a":0,"k":[-24.463,-88.906,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":10,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":20,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":40,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":50,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":70,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":80,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":90,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":100,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":110,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":120,"s":[0,0,100]},{"t":130,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.596,0],[0,0],[0,0],[0,-3.194],[0,0],[0,0],[0,-1.243],[-1.596,0],[0,0],[0,0],[-1.243,0],[0,1.596],[0,0],[0,0],[0,1.243]],"o":[[0,0],[0,0],[0,-3.19],[0,0],[0,0],[-1.596,0],[0,1.241],[0,0],[0,0],[0,1.596],[1.242,0],[0,0],[0,0],[1.596,0],[0,-1.241]],"v":[[-18.355,-91.424],[-21.962,-91.424],[-21.962,-95.032],[-26.961,-95.032],[-26.961,-91.424],[-30.57,-91.424],[-33.002,-88.923],[-30.57,-86.425],[-26.961,-86.425],[-26.961,-82.817],[-24.461,-80.386],[-21.962,-82.817],[-21.962,-86.425],[-18.355,-86.425],[-15.923,-88.926]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.533333361149,0.482352942228,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Ellipes","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-6.663],[6.663,0],[0,6.663],[-6.663,0]],"o":[[0,6.663],[-6.663,0],[0,-6.663],[6.663,0]],"v":[[61.359,-72.965],[49.294,-60.9],[37.229,-72.965],[49.294,-85.03]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0.96862745285,0.800000011921,0.498039215803,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22,"s":[1,0.533333361149,0.482352972031,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[0.309803932905,0.674509823322,0.972549080849,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":68,"s":[0.917647123337,0.592156887054,0.211764723063,1]},{"t":90,"s":[0.890196084976,0.945098042488,0.984313726425,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"gear 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[15]},{"t":90,"s":[375]}],"ix":10},"p":{"a":0,"k":[145.154,237.027,0],"ix":2,"l":2},"a":{"a":0,"k":[13.654,69.027,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.015,-4.165],[-4.086,0.012],[0.056,4.297],[3.946,-0.013]],"o":[[0.015,4.159],[4.26,-0.013],[-0.05,-3.882],[-4.209,0.014]],"v":[[6.309,68.847],[13.716,76.338],[21.27,68.594],[13.812,61.371]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.816,-0.082],[0.252,1.736],[1.616,0.504],[1.027,-1.139],[1.39,1.123],[0.807,0.724],[-0.984,1.258],[0.887,1.526],[1.285,-0.022],[0.187,2.108],[0.112,0.905],[-1.478,0.195],[-0.448,1.735],[1.116,1.001],[-1.078,1.329],[-0.717,0.813],[-1.311,-1.002],[-1.369,0.721],[0.114,1.915],[-1.379,0.196],[-1.222,0.057],[-0.197,-1.489],[-1.438,-0.466],[-1.261,1.439],[-1.035,-0.768],[-0.967,-0.885],[0.899,-1.15],[-0.718,-1.41],[-1.675,0.116],[-0.226,-1.317],[-0.023,-1.312],[1.329,-0.175],[0.481,-1.717],[-1.139,-1.012],[1.12,-1.417],[0.708,-0.821],[1.194,0.933],[1.529,-0.807],[0.033,-1.554],[1.99,-0.296]],"o":[[-1.953,0.057],[-0.234,-1.609],[-1.53,-0.478],[-1.208,1.339],[-0.844,-0.681],[-1.211,-1.087],[1.061,-1.356],[-0.709,-1.219],[-2.1,0.036],[-0.08,-0.908],[-0.186,-1.503],[1.801,-0.238],[0.374,-1.449],[-1.288,-1.154],[0.683,-0.842],[1.1,-1.246],[1.318,1.006],[1.533,-0.807],[-0.081,-1.352],[1.212,-0.172],[1.52,-0.071],[0.204,1.543],[1.646,0.533],[0.83,-0.947],[1.053,0.781],[1.035,0.948],[-0.994,1.272],[0.759,1.49],[1.301,-0.09],[0.222,1.293],[0.024,1.373],[-1.793,0.236],[-0.4,1.427],[1.352,1.201],[-0.672,0.851],[-0.989,1.147],[-1.363,-1.065],[-1.415,0.748],[-0.042,1.98],[-1.014,0.151]],"v":[[14.124,90.48],[10.971,88.198],[8.449,85.359],[5,86.195],[1.14,86.403],[-1.356,84.316],[-1.851,80.753],[-1.66,76.824],[-4.366,75.217],[-7.473,72.329],[-7.762,69.608],[-5.775,66.587],[-2.834,63.776],[-3.652,60.439],[-3.837,56.646],[-1.757,54.145],[1.788,53.61],[5.389,53.635],[7.734,50.206],[9.95,47.932],[13.607,47.576],[16.359,49.684],[18.75,52.221],[22.834,51.484],[25.87,51.393],[28.91,53.893],[29.256,57.199],[29.126,60.814],[32.325,62.864],[34.725,64.97],[35.098,68.883],[33.206,71.442],[30.236,74.256],[30.971,77.557],[31.18,81.417],[29.107,83.924],[25.604,84.454],[21.682,84.28],[19.669,87.329],[16.981,90.186]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,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":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"gear","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":90,"s":[360]}],"ix":10},"p":{"a":0,"k":[139.654,195.027,0],"ix":2,"l":2},"a":{"a":0,"k":[13.654,69.027,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.015,-4.165],[-4.086,0.012],[0.056,4.297],[3.946,-0.013]],"o":[[0.015,4.159],[4.26,-0.013],[-0.05,-3.882],[-4.209,0.014]],"v":[[6.309,68.847],[13.716,76.338],[21.27,68.594],[13.812,61.371]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.816,-0.082],[0.252,1.736],[1.616,0.504],[1.027,-1.139],[1.39,1.123],[0.807,0.724],[-0.984,1.258],[0.887,1.526],[1.285,-0.022],[0.187,2.108],[0.112,0.905],[-1.478,0.195],[-0.448,1.735],[1.116,1.001],[-1.078,1.329],[-0.717,0.813],[-1.311,-1.002],[-1.369,0.721],[0.114,1.915],[-1.379,0.196],[-1.222,0.057],[-0.197,-1.489],[-1.438,-0.466],[-1.261,1.439],[-1.035,-0.768],[-0.967,-0.885],[0.899,-1.15],[-0.718,-1.41],[-1.675,0.116],[-0.226,-1.317],[-0.023,-1.312],[1.329,-0.175],[0.481,-1.717],[-1.139,-1.012],[1.12,-1.417],[0.708,-0.821],[1.194,0.933],[1.529,-0.807],[0.033,-1.554],[1.99,-0.296]],"o":[[-1.953,0.057],[-0.234,-1.609],[-1.53,-0.478],[-1.208,1.339],[-0.844,-0.681],[-1.211,-1.087],[1.061,-1.356],[-0.709,-1.219],[-2.1,0.036],[-0.08,-0.908],[-0.186,-1.503],[1.801,-0.238],[0.374,-1.449],[-1.288,-1.154],[0.683,-0.842],[1.1,-1.246],[1.318,1.006],[1.533,-0.807],[-0.081,-1.352],[1.212,-0.172],[1.52,-0.071],[0.204,1.543],[1.646,0.533],[0.83,-0.947],[1.053,0.781],[1.035,0.948],[-0.994,1.272],[0.759,1.49],[1.301,-0.09],[0.222,1.293],[0.024,1.373],[-1.793,0.236],[-0.4,1.427],[1.352,1.201],[-0.672,0.851],[-0.989,1.147],[-1.363,-1.065],[-1.415,0.748],[-0.042,1.98],[-1.014,0.151]],"v":[[14.124,90.48],[10.971,88.198],[8.449,85.359],[5,86.195],[1.14,86.403],[-1.356,84.316],[-1.851,80.753],[-1.66,76.824],[-4.366,75.217],[-7.473,72.329],[-7.762,69.608],[-5.775,66.587],[-2.834,63.776],[-3.652,60.439],[-3.837,56.646],[-1.757,54.145],[1.788,53.61],[5.389,53.635],[7.734,50.206],[9.95,47.932],[13.607,47.576],[16.359,49.684],[18.75,52.221],[22.834,51.484],[25.87,51.393],[28.91,53.893],[29.256,57.199],[29.126,60.814],[32.325,62.864],[34.725,64.97],[35.098,68.883],[33.206,71.442],[30.236,74.256],[30.971,77.557],[31.18,81.417],[29.107,83.924],[25.604,84.454],[21.682,84.28],[19.669,87.329],[16.981,90.186]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,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":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Gear_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":90,"s":[-360]}],"ix":10},"p":{"a":0,"k":[108.05,216.774,0],"ix":2,"l":2},"a":{"a":0,"k":[-17.95,90.774,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.375,0.047],[0.004,3.262],[3.428,-0.055],[-0.026,-3.347]],"o":[[3.291,-0.046],[-0.005,-3.425],[-3.372,0.055],[0.026,3.353]],"v":[[-17.807,96.659],[-11.814,90.628],[-17.999,84.557],[-23.99,90.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.001,-0.013],[0.449,0.07],[0.1,1.364],[1.115,0.469],[1.008,-0.86],[1.077,0.951],[0.49,0.555],[-0.993,1.128],[0.681,0.922],[0.037,0.193],[0.902,0.059],[0.022,1.882],[0,0.428],[-1.948,0.144],[-0.319,0.683],[1.204,1.287],[-0.53,0.797],[-0.604,0.562],[-1.335,-1.135],[-0.634,0.428],[-0.081,0.024],[-0.118,1.812],[-0.975,0.055],[-0.937,-0.064],[-0.089,-1.403],[-0.851,-0.155],[-0.094,-0.061],[-1.225,0.991],[-0.854,-0.791],[-0.512,-0.61],[0.958,-1.111],[-0.263,-0.798],[-1.671,-0.135],[-0.132,-0.936],[0.144,-0.961],[1.527,-0.089],[0.335,-0.673],[-1.241,-1.372],[0.545,-0.766],[0.683,-0.602],[1.09,0.978],[0.986,-0.349],[0.102,-1.568],[1.411,-0.142],[0.342,-0.003]],"o":[[-0.454,-0.037],[-1.374,-0.214],[-0.086,-1.17],[-1.164,-0.49],[-1.085,0.925],[-0.555,-0.49],[-0.994,-1.127],[0.723,-0.821],[-0.115,-0.155],[-0.166,-0.853],[-1.86,-0.123],[-0.005,-0.428],[-0.002,-1.986],[0.861,-0.064],[0.64,-1.372],[-0.652,-0.697],[0.463,-0.696],[1.283,-1.193],[0.603,0.513],[0.07,-0.048],[1.449,-0.428],[0.059,-0.909],[0.938,-0.053],[1.271,0.087],[0.057,0.9],[0.11,0.02],[1.164,0.756],[0.898,-0.726],[0.585,0.542],[0.873,1.04],[-0.574,0.665],[0.475,1.441],[0.95,0.077],[0.135,0.959],[-0.212,1.411],[-0.781,0.045],[-0.71,1.427],[0.602,0.666],[-0.534,0.75],[-1.092,0.962],[-0.847,-0.759],[-1.337,0.474],[-0.079,1.217],[-0.339,0.034],[-0.001,0.013]],"v":[[-18.099,108.227],[-19.46,108.111],[-21.714,105.831],[-23.389,103.638],[-26.336,103.939],[-29.589,103.753],[-31.162,102.179],[-31.252,98.698],[-30.959,96.238],[-31.178,95.683],[-32.713,94.43],[-35.4,91.464],[-35.407,90.18],[-32.673,87.073],[-31.273,85.914],[-31.533,82.079],[-31.394,79.606],[-29.701,77.796],[-25.888,77.669],[-24.143,77.85],[-23.915,77.734],[-21.229,74.878],[-19.28,73.366],[-16.457,73.365],[-14.218,75.753],[-12.943,77.278],[-12.624,77.398],[-9.205,77.297],[-6.317,77.74],[-4.656,79.465],[-4.738,82.807],[-4.992,84.792],[-2.193,87.3],[-0.6,89.205],[-0.595,92.107],[-3.171,94.371],[-4.59,95.433],[-4.396,99.474],[-4.57,101.866],[-6.459,103.843],[-9.868,103.917],[-12.364,103.623],[-14.611,106.225],[-17.07,108.175],[-18.096,108.188]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,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":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"BG","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126,126,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-62.394],[62.394,0],[0,62.394],[-62.394,0]],"o":[[0,62.394],[-62.394,0],[0,-62.394],[62.394,0]],"v":[[112.974,0],[0,112.974],[-112.974,0],[0,-112.974]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.890196084976,0.945098042488,0.984313726425,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"F","size":26.6488609313965,"style":"Bold","w":60.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.848,-70.596],[6.848,0],[25.278,0],[25.278,-25.479],[56.9,-25.479],[56.9,-40.182],[25.278,-40.182],[25.278,-55.893],[59.518,-55.893],[59.619,-70.596]],"c":true},"ix":2},"nm":"F","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"F","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"},{"ch":"B","size":26.6488609313965,"style":"Bold","w":71.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[16.013,0],[0,0],[0,0],[0,0],[0,12.085],[8.963,1.813],[0,7.352]],"o":[[0,0],[0,0],[0,0],[16.617,0],[0,-9.064],[7.452,-2.014],[0,-10.876]],"v":[[40.384,-70.596],[6.848,-70.596],[6.848,0],[41.693,0],[68.884,-19.638],[54.382,-37.463],[66.568,-52.771]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.136,0],[0,0],[0,0],[0,0],[0,-4.23]],"o":[[0,0],[0,0],[0,0],[5.136,-0.101],[0,4.431]],"v":[[39.377,-42.499],[25.278,-42.499],[25.278,-56.195],[39.377,-56.195],[47.635,-49.548]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[6.445,0],[0,0],[0,0],[0,0],[0,-4.431]],"o":[[0,0],[0,0],[0,0],[6.445,-0.101],[0,4.834]],"v":[[39.377,-14.301],[25.278,-14.301],[25.278,-29.105],[39.377,-29.105],[49.85,-21.954]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"B","np":6,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"},{"ch":"5","size":26.6488609313965,"style":"Bold","w":61.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.511,-0.101],[0,0],[0,0],[0,0],[0,0],[0,0],[-3.726,0],[0,-5.338],[7.15,0],[5.539,5.841],[0,0],[-9.467,0],[0,14.905],[16.617,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[4.431,-0.302],[7.05,0],[0,5.74],[-6.445,0],[0,0],[7.654,5.338],[17.422,0],[0,-12.589],[-1.41,0]],"v":[[24.774,-45.016],[24.774,-55.792],[55.289,-55.792],[55.289,-70.697],[7.855,-70.697],[7.855,-30.414],[27.594,-30.817],[38.672,-22.458],[27.493,-13.495],[9.064,-22.357],[1.712,-8.057],[29.709,0.806],[58.511,-23.767],[31.119,-45.117]],"c":true},"ix":2},"nm":"5","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"5","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"},{"ch":"D","size":26.6488609313965,"style":"Bold","w":76.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.357,0],[0,0],[0,0],[0,0],[0,21.048]],"o":[[0,0],[0,0],[0,0],[22.861,0],[0,-20.947]],"v":[[37.262,-70.596],[6.848,-70.596],[6.848,0],[36.557,0],[74.826,-35.349]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[10.675,0],[0,0],[0,0],[0,0],[0,-12.186]],"o":[[0,0],[0,0],[0,0],[11.179,0],[0,12.085]],"v":[[37.766,-14.905],[25.278,-14.905],[25.278,-55.591],[36.859,-55.591],[55.994,-35.147]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"D","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"},{"ch":"0","size":26.6488609313965,"style":"Bold","w":61.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[17.725,0],[0,-23.062],[-17.926,0],[0,23.062]],"o":[[-17.926,0],[0,23.062],[17.725,0],[0,-23.062]],"v":[[31.119,-71.1],[3.424,-35.349],[31.119,0.504],[58.713,-35.349]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.15,0],[0,-16.214],[7.05,0],[0,16.113]],"o":[[7.05,0],[0,16.113],[-7.15,0],[0,-16.214]],"v":[[31.119,-58.209],[41.089,-35.349],[31.119,-12.488],[21.048,-35.349]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"},{"ch":"1","size":26.6488609313965,"style":"Bold","w":61.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.265,-70.596],[9.265,-55.49],[22.861,-55.49],[22.861,0],[41.29,0],[41.29,-70.596]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"},{"ch":"|","size":26.6488609313965,"style":"Bold","w":30.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.56,-80.768],[8.56,10.977],[21.854,10.977],[21.854,-80.768]],"c":true},"ix":2},"nm":"|","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"|","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Montserrat"}]}
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/values-night/themes.xml b/android/HowAboutTrip/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..95d02503
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/values/colors.xml b/android/HowAboutTrip/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..d2a60bbd
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #FF000000
+ #FFFFFFFF
+ #FFD9D9D9
+ #FFCF2727
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/values/strings.xml b/android/HowAboutTrip/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..9cc5ec15
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/values/strings.xml
@@ -0,0 +1,35 @@
+
+ HowAboutTrip
+ HowAboutTripì—ì„œ\n여행 계íšì„ 세우는 ê±´ 어떤가요?
+ google login
+ How About Trip
+ ìž…ë ¥ 완료
+ How About Tripì„ ì²˜ìŒ ì‚¬ìš©í•˜ì‹œëŠ” êµ°ìš”!
+ ì‹ ê·œ 가입ìžëŠ” 추가 ì •ë³´ë¥¼ ìž…ë ¥í•˜ì…”ì•¼ 합니다.\nì´ë¦„ì€ ë³¸ì¸ ì‹¤ëª…ì„ ìž…ë ¥í•˜ì…”ì•¼ 합니다.
+ ì´ë¦„
+ ë³¸ì¸ ëª…ì˜ ì´ë¦„으로 작성
+ ì „í™”ë²ˆí˜¸
+ 010-1234-5678
+ ìƒë…„ ì›”ì¼
+ ìž…ë ¥
+ ë¯¸ìž…ë ¥
+ 2024
+ 01
+ SUN
+ MON
+ TUE
+ WED
+ THU
+ FRI
+ SAT
+ í™•ì •
+ 초기화
+ saveCheck
+ í•ê³µ 숙박
+ ì¼ì • 조회
+ 사진 기ë¡
+ My
+
+ Hello blank fragment
+ Bearer %1$s
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/values/themes.xml b/android/HowAboutTrip/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..eb54e315
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/values/themes.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/xml/backup_rules.xml b/android/HowAboutTrip/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..fa0f996d
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/xml/data_extraction_rules.xml b/android/HowAboutTrip/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..9ee9997b
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/main/res/xml/network_security_config.xml b/android/HowAboutTrip/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 00000000..176d19a4
--- /dev/null
+++ b/android/HowAboutTrip/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/android/HowAboutTrip/app/src/test/java/com/project/how/ExampleUnitTest.kt b/android/HowAboutTrip/app/src/test/java/com/project/how/ExampleUnitTest.kt
new file mode 100644
index 00000000..d6e1d653
--- /dev/null
+++ b/android/HowAboutTrip/app/src/test/java/com/project/how/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.project.how
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/build.gradle.kts b/android/HowAboutTrip/build.gradle.kts
new file mode 100644
index 00000000..817165d5
--- /dev/null
+++ b/android/HowAboutTrip/build.gradle.kts
@@ -0,0 +1,12 @@
+buildscript {
+ dependencies {
+ classpath("com.google.gms:google-services:4.4.0")
+ }
+}
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id("com.android.application") version "8.2.2" apply false
+ id("org.jetbrains.kotlin.android") version "1.9.10" apply false
+ id("com.google.gms.google-services") version "4.4.0" apply false
+ kotlin("kapt") version "1.9.22"
+}
\ No newline at end of file
diff --git a/android/HowAboutTrip/gradle.properties b/android/HowAboutTrip/gradle.properties
new file mode 100644
index 00000000..3c5031eb
--- /dev/null
+++ b/android/HowAboutTrip/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/android/HowAboutTrip/gradle/wrapper/gradle-wrapper.jar b/android/HowAboutTrip/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/android/HowAboutTrip/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/HowAboutTrip/gradle/wrapper/gradle-wrapper.properties b/android/HowAboutTrip/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..58e3c691
--- /dev/null
+++ b/android/HowAboutTrip/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Jan 07 22:58:56 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/android/HowAboutTrip/gradlew b/android/HowAboutTrip/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/android/HowAboutTrip/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/android/HowAboutTrip/gradlew.bat b/android/HowAboutTrip/gradlew.bat
new file mode 100644
index 00000000..ac1b06f9
--- /dev/null
+++ b/android/HowAboutTrip/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/android/HowAboutTrip/settings.gradle.kts b/android/HowAboutTrip/settings.gradle.kts
new file mode 100644
index 00000000..15ecec1d
--- /dev/null
+++ b/android/HowAboutTrip/settings.gradle.kts
@@ -0,0 +1,18 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "HowAboutTrip"
+include(":app")
+
\ No newline at end of file
diff --git a/android/README.md b/android/README.md
new file mode 100644
index 00000000..1277c26a
--- /dev/null
+++ b/android/README.md
@@ -0,0 +1,25 @@
+# HowAboutTrip 여행어때 (Android)
+### Android 개발 환경
+- Lanaguages : Kotlin
+- Tool : Android Studio
+ - Version : Hedgehog
+ - Java : Java 8
+ - Android Gradle Plugin : 8.2.1
+ - Gradle Version : 8.2
+- - -
+### ì‚¬ìš©ëœ ì˜¤í”ˆì†ŒìŠ¤ ë¼ì´ë¸ŒëŸ¬ë¦¬ 목ë¡
+| ì´ë¦„ | ë¼ì´ì„¼ìŠ¤ |
+|---|---|
+|[Glide](https://github.com/bumptech/glide) | BSD-2, part MIT and Apache 2.0 [(ìƒì„¸)](https://github.com/bumptech/glide/blob/master/LICENSE) |
+|[CircleImageView](https://github.com/hdodenhof/CircleImageView) | Apache License 2.0 |
+|[Retrofit2](https://square.github.io/retrofit/) | Apache License 2.0 |
+|[lottie-android](https://github.com/airbnb/lottie-android) | Apache License 2.0 |
+|[OkHttp3](https://square.github.io/okhttp/)| Apache License 2.0 |
+- - -
+### ì‚¬ìš©ëœ API 목ë¡
+| ì´ë¦„ | 설명 |
+|---|---|
+| Google Maps SDK for Android | 구글 지ë„를 활용하여 ì§€ë„ ê¸°ëŠ¥ì„ êµ¬í˜„ |
+| Google OAuth | 구글 ë¡œê·¸ì¸ |
+| 백엔드 API | 비즈니스 ë¡œì§ êµ¬í˜„ì„ ìœ„í•œ API |
+
diff --git a/backend/.gitignore b/backend/.gitignore
new file mode 100644
index 00000000..0584e7bc
--- /dev/null
+++ b/backend/.gitignore
@@ -0,0 +1,129 @@
+### Java template
+# Compiled class file
+*.class
+.env
+.idea/
+.gradle/
+
+# Log file
+*.log
+.DS_Store
+/.DS_Store
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Gradle template
+.gradle
+**/build/
+!src/**/build/
+.idea/sonarlint
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Cache of project
+.gradletasknamecache
+
+# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
+# gradle/wrapper/gradle-wrapper.properties
+
+
+.idea/misc.xml
+
+*.lock
+
+.idea/
+
+.env
+/.env
\ No newline at end of file
diff --git a/backend/appspec.yml b/backend/appspec.yml
new file mode 100644
index 00000000..64e0e04f
--- /dev/null
+++ b/backend/appspec.yml
@@ -0,0 +1,15 @@
+version: 0.0
+os: linux
+
+files:
+ - source: /
+ destination: /home/ubuntu/howabouttrip
+permissions:
+ - object: /home/ubuntu/howabouttrip/
+ owner: ubuntu
+ group: ubuntu
+hooks:
+ AfterInstall:
+ - location: scripts/deploy.sh
+ timeout: 60
+ runas: ubuntu
\ No newline at end of file
diff --git a/backend/build.gradle b/backend/build.gradle
new file mode 100644
index 00000000..cafd748d
--- /dev/null
+++ b/backend/build.gradle
@@ -0,0 +1,58 @@
+plugins {
+ id 'java'
+ id 'org.springframework.boot' version '3.2.1'
+ id 'io.spring.dependency-management' version '1.1.4'
+}
+
+group = 'com.isp'
+version = '0.0.1-SNAPSHOT'
+
+java {
+ sourceCompatibility = '17'
+}
+
+configurations {
+ compileOnly {
+ extendsFrom annotationProcessor
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+ implementation 'org.springframework.boot:spring-boot-starter-security'
+
+ compileOnly 'org.projectlombok:lombok'
+ annotationProcessor 'org.projectlombok:lombok'
+ runtimeOnly 'com.mysql:mysql-connector-j'
+
+ // JWT
+ implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
+ implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
+ implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
+
+ // AWS
+ implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.2'
+ implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.2")
+ implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3'
+
+ implementation 'org.springframework.boot:spring-boot-starter-webflux'
+ implementation 'io.netty:netty-resolver-dns-native-macos:4.1.68.Final:osx-aarch_64'
+
+ // Open API
+ implementation "com.amadeus:amadeus-java:8.0.0"
+
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testImplementation 'org.springframework.security:spring-security-test'
+
+ //GSON
+ implementation 'com.google.code.gson:gson:2.8.8'
+}
+
+tasks.named('test') {
+ useJUnitPlatform()
+}
\ No newline at end of file
diff --git a/backend/gradle/wrapper/gradle-wrapper.jar b/backend/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..d64cd491
Binary files /dev/null and b/backend/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/backend/gradle/wrapper/gradle-wrapper.properties b/backend/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1af9e093
--- /dev/null
+++ b/backend/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/backend/gradlew b/backend/gradlew
new file mode 100755
index 00000000..1aa94a42
--- /dev/null
+++ b/backend/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/backend/gradlew.bat b/backend/gradlew.bat
new file mode 100644
index 00000000..6689b85b
--- /dev/null
+++ b/backend/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/backend/scripts/deploy.sh b/backend/scripts/deploy.sh
new file mode 100644
index 00000000..35e87630
--- /dev/null
+++ b/backend/scripts/deploy.sh
@@ -0,0 +1,19 @@
+REPOSITORY=/home/ubuntu/howabouttrip
+cd $REPOSITORY
+
+JAR_NAME=$(ls $REPOSITORY/build/libs/ | grep 'SNAPSHOT.jar' | tail -n 1)
+JAR_PATH=$REPOSITORY/build/libs/$JAR_NAME
+
+CURRENT_PID=$(pgrep -fl 'java -jar /home/ubuntu/howabouttrip/build/libs/backend-0.0.1-SNAPSHOT.jar')
+
+if [ -z $CURRENT_PID ]
+then
+ echo "> ì¢…ë£Œí• ì• í”Œë¦¬ì¼€ì´ì…˜ì´ 없습니다."
+else
+ echo "> kill -9 $CURRENT_PID"
+ kill -15 $CURRENT_PID
+ sleep 5
+fi
+
+echo "> Deploy - $JAR_PATH "
+nohup java -jar $JAR_PATH > $REPOSITORY/build/libs/nohup.out 2>&1 &
\ No newline at end of file
diff --git a/backend/settings.gradle b/backend/settings.gradle
new file mode 100644
index 00000000..0f5036dc
--- /dev/null
+++ b/backend/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'backend'
diff --git a/backend/src/main/java/com/isp/backend/BackendApplication.java b/backend/src/main/java/com/isp/backend/BackendApplication.java
new file mode 100644
index 00000000..5fd1a247
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/BackendApplication.java
@@ -0,0 +1,21 @@
+package com.isp.backend;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootApplication
+@EnableScheduling
+public class BackendApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(BackendApplication.class, args);
+ }
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/HealthCheckController.java b/backend/src/main/java/com/isp/backend/HealthCheckController.java
new file mode 100644
index 00000000..d8f5bb94
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/HealthCheckController.java
@@ -0,0 +1,13 @@
+package com.isp.backend;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HealthCheckController {
+
+ @GetMapping("/")
+ public String healthCheck() {
+ return "Service is up and running........";
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java b/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java
new file mode 100644
index 00000000..ab75715f
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java
@@ -0,0 +1,78 @@
+package com.isp.backend.domain.country.controller;
+
+import com.isp.backend.domain.country.dto.request.LocationRequest;
+import com.isp.backend.domain.country.dto.response.DailyWeatherResponse;
+import com.isp.backend.domain.country.dto.response.ExchangeRateResponse;
+import com.isp.backend.domain.country.dto.response.LocationResponse;
+import com.isp.backend.domain.country.dto.response.WeatherResponse;
+import com.isp.backend.domain.country.service.CountryService;
+import com.isp.backend.domain.country.service.ExchangeRateService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalTime;
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("/countries")
+@RequiredArgsConstructor
+public class CountryController {
+
+ private final CountryService countryService;
+ private final ExchangeRateService exchangeRateService ;
+
+ /** 여행지 좌표 찾기 **/
+ @PostMapping("/locations")
+ public ResponseEntity findLocation(@RequestBody LocationRequest requestDTO) {
+ String country = requestDTO.getCountry();
+ Optional responseDTO = countryService.findLocationByCity(country);
+ if (responseDTO.isPresent()) {
+ return ResponseEntity.ok(responseDTO.get());
+ } else {
+ return ResponseEntity.notFound().build();
+ }
+ }
+
+
+ /** 여행지 현재 ë‚ ì”¨ ì •ë³´ ê°€ì ¸ì˜¤ê¸° **/
+ @PostMapping("/weather/current")
+ public ResponseEntity getCurrentWeather(@RequestBody LocationRequest requestDTO) {
+ String city = requestDTO.getCountry();
+ WeatherResponse weatherResponse = countryService.getCurrentWeather(city);
+ return ResponseEntity.ok(weatherResponse);
+ }
+
+
+ /** 여행지 í•œ 주 ë‚ ì”¨ ì •ë³´ 조회 **/
+ @PostMapping("/weather/weekly")
+ public ResponseEntity> getWeeklyWeather(@RequestBody LocationRequest requestDTO) {
+ String city = requestDTO.getCountry();
+ LocalTime requestedTime = LocalTime.of(12, 0);
+ List weeklyWeather = countryService.getWeeklyWeather(city, requestedTime);
+ return ResponseEntity.ok(weeklyWeather);
+ }
+
+
+ /** 여행지 환율 ì •ë³´ ì—…ë°ì´íŠ¸ API **/
+ @GetMapping("/exchange-rates/update")
+ public String updateExchangeRate() {
+ try {
+ exchangeRateService.updateExchangeRates();
+ return "updated Successfully";
+ } catch (Exception e) {
+ return "failed to update exchange rates: " + e.getMessage();
+ }
+ }
+
+
+ /** 여행지 환율 ì •ë³´ 조회 API **/
+ @GetMapping("/exchange-rates")
+ public ResponseEntity> getAllExchangeRates() {
+ List exchangeRates = exchangeRateService.getAllExchangeRates();
+ return ResponseEntity.ok(exchangeRates);
+
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/request/CurrencyCalculateRequest.java b/backend/src/main/java/com/isp/backend/domain/country/dto/request/CurrencyCalculateRequest.java
new file mode 100644
index 00000000..b9772314
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/dto/request/CurrencyCalculateRequest.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.country.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class CurrencyCalculateRequest {
+
+ private String baseCity;
+
+ private double basePrice ;
+
+ private String targetCity ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/request/LocationRequest.java b/backend/src/main/java/com/isp/backend/domain/country/dto/request/LocationRequest.java
new file mode 100644
index 00000000..5adf9bc4
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/dto/request/LocationRequest.java
@@ -0,0 +1,10 @@
+package com.isp.backend.domain.country.dto.request;
+
+import lombok.Getter;
+
+@Getter
+public class LocationRequest {
+
+ private String country;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java b/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java
new file mode 100644
index 00000000..f2e96331
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.country.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class DailyWeatherResponse {
+
+ private String date;
+
+ private String temp;
+
+ private String iconUrl;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/response/ExchangeRateResponse.java b/backend/src/main/java/com/isp/backend/domain/country/dto/response/ExchangeRateResponse.java
new file mode 100644
index 00000000..a766cec8
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/dto/response/ExchangeRateResponse.java
@@ -0,0 +1,18 @@
+package com.isp.backend.domain.country.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ExchangeRateResponse {
+ private String baseCurrency;
+ private String targetCurrency;
+ private BigDecimal rate;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/response/LocationResponse.java b/backend/src/main/java/com/isp/backend/domain/country/dto/response/LocationResponse.java
new file mode 100644
index 00000000..03ccefdd
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/dto/response/LocationResponse.java
@@ -0,0 +1,23 @@
+package com.isp.backend.domain.country.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class LocationResponse {
+
+ private double latitude;
+
+ private double longitude;
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/response/WeatherResponse.java b/backend/src/main/java/com/isp/backend/domain/country/dto/response/WeatherResponse.java
new file mode 100644
index 00000000..52034b56
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/dto/response/WeatherResponse.java
@@ -0,0 +1,27 @@
+package com.isp.backend.domain.country.dto.response;
+
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WeatherResponse {
+
+ private String main;
+ private String description;
+
+ @JsonProperty("temp_min")
+ private String tempMin;
+
+ @JsonProperty("temp_max")
+ private String tempMax;
+
+ private String temp;
+
+ private String localTime;
+
+ private String iconUrl ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/entity/Country.java b/backend/src/main/java/com/isp/backend/domain/country/entity/Country.java
new file mode 100644
index 00000000..1c713c82
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/entity/Country.java
@@ -0,0 +1,40 @@
+package com.isp.backend.domain.country.entity;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@NoArgsConstructor
+@Table(name = "country")
+public class Country {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String nation;
+
+ private String city;
+
+ private String imageUrl;
+
+ private String airportCode; // ê³µí• ì½”ë“œ
+
+ private double latitude ; // 위ë„
+
+ private double longitude ; // ê²½ë„
+
+ private String currencyCode ;
+
+ private String currencyName ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/entity/ExchangeRate.java b/backend/src/main/java/com/isp/backend/domain/country/entity/ExchangeRate.java
new file mode 100644
index 00000000..8b5e974e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/entity/ExchangeRate.java
@@ -0,0 +1,34 @@
+package com.isp.backend.domain.country.entity;
+
+import com.isp.backend.global.common.BaseEntity;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.math.BigDecimal;
+
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "exchange_rate")
+public class ExchangeRate extends BaseEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String baseCurrency;
+
+ private String targetCurrency;
+
+ private Double rate;
+
+ public ExchangeRate(String baseCurrency, String targetCurrency, Double rate) {
+ this.baseCurrency = baseCurrency;
+ this.targetCurrency = targetCurrency;
+ this.rate = rate;
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/country/mapper/ExchangeRateMapper.java b/backend/src/main/java/com/isp/backend/domain/country/mapper/ExchangeRateMapper.java
new file mode 100644
index 00000000..d082e329
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/mapper/ExchangeRateMapper.java
@@ -0,0 +1,22 @@
+package com.isp.backend.domain.country.mapper;
+
+import com.isp.backend.domain.country.dto.response.ExchangeRateResponse;
+import com.isp.backend.domain.country.entity.ExchangeRate;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+@RequiredArgsConstructor
+public class ExchangeRateMapper {
+
+ public ExchangeRateResponse convertToDto(ExchangeRate exchangeRate) {
+ ExchangeRateResponse dto = new ExchangeRateResponse();
+ dto.setBaseCurrency(exchangeRate.getBaseCurrency());
+ dto.setTargetCurrency(exchangeRate.getTargetCurrency());
+ dto.setRate(BigDecimal.valueOf(exchangeRate.getRate()));
+ return dto;
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/mapper/WeatherMapper.java b/backend/src/main/java/com/isp/backend/domain/country/mapper/WeatherMapper.java
new file mode 100644
index 00000000..be0bc727
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/mapper/WeatherMapper.java
@@ -0,0 +1,31 @@
+package com.isp.backend.domain.country.mapper;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/** weather id ê°’ì„ í†µí•´ description ì¶œë ¥ **/
+public class WeatherMapper {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+ private static final String MAPPING_FILE_PATH = "/weather_mapping.json";
+
+ public static String getWeatherDescriptionTranslation(String descriptionId) {
+ try {
+ InputStream inputStream = WeatherMapper.class.getResourceAsStream(MAPPING_FILE_PATH);
+ JsonNode mappingNode = objectMapper.readTree(inputStream);
+ JsonNode descriptionNode = mappingNode.get(descriptionId);
+
+ // 만약 해당 IDì— ëŒ€í•œ ì„¤ëª…ì´ ì—†ë‹¤ë©´ 기본값 반환 --> 추후 공통 ì—러 반환
+ if (descriptionNode == null) {
+ return "해당 ì„¤ëª…ì„ ì°¾ì„ ìˆ˜ 없습니다.";
+ }
+ return descriptionNode.asText();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("Failed to read weather mapping file", e);
+ }
+ }
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/repository/CountryRepository.java b/backend/src/main/java/com/isp/backend/domain/country/repository/CountryRepository.java
new file mode 100644
index 00000000..abf5f106
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/repository/CountryRepository.java
@@ -0,0 +1,15 @@
+package com.isp.backend.domain.country.repository;
+
+import com.isp.backend.domain.country.entity.Country;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface CountryRepository extends JpaRepository {
+
+ Optional findIdByCity(String city); // ì—¬í–‰ë‚˜ë¼ ì´ë¦„으로 id 찾기
+ Country findCountryById(Long countryId);
+ Optional findAirportCodeByCity(String countryName); // ë‚˜ë¼ ì´ë¦„으로 ê³µí• ì½”ë“œ 찾기
+ Optional findCountryByAirportCode(String airportCode);
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/repository/ExchangeRateRepository.java b/backend/src/main/java/com/isp/backend/domain/country/repository/ExchangeRateRepository.java
new file mode 100644
index 00000000..aa4381d3
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/repository/ExchangeRateRepository.java
@@ -0,0 +1,9 @@
+package com.isp.backend.domain.country.repository;
+
+import com.isp.backend.domain.country.entity.ExchangeRate;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ExchangeRateRepository extends JpaRepository {
+ ExchangeRate findByBaseCurrencyAndTargetCurrency(String baseCurrency, String targetCurrency);
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java b/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java
new file mode 100644
index 00000000..86ff3c5d
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.country.service;
+
+import com.isp.backend.domain.country.dto.response.DailyWeatherResponse;
+import com.isp.backend.domain.country.dto.response.LocationResponse;
+import com.isp.backend.domain.country.dto.response.WeatherResponse;
+import com.isp.backend.domain.country.entity.Country;
+
+import java.text.DecimalFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+
+public interface CountryService {
+ Optional findLocationByCity(String city);
+
+ WeatherResponse getCurrentWeather(String city);
+
+ List getWeeklyWeather(String city, LocalTime requestedTime);
+
+ Optional findCountryByCity(String city);
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/service/CountryServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/country/service/CountryServiceImpl.java
new file mode 100644
index 00000000..1a113aea
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/service/CountryServiceImpl.java
@@ -0,0 +1,201 @@
+package com.isp.backend.domain.country.service;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.isp.backend.domain.country.dto.response.DailyWeatherResponse;
+import com.isp.backend.domain.country.dto.response.LocationResponse;
+import com.isp.backend.domain.country.dto.response.WeatherResponse;
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.country.mapper.WeatherMapper;
+import com.isp.backend.domain.country.repository.CountryRepository;
+import com.isp.backend.global.exception.openApi.OpenWeatherSearchFailedException;
+import com.isp.backend.global.exception.schedule.CountryNotFoundException;
+import com.isp.backend.global.s3.constant.S3BucketDirectory;
+import com.isp.backend.global.s3.service.S3ImageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.util.*;
+
+
+@Service
+public class CountryServiceImpl implements CountryService {
+
+ @Autowired
+ private CountryRepository countryRepository;
+
+ @Value("${api-key.open-weather}")
+ private String weatherApiKey;
+
+ private final RestTemplate restTemplate = new RestTemplate();
+
+ @Autowired
+ private S3ImageService s3ImageService;
+
+
+ /** 여행지 좌표 찾기 **/
+ @Override
+ public Optional findLocationByCity(String city) {
+ Optional findCountry = countryRepository.findIdByCity(city);
+
+ if (findCountry.isPresent()) {
+ return findCountry.map(country -> {
+ LocationResponse locationDTO = new LocationResponse();
+ locationDTO.setLatitude(country.getLatitude());
+ locationDTO.setLongitude(country.getLongitude());
+ return locationDTO;
+ });
+ } else {
+ throw new CountryNotFoundException();
+ }
+ }
+
+
+
+ /** ì—¬í–‰ì§€ì˜ ë‚ ì”¨ ì •ë³´ ê°€ì ¸ì˜¤ê¸° **/
+ @Override
+ public WeatherResponse getCurrentWeather(String city) {
+ Optional findCountry = findCountryByCity(city);
+ Country country = findCountry.get();
+ double latitude = country.getLatitude();
+ double longitude = country.getLongitude();
+
+ String url = String.format("http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%s", latitude, longitude, weatherApiKey);
+ String jsonResponse = restTemplate.getForObject(url, String.class);
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ WeatherResponse weatherResponse = new WeatherResponse();
+
+ try {
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+
+ JsonNode weatherNode = rootNode.path("weather").get(0);
+ weatherResponse.setMain(weatherNode.path("main").asText());
+ String descriptionId = weatherNode.path("id").asText(); // ID ê°’ ê°€ì ¸ì˜¤ê¸°
+ String descriptionTranslation = WeatherMapper.getWeatherDescriptionTranslation(descriptionId); // ë‚ ì”¨ 설명
+ weatherResponse.setDescription(descriptionTranslation);
+
+ String icon = weatherNode.path("icon").asText();
+ weatherResponse.setIconUrl(s3ImageService.get(S3BucketDirectory.WEATHER.getDirectory(), icon + ".png"));
+
+ JsonNode mainNode = rootNode.path("main");
+ weatherResponse.setTemp(convertToCelsius(mainNode.path("temp").asDouble()));
+ weatherResponse.setTempMin(convertToCelsius(mainNode.path("temp_min").asDouble()));
+ weatherResponse.setTempMax(convertToCelsius(mainNode.path("temp_max").asDouble()));
+
+ int timezoneOffset = rootNode.path("timezone").asInt();
+ weatherResponse.setLocalTime(getLocalTime(timezoneOffset));
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new OpenWeatherSearchFailedException();
+ }
+
+ return weatherResponse;
+ }
+
+
+
+ /** í•œ ì£¼ì˜ ë‚ ì”¨ ì •ë³´ 조회 **/
+ @Override
+ public List getWeeklyWeather(String city, LocalTime requestedTime) {
+ Optional findCountry = findCountryByCity(city);
+ Country country = findCountry.get();
+ double latitude = country.getLatitude();
+ double longitude = country.getLongitude();
+
+ List weeklyWeather = new ArrayList<>();
+ String url = String.format("http://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&appid=%s", latitude, longitude, weatherApiKey);
+ String jsonResponse = restTemplate.getForObject(url, String.class);
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+ JsonNode forecastList = rootNode.path("list");
+
+ Map dailyWeatherMap = new HashMap<>(); // ê° ë‚ ì§œì˜ ë‚ ì”¨ ì •ë³´ë¥¼ ì €ìž¥í• ë§µ
+
+ for (JsonNode forecast : forecastList) {
+ String dateTime = forecast.path("dt_txt").asText(); // 예측 시간 ì •ë³´
+ LocalDateTime localDateTime = LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+ // ìš”ì²ëœ ì‹œê°„ëŒ€ì˜ ì˜¨ë„만 ê³ ë ¤
+ if (localDateTime.toLocalTime().equals(requestedTime)) {
+ String dateString = localDateTime.toLocalDate().toString();
+ double temperature = forecast.path("main").path("temp").asDouble(); // ì˜¨ë„ ì •ë³´
+
+ // 해당 ë‚ ì§œì˜ ì˜¨ë„ ì •ë³´ë¥¼ ì €ìž¥ (ë™ì¼í•œ ì‹œê°„ëŒ€ì— ì—¬ëŸ¬ ë°ì´í„°ê°€ ìžˆì„ ê²½ìš°, 가장 첫 번째 ë°ì´í„°ë¥¼ 사용)
+ if (!dailyWeatherMap.containsKey(dateString)) {
+ // ì•„ì´ì½˜ URL ê°€ì ¸ì˜¤ê¸°
+ String iconCode = forecast.path("weather").get(0).path("icon").asText();
+ String iconUrl = String.format(s3ImageService.get(S3BucketDirectory.WEATHER.getDirectory(), iconCode + ".png"));
+
+ DailyWeatherResponse dailyWeather = new DailyWeatherResponse();
+ dailyWeather.setDate(parseDayOfWeek(dateString));
+ dailyWeather.setTemp(convertToCelsius(temperature));
+ dailyWeather.setIconUrl(iconUrl);
+
+ dailyWeatherMap.put(dateString, dailyWeather);
+ }
+ }
+ }
+
+ weeklyWeather.addAll(dailyWeatherMap.values());
+ weeklyWeather.sort(Comparator.comparing(DailyWeatherResponse::getDate));
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new OpenWeatherSearchFailedException();
+ }
+
+ return weeklyWeather;
+ }
+
+
+ /** ë„ì‹œì´ë¦„으로 ë‚˜ë¼ ì°¾ê¸° **/
+ @Override
+ public Optional findCountryByCity(String city) {
+ Optional findCountry = countryRepository.findIdByCity(city);
+ if (!findCountry.isPresent()) {
+ throw new CountryNotFoundException();
+ }
+ return findCountry;
+ }
+
+
+ /** 현지 시간으로 변환 **/
+ private String getLocalTime(int timezoneOffset) {
+ Instant now = Instant.now();
+ ZoneOffset offset = ZoneOffset.ofTotalSeconds(timezoneOffset);
+ LocalDateTime localDateTime = LocalDateTime.ofInstant(now, offset);
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
+ return localDateTime.format(formatter);
+ }
+
+
+ /** 온ë„를 ì„씨로 변환 **/
+ private String convertToCelsius(double kelvin) {
+ double celsius = kelvin - 273.15;
+ DecimalFormat df = new DecimalFormat("#.##");
+ return df.format(celsius);
+ }
+
+
+ /** ë‚ ì§œ 문ìžì—´ì—ì„œ ìš”ì¼ì„ 파싱 **/
+ private String parseDayOfWeek(String dateString) {
+ LocalDate localDate = LocalDate.parse(dateString);
+ DayOfWeek dayOfWeek = localDate.getDayOfWeek();
+ String weekDay = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.KOREAN);
+ return (dateString + "," + weekDay);
+ }
+
+
+}
+
diff --git a/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateScheduler.java b/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateScheduler.java
new file mode 100644
index 00000000..0b7740ba
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateScheduler.java
@@ -0,0 +1,23 @@
+package com.isp.backend.domain.country.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ExchangeRateScheduler {
+
+ @Autowired
+ private ExchangeRateService exchangeRateService;
+
+ @Scheduled(cron = "0 0 2 * * ?", zone = "Asia/Seoul") // ë§¤ì¼ í•œêµì‹œê°„ 새벽 2ì‹œì— ì‹¤í–‰
+ public void scheduleExchangeRateUpdate() {
+ try {
+ exchangeRateService.updateExchangeRates();
+ } catch (Exception e) {
+ // 예외 처리 ë¡œì§
+ System.out.println("Failed to update exchange rates: " + e.getMessage());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateService.java b/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateService.java
new file mode 100644
index 00000000..14a6469a
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateService.java
@@ -0,0 +1,13 @@
+package com.isp.backend.domain.country.service;
+
+import com.isp.backend.domain.country.dto.response.ExchangeRateResponse;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface ExchangeRateService {
+ @Transactional
+ void updateExchangeRates();
+ List getAllExchangeRates();
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateServiceImpl.java
new file mode 100644
index 00000000..3411defe
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/country/service/ExchangeRateServiceImpl.java
@@ -0,0 +1,119 @@
+package com.isp.backend.domain.country.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.isp.backend.domain.country.dto.response.ExchangeRateResponse;
+import com.isp.backend.domain.country.entity.ExchangeRate;
+import com.isp.backend.domain.country.mapper.ExchangeRateMapper;
+import com.isp.backend.domain.country.repository.ExchangeRateRepository;
+import com.isp.backend.global.exception.openApi.ExchangeRateIsFailedException;
+import com.isp.backend.global.exception.openApi.ExchangeRateSearchFailedException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Service
+public class ExchangeRateServiceImpl implements ExchangeRateService {
+
+ private final ExchangeRateRepository exchangeRateRepository;
+ private final ExchangeRateMapper exchangeRateMapper ;
+
+ @Value("${api-key.exchange-rate}")
+ private String exchangeRateApiKey;
+
+ @Autowired
+ public ExchangeRateServiceImpl(ExchangeRateRepository exchangeRateRepository, ExchangeRateMapper exchangeRateMapper) {
+ this.exchangeRateRepository = exchangeRateRepository;
+ this.exchangeRateMapper = exchangeRateMapper;
+ }
+
+ /** 환율 ë°ì´í„° ê°€ì ¸ì™€ì„œ ì—…ë°ì´íŠ¸ 하는 API 메서드 **/
+ @Override
+ @Transactional
+ public void updateExchangeRates() {
+ // í•œêµê³¼ ë¯¸êµ í†µí™” 환율 비율 ì €ìž¥
+ updateRatesForBaseCurrency("KRW");
+ updateRatesForBaseCurrency("USD");
+ }
+
+
+ /** 환율 ë°ì´í„° ê°€ì ¸ì™€ì„œ ì—…ë°ì´íŠ¸ 하는 API 메서드 **/
+ @Override
+ public List getAllExchangeRates() {
+ try {
+ // DBì—ì„œ ëª¨ë“ í™˜ìœ¨ ë°ì´í„°ë¥¼ ê°€ì ¸ì˜´
+ List exchangeRates = exchangeRateRepository.findAll();
+
+ // baseCurrencyê°€ "KRW" ë˜ëŠ” "USD"ì¸ ë°ì´í„°ë§Œ í•„í„°ë§í•˜ê³ DTOë¡œ 변환
+ return exchangeRates.stream()
+ .filter(rate -> ("KRW".equals(rate.getBaseCurrency()) || "USD".equals(rate.getBaseCurrency()))
+ && !rate.getBaseCurrency().equals(rate.getTargetCurrency()))
+ .map(exchangeRateMapper::convertToDto)
+ .collect(Collectors.toList());
+ } catch (Exception e) {
+ throw new ExchangeRateIsFailedException() ;
+ }
+ }
+
+
+ /** ì¸¡ì • baseCurrency í†µí™”ì— ëŒ€í•´ ì—…ë°ì´íŠ¸ 하는 메서드**/
+ private void updateRatesForBaseCurrency(String baseCurrency) {
+ String exchangeRateAPI_URL = "https://v6.exchangerate-api.com/v6/" + exchangeRateApiKey + "/latest/" + baseCurrency;
+
+ try {
+ URL url = new URL(exchangeRateAPI_URL);
+ HttpURLConnection request = (HttpURLConnection) url.openConnection();
+ request.connect();
+
+ // API ì‘답 ë°ì´í„°ë¥¼ JsonObjectë¡œ 변환
+ Gson gson = new Gson();
+ JsonObject jsonobj = gson.fromJson(new InputStreamReader(request.getInputStream()), JsonObject.class);
+
+ // API ì‘답 ê²°ê³¼
+ String req_result = jsonobj.get("result").getAsString();
+
+ if ("success".equals(req_result)) {
+ JsonObject conversionRates = jsonobj.getAsJsonObject("conversion_rates");
+ for (String targetCurrency : conversionRates.keySet()) {
+ // 필요한 통화만 ê°€ì ¸ì˜¨ë‹¤
+ if (isSupportedCurrency(targetCurrency)) {
+ double rate = conversionRates.get(targetCurrency).getAsDouble();
+
+ // DBì—ì„œ 환율 ë°ì´í„° 존재 여부 확ì¸
+ ExchangeRate existingRate = exchangeRateRepository.findByBaseCurrencyAndTargetCurrency(baseCurrency, targetCurrency);
+
+ if (existingRate == null) {
+ ExchangeRate newExchangeRate = new ExchangeRate(baseCurrency, targetCurrency, rate);
+ exchangeRateRepository.save(newExchangeRate);
+ } else {
+ // 기ë¡ì´ ì´ë¯¸ 존재하면, rate만 ìˆ˜ì •í•œë‹¤.
+ existingRate.setRate(rate);
+ exchangeRateRepository.save(existingRate);
+ }
+ }
+ }
+ } else {
+ throw new ExchangeRateSearchFailedException();
+ }
+ } catch (Exception e) {
+ throw new ExchangeRateIsFailedException() ;
+ }
+ }
+
+ /** 지ì›í•˜ëŠ” 통화만 ê°€ì ¸ì˜¤ëŠ” 메서드 **/
+ private boolean isSupportedCurrency(String currencyCode) {
+ return Set.of("JPY", "GBP", "EUR", "CHF", "CZK", "USD", "SGD", "TWD", "LAK", "MYR", "VND", "THB", "IDR", "PHP", "KRW").contains(currencyCode);
+ }
+
+
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/controller/FlightOfferController.java b/backend/src/main/java/com/isp/backend/domain/flight/controller/FlightOfferController.java
new file mode 100644
index 00000000..684adfe6
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/controller/FlightOfferController.java
@@ -0,0 +1,81 @@
+package com.isp.backend.domain.flight.controller;
+
+import com.amadeus.exceptions.ResponseException;
+import com.isp.backend.domain.flight.dto.request.FlightLikeRequest;
+import com.isp.backend.domain.flight.dto.request.SkyScannerRequest;
+import com.isp.backend.domain.flight.dto.response.FlightLikeResponse;
+import com.isp.backend.domain.flight.service.FlightOfferService;
+import com.isp.backend.domain.flight.dto.request.FlightSearchRequest;
+import com.isp.backend.global.exception.openApi.AmadeusSearchFailedException;
+import com.isp.backend.global.exception.openApi.SkyScannerGenerateFailedException;
+import com.isp.backend.global.security.CustomUserDetails;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/bookings/flights")
+@RequiredArgsConstructor
+public class FlightOfferController {
+
+ @Autowired
+ private FlightOfferService flightOfferService;
+
+ /** í•ê³µê¶Œ 검색 API **/
+ @PostMapping("/search")
+ public ResponseEntity getFlightOffers(@RequestBody FlightSearchRequest request) {
+ try {
+ String flightOffersJson = flightOfferService.getFlightOffers(request);
+ return ResponseEntity.ok(flightOffersJson);
+ } catch (ResponseException e) {
+ throw new AmadeusSearchFailedException();
+ }
+ }
+
+
+ /** í•ê³µê¶Œ ì„ íƒì‹œ 스카ì´ìŠ¤ìºë„ˆ 사ì´íŠ¸ë¡œ ì—°ê²° API **/
+ @PostMapping("/connect")
+ public ResponseEntity getFlightSearchUrl(@RequestBody SkyScannerRequest request) {
+ try {
+ String skyscannerUrl = flightOfferService.generateSkyscannerUrl(request);
+ return ResponseEntity.ok("{\"skyscannerUrl\": \"" + skyscannerUrl + "\"}");
+ } catch (Exception e) {
+ throw new SkyScannerGenerateFailedException();
+ }
+ }
+
+
+ /** í•ê³µê¶Œ 좋아요 ì €ìž¥ API **/
+ @PostMapping("/like")
+ public ResponseEntity addLikeFlight(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @RequestBody FlightLikeRequest flightLikeRequest) {
+ String memberUid = customUserDetails.getUsername();
+ Long flightId = flightOfferService.addLikeFlight(memberUid, flightLikeRequest);
+ return ResponseEntity.status(HttpStatus.CREATED).body(flightId);
+ }
+
+
+ /** í•ê³µê¶Œ ë‚˜ì˜ ì¢‹ì•„ìš” ëª©ë¡ ë¶ˆëŸ¬ì˜¤ê¸° API **/
+ @GetMapping("/likes")
+ public ResponseEntity> getLikedFlights(@AuthenticationPrincipal CustomUserDetails customUserDetails) {
+ String memberUid = customUserDetails.getUsername();
+ List likedFlights = flightOfferService.getLikedFlights(memberUid);
+ return ResponseEntity.ok(likedFlights);
+ }
+
+
+ /** í•ê³µê¶Œ ë‚˜ì˜ ì¢‹ì•„ìš” ì‚ì œ API **/
+ @DeleteMapping("/like/{id}")
+ public ResponseEntity deleteLikeFlight(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @PathVariable Long id) {
+ String memberUid = customUserDetails.getUsername();
+ flightOfferService.deleteLikeFlight(memberUid, id);
+ return ResponseEntity.ok().build();
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/dto/request/FlightLikeRequest.java b/backend/src/main/java/com/isp/backend/domain/flight/dto/request/FlightLikeRequest.java
new file mode 100644
index 00000000..179053e5
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/dto/request/FlightLikeRequest.java
@@ -0,0 +1,40 @@
+package com.isp.backend.domain.flight.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class FlightLikeRequest {
+
+ private String carrierCode;
+
+ private int totalPrice;
+
+ private String abroadDuration;
+
+ private String abroadDepartureTime;
+
+ private String abroadArrivalTime;
+
+ private String homeDuration;
+
+ private String homeDepartureTime;
+
+ private String homeArrivalTime;
+
+ private String departureIataCode;
+
+ private String arrivalIataCode;
+
+ private String transferCount;
+
+ private int adult ;
+
+ private int children ;
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/dto/request/FlightSearchRequest.java b/backend/src/main/java/com/isp/backend/domain/flight/dto/request/FlightSearchRequest.java
new file mode 100644
index 00000000..8c0af1f2
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/dto/request/FlightSearchRequest.java
@@ -0,0 +1,28 @@
+package com.isp.backend.domain.flight.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class FlightSearchRequest {
+
+ private String originCity;
+
+ private String destinationCity;
+
+ private String departureDate;
+
+ private String returnDate;
+
+ private int adults;
+
+ private int children;
+
+ private int max ;
+
+ private boolean nonStop ; // ì§í• í•ê³µíŽ¸ ìœ ë¬´
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/dto/request/SkyScannerRequest.java b/backend/src/main/java/com/isp/backend/domain/flight/dto/request/SkyScannerRequest.java
new file mode 100644
index 00000000..ff6e8d8e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/dto/request/SkyScannerRequest.java
@@ -0,0 +1,28 @@
+package com.isp.backend.domain.flight.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class SkyScannerRequest {
+
+ private String departureIataCode;
+
+ private String arrivalIataCode;
+
+ private String departureDate;
+
+ private String returnDate;
+
+ private int adult;
+
+ private int children;
+
+ private String departureTime;
+
+ private int transferCount;
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/dto/response/FlightLikeResponse.java b/backend/src/main/java/com/isp/backend/domain/flight/dto/response/FlightLikeResponse.java
new file mode 100644
index 00000000..4f539e55
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/dto/response/FlightLikeResponse.java
@@ -0,0 +1,42 @@
+package com.isp.backend.domain.flight.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class FlightLikeResponse {
+
+ private Long id;
+
+ private String carrierCode;
+
+ private int totalPrice;
+
+ private String abroadDuration;
+
+ private String abroadDepartureTime;
+
+ private String abroadArrivalTime;
+
+ private String homeDuration;
+
+ private String homeDepartureTime;
+
+ private String homeArrivalTime;
+
+ private String departureIataCode;
+
+ private String arrivalIataCode;
+
+ private String transferCount;
+
+ private int adult ;
+
+ private int children ;
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/entity/Flight.java b/backend/src/main/java/com/isp/backend/domain/flight/entity/Flight.java
new file mode 100644
index 00000000..3ed80cef
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/entity/Flight.java
@@ -0,0 +1,57 @@
+package com.isp.backend.domain.flight.entity;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.member.entity.Member;
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@NoArgsConstructor
+@Table(name = "flight")
+public class Flight {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id ;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "member_id", nullable = false)
+ private Member member;
+
+ private String carrierCode ;
+
+ private Double price ;
+
+ private String abroadDuration ;
+
+ private String abroadDepartureTime ; // 출êµ-출발
+
+ private String abroadArrivalTime ; // 출êµ-ë„ì°©
+
+ @ManyToOne
+ @JoinColumn(name = "departure_iata_code_id")
+ private Country departureIataCode ;
+
+ private String homeDuration ;
+
+ private String homeDepartureTime ; // ìž…êµ-출발
+
+ private String homeArrivalTime ; // ìž…êµ-ë„ì°©
+ @ManyToOne
+ @JoinColumn(name = "arrival_iata_code_id")
+ private Country arrivalIataCode ;
+
+ private int transferCount ;
+
+ private int adult ;
+
+ private int children ;
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/mapper/FlightMapper.java b/backend/src/main/java/com/isp/backend/domain/flight/mapper/FlightMapper.java
new file mode 100644
index 00000000..9a5a8e3e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/mapper/FlightMapper.java
@@ -0,0 +1,61 @@
+package com.isp.backend.domain.flight.mapper;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.flight.dto.request.FlightLikeRequest;
+import com.isp.backend.domain.flight.dto.response.FlightLikeResponse;
+import com.isp.backend.domain.flight.entity.Flight;
+import com.isp.backend.domain.member.entity.Member;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+@RequiredArgsConstructor
+public class FlightMapper {
+
+ public Flight toEntity(FlightLikeRequest request, Member member, Country departureIataCode, Country arrivalIataCode) {
+ return Flight.builder()
+ .member(member)
+ .carrierCode(request.getCarrierCode())
+ .price((double) request.getTotalPrice())
+ .abroadDuration(request.getAbroadDuration())
+ .abroadDepartureTime(request.getAbroadDepartureTime())
+ .abroadArrivalTime(request.getAbroadArrivalTime())
+ .homeDuration(request.getHomeDuration())
+ .homeDepartureTime(request.getHomeDepartureTime())
+ .homeArrivalTime(request.getHomeArrivalTime())
+ .departureIataCode(departureIataCode)
+ .arrivalIataCode(arrivalIataCode)
+ .transferCount(Integer.parseInt(request.getTransferCount()))
+ .adult(request.getAdult())
+ .children(request.getChildren())
+ .build();
+ }
+
+ public FlightLikeResponse toFlightLikeRequest(Flight flight) {
+ FlightLikeResponse response = new FlightLikeResponse();
+ response.setId(flight.getId());
+ response.setCarrierCode(flight.getCarrierCode());
+ response.setTotalPrice((int) Math.round(flight.getPrice()));
+ response.setAbroadDuration(flight.getAbroadDuration());
+ response.setAbroadDepartureTime(flight.getAbroadDepartureTime());
+ response.setAbroadArrivalTime(flight.getAbroadArrivalTime());
+ response.setHomeDuration(flight.getHomeDuration());
+ response.setHomeDepartureTime(flight.getHomeDepartureTime());
+ response.setHomeArrivalTime(flight.getHomeArrivalTime());
+ response.setDepartureIataCode(flight.getDepartureIataCode().getAirportCode());
+ response.setArrivalIataCode(flight.getArrivalIataCode().getAirportCode());
+ response.setTransferCount(String.valueOf(flight.getTransferCount()));
+ response.setAdult(flight.getAdult());
+ response.setChildren(flight.getChildren());
+ return response;
+ }
+
+ public List toFlightLikeRequestList(List flights) {
+ return flights.stream()
+ .map(this::toFlightLikeRequest)
+ .collect(Collectors.toList());
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/mapper/FlightOfferProcessor.java b/backend/src/main/java/com/isp/backend/domain/flight/mapper/FlightOfferProcessor.java
new file mode 100644
index 00000000..8e84539f
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/mapper/FlightOfferProcessor.java
@@ -0,0 +1,128 @@
+package com.isp.backend.domain.flight.mapper;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import org.springframework.stereotype.Service;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Service
+public class FlightOfferProcessor {
+
+ /** 추출한 ì •ë³´ json으로 반환 **/
+ public String processFlightOffers(String flightOffersJson) {
+ JsonArray flightOffersArray = new Gson().fromJson(flightOffersJson, JsonArray.class);
+
+ JsonArray filteredFlightOffers = new JsonArray();
+ for (JsonElement flightOfferElement : flightOffersArray) {
+ JsonObject flightOffer = flightOfferElement.getAsJsonObject();
+ JsonObject filteredFlightOffer = filterFlightOffer(flightOffer);
+ filteredFlightOffers.add(filteredFlightOffer);
+ }
+ return filteredFlightOffers.toString();
+ }
+
+ /** í•ê³µ ì •ë³´ì—ì„œ 필요한 ì •ë³´ 추출 **/
+ public JsonObject filterFlightOffer(JsonObject flightOffer) {
+ JsonObject filteredFlightOffer = new JsonObject();
+
+ // 필요한 ì •ë³´ 추출
+ String id = flightOffer.get("id").getAsString();
+ String carrierCode = flightOffer.getAsJsonArray("itineraries").get(0).getAsJsonObject()
+ .getAsJsonArray("segments").get(0).getAsJsonObject().get("carrierCode").getAsString();
+ Double price = flightOffer.getAsJsonObject("price").get("total").getAsDouble();
+
+ // 왕복-íŽ¸ë„ ì—¬í–‰ 여부 í™•ì¸ (itineraries ë°°ì—´ ê¸¸ì´ í™•ì¸)
+ boolean isRoundTrip = flightOffer.getAsJsonArray("itineraries").size() == 2;
+
+ // ì¶œêµ ì •ë³´ 추출
+ JsonObject abroadItinerary = flightOffer.getAsJsonArray("itineraries").get(0).getAsJsonObject();
+ String abroadDuration = abroadItinerary.get("duration").getAsString();
+ String abroadDepartureTime = abroadItinerary.getAsJsonArray("segments").get(0).getAsJsonObject().getAsJsonObject("departure").get("at").getAsString();
+ String abroadArrivalTime = abroadItinerary.getAsJsonArray("segments").get(0).getAsJsonObject().getAsJsonObject("arrival").get("at").getAsString();
+
+ // 출발지 ë° ë„착지 ì •ë³´ 추출
+ JsonArray segments = flightOffer.getAsJsonArray("itineraries").get(0).getAsJsonObject().getAsJsonArray("segments");
+ JsonObject lastSegment = segments.get(segments.size() - 1).getAsJsonObject();
+ String departureIataCode = segments.get(0).getAsJsonObject().getAsJsonObject("departure").get("iataCode").getAsString();
+ String arrivalIataCode = lastSegment.getAsJsonObject("arrival").get("iataCode").getAsString();
+
+ // ê²½ìœ íšŸìˆ˜ 확ì¸
+ int transferCount = countTransfers(segments);
+
+ // 시간 변환 ë° ì €ìž¥
+ String filteredAbroadDepartureTime = formatTime(abroadDepartureTime);
+ String filteredAbroadArrivalTime = formatTime(abroadArrivalTime);
+
+ // duration 변환 ë° ì €ìž¥
+ String filteredAbroadDuration = formatDuration(abroadDuration);
+
+ // ê²½ìœ ë° ì§í• 여부 추출
+ boolean nonstop = segments.size() == 1; // ì§í•ì¼ 경우 segments ë°°ì—´ì˜ í¬ê¸°ëŠ” 1ì´ ë¨
+
+ filteredFlightOffer.addProperty("id", id);
+ filteredFlightOffer.addProperty("carrierCode", carrierCode);
+ filteredFlightOffer.addProperty("totalPrice", price);
+ filteredFlightOffer.addProperty("departureIataCode", departureIataCode);
+ filteredFlightOffer.addProperty("arrivalIataCode", arrivalIataCode);
+ filteredFlightOffer.addProperty("nonstop", nonstop);
+ filteredFlightOffer.addProperty("transferCount", transferCount);
+
+ filteredFlightOffer.addProperty("abroadDuration", filteredAbroadDuration);
+ filteredFlightOffer.addProperty("abroadDepartureTime", filteredAbroadDepartureTime);
+ filteredFlightOffer.addProperty("abroadArrivalTime", filteredAbroadArrivalTime);
+
+
+ // 왕복 ì—¬í–‰ì˜ ê²½ìš°
+ if (isRoundTrip) {
+ // ìž…êµ ì—¬í–‰ ì •ë³´ 추출
+ JsonObject homeItinerary = flightOffer.getAsJsonArray("itineraries").get(1).getAsJsonObject();
+ String homeDuration = homeItinerary.get("duration").getAsString();
+ String homeDepartureTime = homeItinerary.getAsJsonArray("segments").get(0).getAsJsonObject().getAsJsonObject("departure").get("at").getAsString();
+ String homeArrivalTime = homeItinerary.getAsJsonArray("segments").get(1).getAsJsonObject().getAsJsonObject("arrival").get("at").getAsString();
+ String filteredHomeDepartureTime = formatTime(homeDepartureTime);
+ String filteredHomeArrivalTime = formatTime(homeArrivalTime);
+ String filteredHomeDuration = formatDuration(homeDuration);
+
+ // ì‘답 ê°’ì— ì¶”ê°€
+ filteredFlightOffer.addProperty("homeDuration", filteredHomeDuration);
+ filteredFlightOffer.addProperty("homeDepartureTime", filteredHomeDepartureTime);
+ filteredFlightOffer.addProperty("homeArrivalTime", filteredHomeArrivalTime);
+ }
+ return filteredFlightOffer;
+ }
+
+
+ /** ê²½ìœ íšŸìˆ˜ í™•ì¸ **/
+ private int countTransfers(JsonArray segments) {
+ // ì§í•ì¼ 경우 ê²½ìœ ì—†ìŒ
+ if (segments.size() == 1) {
+ return 0;
+ }
+ // ê²½ìœ íšŸìˆ˜ëŠ” í•ê³µíŽ¸ 세그먼트 개수 - 1
+ return segments.size() - 1;
+ }
+
+
+ /** 시간 변환 **/
+ private String formatTime(String timeStr) {
+ LocalDateTime time = LocalDateTime.parse(timeStr, DateTimeFormatter.ISO_DATE_TIME);
+ return time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ }
+
+
+ /** duration 비행 시간 변환 **/
+ private String formatDuration(String durationStr) {
+ Duration duration = Duration.parse(durationStr);
+
+ long hours = duration.toHours();
+ long minutes = duration.minusHours(hours).toMinutes();
+ return String.format("%d:%02d", hours, minutes);
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/repository/FlightRepository.java b/backend/src/main/java/com/isp/backend/domain/flight/repository/FlightRepository.java
new file mode 100644
index 00000000..ad5aae33
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/repository/FlightRepository.java
@@ -0,0 +1,16 @@
+package com.isp.backend.domain.flight.repository;
+
+import com.isp.backend.domain.flight.entity.Flight;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface FlightRepository extends JpaRepository {
+ @Query("SELECT f FROM Flight f WHERE f.member = :member ORDER BY f.id DESC")
+ List findByMember(@Param("member") Member member);
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/service/FlightOfferService.java b/backend/src/main/java/com/isp/backend/domain/flight/service/FlightOfferService.java
new file mode 100644
index 00000000..d61aa97d
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/service/FlightOfferService.java
@@ -0,0 +1,25 @@
+package com.isp.backend.domain.flight.service;
+
+import com.amadeus.exceptions.ResponseException;
+import com.isp.backend.domain.flight.dto.request.FlightLikeRequest;
+import com.isp.backend.domain.flight.dto.request.FlightSearchRequest;
+import com.isp.backend.domain.flight.dto.request.SkyScannerRequest;
+import com.isp.backend.domain.flight.dto.response.FlightLikeResponse;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface FlightOfferService {
+
+ String getFlightOffers(FlightSearchRequest request) throws ResponseException;
+
+ String generateSkyscannerUrl(SkyScannerRequest request);
+
+ @Transactional
+ Long addLikeFlight(String uid, FlightLikeRequest flightLikeRequest);
+
+ List getLikedFlights(String memberUid);
+
+ @Transactional
+ void deleteLikeFlight(String memberUid, Long id);
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/flight/service/FlightOfferServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/flight/service/FlightOfferServiceImpl.java
new file mode 100644
index 00000000..e38c4716
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/flight/service/FlightOfferServiceImpl.java
@@ -0,0 +1,178 @@
+package com.isp.backend.domain.flight.service;
+
+import com.amadeus.Amadeus;
+import com.amadeus.Params;
+import com.amadeus.exceptions.ResponseException;
+import com.amadeus.resources.FlightOfferSearch;
+import com.google.gson.Gson;
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.country.repository.CountryRepository;
+import com.isp.backend.domain.flight.dto.request.FlightLikeRequest;
+import com.isp.backend.domain.flight.dto.request.FlightSearchRequest;
+import com.isp.backend.domain.flight.dto.request.SkyScannerRequest;
+import com.isp.backend.domain.flight.dto.response.FlightLikeResponse;
+import com.isp.backend.domain.flight.entity.Flight;
+import com.isp.backend.domain.flight.mapper.FlightMapper;
+import com.isp.backend.domain.flight.mapper.FlightOfferProcessor;
+import com.isp.backend.domain.flight.repository.FlightRepository;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.schedule.service.ScheduleService;
+import com.isp.backend.global.exception.openApi.FlightNotFoundException;
+import com.isp.backend.global.exception.openApi.NotYourFlightException;
+import com.isp.backend.global.exception.schedule.CountryNotFoundException;
+import com.isp.backend.global.exception.schedule.IataCodeNotFoundException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collections;
+import java.util.List;
+
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+@Service
+public class FlightOfferServiceImpl implements FlightOfferService {
+
+ private final Amadeus amadeus;
+ private final CountryRepository countryRepository;
+ private final ScheduleService scheduleService;
+ private final FlightOfferProcessor flightOfferProcessor ;
+ private final FlightRepository flightRepository;
+ private final FlightMapper flightMapper;
+
+
+ /** í•ê³µíŽ¸ 조회 **/
+ @Override
+ public String getFlightOffers(FlightSearchRequest request) throws ResponseException {
+
+ String originLocationCode = findAirportCode(request.getOriginCity());
+ String destinationLocationCode = findAirportCode(request.getDestinationCity());
+
+ Params params = Params.with("originLocationCode", originLocationCode)
+ .and("destinationLocationCode", destinationLocationCode)
+ .and("departureDate", request.getDepartureDate())
+ .and("adults", request.getAdults())
+ .and("children", request.getChildren())
+ .and("max", request.getMax())
+ .and("nonStop", request.isNonStop())
+ .and("currencyCode", "KRW"); // ì›í™” ì„¤ì • -> 추후 ìœ ì €ì—게 ìž…ë ¥ë°›ì„ ìˆ˜ 있게 남겨ë‘
+
+ // returnDateê°€ 빈 문ìžì—´ì´ ì•„ë‹Œ 경우ì—만 파ë¼ë¯¸í„° 추가
+ if (request.getReturnDate() != null && !request.getReturnDate().isEmpty()) {
+ params.and("returnDate", request.getReturnDate());
+ }
+
+ FlightOfferSearch[] flightOffers = amadeus.shopping.flightOffersSearch.get(params);
+
+ Gson gson = new Gson();
+ String flightOffersJson = gson.toJson(flightOffers);
+ return flightOfferProcessor.processFlightOffers(flightOffersJson);
+ }
+
+
+ /** í•ê³µê¶Œ ì„ íƒì‹œ 스카ì´ìŠ¤ìºë„ˆ 사ì´íŠ¸ë¡œ ì—°ê²° **/
+ @Override
+ public String generateSkyscannerUrl(SkyScannerRequest request) {
+ // ìš”ì² ë°ì´í„° ì •ì œ
+ String departureDate = request.getDepartureDate().replace("-", "").substring(2) + "/";
+ String returnDate = (request.getReturnDate() != null && !request.getReturnDate().isEmpty()) ? request.getReturnDate().replace("-", "").substring(2) + "/" : "";
+ int departureTimeMinutes = convertToMinutes(request.getDepartureTime());
+ String childrenParam = buildChildrenParam(request.getChildren());
+
+ String url = "https://www.skyscanner.co.kr/transport/flights/" +
+ request.getDepartureIataCode().toLowerCase() + "/" +
+ request.getArrivalIataCode().toLowerCase() + "/" +
+ departureDate + returnDate + "?adultsv2=" + request.getAdult() + childrenParam +
+ "&departure-times=" + departureTimeMinutes +
+ "&inboundaltsenabled=false&outboundaltsenabled=false&ref=home&rtn=" + (returnDate.isEmpty() ? "0" : "1");
+
+ // ì§í•ì¸ 경우
+ if (request.getTransferCount() == 0) {
+ url += "&preferdirects=true";
+ } else if (request.getTransferCount() == 1) {
+ url += "&preferdirects=false&stops=!direct";
+ } else {
+ url += "&preferdirects=false&stops=!direct,!oneStop,!oneStop";
+ }
+ return url;
+ }
+
+ /** childern 계산 **/
+ private String buildChildrenParam(int count) {
+ if (count <= 0) { return ""; }
+ StringBuilder childrenBuilder = new StringBuilder("&children=");
+ childrenBuilder.append(count);
+ if (count > 1) {
+ childrenBuilder.append("&childrenv2=");
+ childrenBuilder.append(String.join("%7c", Collections.nCopies(count, "8")));
+ }
+ return childrenBuilder.toString();
+ }
+
+ /**
+ * í•ê³µê¶Œ 좋아요 ì €ìž¥
+ **/
+ @Override
+ @Transactional
+ public Long addLikeFlight(String uid, FlightLikeRequest flightLikeRequest) {
+ // ìœ ì € ì •ë³´ 확ì¸
+ Member findMember = scheduleService.validateUserCheck(uid);
+
+ // 출발지, ë„착지 ì •ë³´
+ Country departureIataCode = countryRepository.findCountryByAirportCode(flightLikeRequest.getDepartureIataCode())
+ .orElseThrow(()-> new IataCodeNotFoundException());
+ Country arrivalIataCode = countryRepository.findCountryByAirportCode(flightLikeRequest.getArrivalIataCode())
+ .orElseThrow(()-> new IataCodeNotFoundException());
+
+ // ë°ì´í„° 변환 ë° ì €ìž¥
+ Flight flight = flightMapper.toEntity(flightLikeRequest, findMember, departureIataCode, arrivalIataCode);
+ flightRepository.save(flight);
+ return flight.getId();
+ }
+
+
+ /** í•ê³µê¶Œ ë‚˜ì˜ ì¢‹ì•„ìš” ëª©ë¡ ë¶ˆëŸ¬ì˜¤ê¸° **/
+ @Override
+ public List getLikedFlights(String memberUid) {
+ Member findMember = scheduleService.validateUserCheck(memberUid);
+ List likedFlights = flightRepository.findByMember(findMember);
+
+ return flightMapper.toFlightLikeRequestList(likedFlights);
+ }
+
+
+ /** í•ê³µê¶Œ ë‚˜ì˜ ì¢‹ì•„ìš” ì‚ì œ **/
+ @Override
+ @Transactional
+ public void deleteLikeFlight(String memberUid, Long id) {
+ Member findMember = scheduleService.validateUserCheck(memberUid);
+
+ // 해당 í•ê³µê¶Œ id 조회
+ Flight flight = flightRepository.findById(id).orElseThrow(() -> new FlightNotFoundException());
+
+ // 해당 í•ê³µê¶Œì´ ìœ ì €ì˜ ê²ƒì¸ì§€ 확ì¸
+ if (!flight.getMember().getId().equals(findMember.getId())) {
+ throw new NotYourFlightException();
+ }
+
+ flightRepository.delete(flight);
+ }
+
+ /** ê³µí• ì½”ë“œ 찾기 **/
+ String findAirportCode(String countryName) {
+ Country findCountry = countryRepository.findAirportCodeByCity(countryName)
+ .orElseThrow(() -> new CountryNotFoundException());
+ return findCountry.getAirportCode();
+ }
+
+
+ /** ì‹œê°„ì„ ë¶„ìœ¼ë¡œ 변환 **/
+ static int convertToMinutes(String timeString) {
+ String[] parts = timeString.split(":");
+ int hours = Integer.parseInt(parts[0]);
+ int minutes = Integer.parseInt(parts[1]);
+ return hours * 60 + minutes;
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/config/GptConfig.java b/backend/src/main/java/com/isp/backend/domain/gpt/config/GptConfig.java
new file mode 100644
index 00000000..0e483671
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/config/GptConfig.java
@@ -0,0 +1,73 @@
+package com.isp.backend.domain.gpt.config;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class GptConfig {
+ public static final String BEARER = "Bearer ";
+ public static final String CHAT_MODEL = "gpt-4o";
+ public static final Integer MAX_TOKEN = 4095;
+ public static final Boolean STREAM = false;
+ public static final String ROLE = "user";
+ public static final Double TEMPERATURE = 0.9;
+ public static final String CHAT_URL = "https://api.openai.com/v1/chat/completions";
+ public static final String PROMPT = """
+ 너는 매우 ì¸ê¸°ìžˆëŠ” 여행사 ì§ì›ì´ì•¼.
+ 여행사 ê³ ê°ì„ 위해 패키지 ì—¬í–‰ì„ ê³„íší•˜ì—¬ ì¼ì •ì„ 만들어줘야 ë¼.
+
+ 여행지: %s
+ ì´ë²ˆ ì—¬í–‰ì˜ ëª©ì : %s
+ ì—¬í–‰ì— í¬í•¨í•˜ê³ ì‹¶ì€ í™œë™: %s
+ 여행ì—ì„œ ì œì™¸í•˜ê³ ì‹¶ì€ í™œë™: %s
+ í•œêµì—ì„œ 출êµí•˜ëŠ” ë‚ ì§œ: %s
+ í•œêµìœ¼ë¡œ ê·€êµí•˜ëŠ” ë‚ ì§œ: %s
+
+ 위 ì •ë³´ë“¤ì„ í† ëŒ€ë¡œ ì¼ì •ì„ 만들어줘
+
+ 너가 주ì˜í•´ì•¼ í• ì‚¬í•ì€ 아래 네가지야.
+
+ 1. ê³ ê°ì´ ì›í•˜ëŠ” 목ì 지를 기반으로 여행 계íšì„ 만들어 줘야 하는ë°, 너무 멀리 있는 ìž¥ì†Œë“¤ì„ ë¬¶ìœ¼ë©´ 안ë¼.
+ 2. í•˜ë£¨ì— ìµœì†Œ 세 ê°œì˜ ëª…ì†Œë¥¼ ë°©ë¬¸í•˜ê³ ì‹¶ì–´.
+ 3. í•˜ë£¨ì— ìµœì†Œ 9ì‹œê°„ì„ ëŒì•„다ë‹ê±°ì•¼.
+ 4. 3ì¼ ê°„ì˜ ì—¬í–‰ì´ë©´ 3ì¼ì§œë¦¬ 계íšì„ 만들어주면 ë¼.
+ 5. ìž¥ì†Œì˜ ì¢Œí‘¯ê°’ë„ ì†Œìˆ˜ì 까지 함께 ì•Œë ¤ì¤˜
+ 6. 특수 문ìžë¥¼ 사용하지 ì•Šê³ , 아래 예시대로 ì¼ì •ì„ 작성해줘
+
+ 4ë²ˆì˜ ì˜ˆì‹œëŠ” 아래와 같아
+
+ <2024.02.06>
+
+ - 세비야 대성당 37.38610100, -5.99220400
+ - 알카사르 세비야 37.38338500, -5.99051600
+ - ì 심ì‹ì‚¬ ì—스피넬리 글로리아 37.39404600, -5.99379500
+ - 히랄다 탑 37.38603000, -5.99303300
+ - ìŠ¤íŽ˜ì¸ ê´‘ìž¥ 37.37722200, -5.98694400
+ - ì €ë…ì‹ì‚¬ 바루로 37.37734300, -5.98742700
+ - 쇼핑 세비야 ì—˜ 코르테 ìž‰ê¸€ë ˆìŠ¤ 37.38942400, -5.99407200
+
+ <2024.02.07>
+
+ - 세비야 대성당 37.38610100, -5.99220400
+ - 알카사르 세비야 37.38338500, -5.99051600
+ - ì 심ì‹ì‚¬ ì—스피넬리 글로리아 37.39404600, -5.99379500
+ - 히랄다 탑 37.38603000, -5.99303300
+ - ìŠ¤íŽ˜ì¸ ê´‘ìž¥ 37.37722200, -5.98694400
+ - ì €ë…ì‹ì‚¬ 바루로 37.37734300, -5.98742700
+ - 쇼핑 세비야 ì—˜ 코르테 ìž‰ê¸€ë ˆìŠ¤ 37.38942400, -5.99407200
+
+ <2024.02.08>
+
+ - 세비야 대성당 37.38610100, -5.99220400
+ - 알카사르 세비야 37.38338500, -5.99051600
+ - ì 심ì‹ì‚¬ ì—스피넬리 글로리아 37.39404600, -5.99379500
+ - 히랄다 탑 37.38603000, -5.99303300
+ - ìŠ¤íŽ˜ì¸ ê´‘ìž¥ 37.37722200, -5.98694400
+ - ì €ë…ì‹ì‚¬ 바루로 37.37734300, -5.98742700
+ - 쇼핑 세비야 ì—˜ 코르테 ìž‰ê¸€ë ˆìŠ¤ 37.38942400, -5.99407200
+
+ ë‚ ì§œ 형ì‹ì€ 반드시 ì„ ì§€ì¼œì¤˜.
+ ë§¤ì¼ ì 심과 ì €ë…ì€ ë ˆìŠ¤í† ëž‘ì—ì„œ ë¨¹ì„ ê±°ë‹ˆê¹Œ, ì‹¤ì œë¡œ ë§›ìžˆê³ ìœ ëª…í•œ ë ˆìŠ¤í† ëž‘ë„ ì¼ì •ì— í¬í•¨ì‹œì¼œì¤˜.
+ 모ë‘ê°€ ë„ˆì˜ ê³„íšì„ ê¸°ëŒ€í•˜ê³ ìžˆì–´.
+ 다른 ë§ì€ 하지 ë§ê³ , ì˜¤ì§ ì¼ì •ë§Œ ì œê³µí•´ì¤˜""";
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/config/WebClientConfig.java b/backend/src/main/java/com/isp/backend/domain/gpt/config/WebClientConfig.java
new file mode 100644
index 00000000..72b4a361
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/config/WebClientConfig.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.gpt.config;
+
+import io.netty.channel.ChannelOption;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.handler.timeout.WriteTimeoutHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.netty.http.client.HttpClient;
+
+
+@Configuration
+public class WebClientConfig {
+ @Bean
+ public WebClient webClient() {
+ HttpClient httpClient = HttpClient.create()
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30000)
+ .doOnConnected(conn -> conn
+ .addHandlerLast(new ReadTimeoutHandler(50))
+ .addHandlerLast(new WriteTimeoutHandler(50)));
+ return WebClient.builder()
+ .clientConnector(new ReactorClientHttpConnector(httpClient))
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/constant/ParsingConstants.java b/backend/src/main/java/com/isp/backend/domain/gpt/constant/ParsingConstants.java
new file mode 100644
index 00000000..dd27dcbc
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/constant/ParsingConstants.java
@@ -0,0 +1,13 @@
+package com.isp.backend.domain.gpt.constant;
+
+import java.util.List;
+
+public class ParsingConstants {
+ public static final String DATE_REGEX = "(\\d{4}\\.\\d{2}\\.\\d{2})";
+ public static final String NEW_LINE_REGEX = "\n";
+ public static final String CURRENT_DATE = "";
+ public static final String COMMA = ", ";
+ public static final List FILTER_STRINGS = List.of(
+ "Message(role=assistant, content=", ")"
+ );
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/controller/GptController.java b/backend/src/main/java/com/isp/backend/domain/gpt/controller/GptController.java
new file mode 100644
index 00000000..04dade00
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/controller/GptController.java
@@ -0,0 +1,23 @@
+package com.isp.backend.domain.gpt.controller;
+
+import com.isp.backend.domain.gpt.dto.request.GptScheduleRequest;
+import com.isp.backend.domain.gpt.dto.response.GptSchedulesResponse;
+import com.isp.backend.domain.gpt.service.GptService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.concurrent.CompletableFuture;
+
+@RequiredArgsConstructor
+@RequestMapping("/gpt")
+@RestController
+@ResponseStatus(value = HttpStatus.CREATED)
+public class GptController {
+ private final GptService gptService;
+
+ @PostMapping("/schedules")
+ public CompletableFuture sendQuestion(@RequestBody GptScheduleRequest gptScheduleRequest) {
+ return gptService.askQuestion(gptScheduleRequest);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/dto/request/GptRequest.java b/backend/src/main/java/com/isp/backend/domain/gpt/dto/request/GptRequest.java
new file mode 100644
index 00000000..db204941
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/dto/request/GptRequest.java
@@ -0,0 +1,22 @@
+package com.isp.backend.domain.gpt.dto.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.isp.backend.domain.gpt.entity.GptMessage;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class GptRequest {
+ private String model;
+
+ @JsonProperty("max_tokens")
+ private Integer maxTokens;
+ private Double temperature;
+ private Boolean stream;
+ private List messages;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/dto/request/GptScheduleRequest.java b/backend/src/main/java/com/isp/backend/domain/gpt/dto/request/GptScheduleRequest.java
new file mode 100644
index 00000000..70e51901
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/dto/request/GptScheduleRequest.java
@@ -0,0 +1,19 @@
+package com.isp.backend.domain.gpt.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class GptScheduleRequest {
+ private String destination;
+ private List purpose;
+ private List includedActivities;
+ private List excludedActivities;
+ private String departureDate;
+ private String returnDate;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptResponse.java b/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptResponse.java
new file mode 100644
index 00000000..eefdf30c
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptResponse.java
@@ -0,0 +1,22 @@
+package com.isp.backend.domain.gpt.dto.response;
+
+import com.isp.backend.domain.gpt.entity.GptMessage;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class GptResponse {
+ private List choices;
+
+ @Getter
+ @Setter
+ public static class Choice {
+ private GptMessage message;
+ }
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptScheduleResponse.java b/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptScheduleResponse.java
new file mode 100644
index 00000000..9ca3d044
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptScheduleResponse.java
@@ -0,0 +1,15 @@
+package com.isp.backend.domain.gpt.dto.response;
+
+import com.isp.backend.domain.gpt.entity.GptSchedule;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class GptScheduleResponse {
+ private List schedule;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptSchedulesResponse.java b/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptSchedulesResponse.java
new file mode 100644
index 00000000..52dadab1
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/dto/response/GptSchedulesResponse.java
@@ -0,0 +1,15 @@
+package com.isp.backend.domain.gpt.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class GptSchedulesResponse {
+ private String countryImage;
+ private List schedules;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/entity/Coordinate.java b/backend/src/main/java/com/isp/backend/domain/gpt/entity/Coordinate.java
new file mode 100644
index 00000000..f3bb8bc7
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/entity/Coordinate.java
@@ -0,0 +1,16 @@
+package com.isp.backend.domain.gpt.entity;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class Coordinate {
+ private Double latitude;
+ private Double longitude;
+
+ public Coordinate(Double latitude, Double longitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptMessage.java b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptMessage.java
new file mode 100644
index 00000000..beaac34b
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptMessage.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.gpt.entity;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+public class GptMessage implements Serializable {
+ private String role;
+ private String content;
+
+ @Builder
+ public GptMessage(String role, String content) {
+ this.role = role;
+ this.content = content;
+ }
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptSchedule.java b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptSchedule.java
new file mode 100644
index 00000000..c78e099d
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptSchedule.java
@@ -0,0 +1,18 @@
+package com.isp.backend.domain.gpt.entity;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+public class GptSchedule {
+ private String date;
+ private List scheduleDetail;
+
+ public GptSchedule(String date, List scheduleDetail) {
+ this.date = date;
+ this.scheduleDetail = scheduleDetail;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptScheduleDetail.java b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptScheduleDetail.java
new file mode 100644
index 00000000..99781771
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptScheduleDetail.java
@@ -0,0 +1,16 @@
+package com.isp.backend.domain.gpt.entity;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class GptScheduleDetail {
+ private String detail;
+ private Coordinate coordinate;
+
+ public GptScheduleDetail(String detail, Coordinate coordinate) {
+ this.detail = detail;
+ this.coordinate = coordinate;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptScheduleParser.java b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptScheduleParser.java
new file mode 100644
index 00000000..ce3914e3
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/entity/GptScheduleParser.java
@@ -0,0 +1,65 @@
+package com.isp.backend.domain.gpt.entity;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RequiredArgsConstructor
+@Component
+public class GptScheduleParser {
+
+ public List parseScheduleText(String scheduleText) {
+ System.out.println(scheduleText);
+ List schedules = new ArrayList<>();
+
+ String[] entries = scheduleText.split("<");
+
+ for (String entry : entries) {
+ if (entry.trim().isEmpty()) continue;
+
+ String[] lines = entry.split("\n");
+ String date = lines[0].trim().replace(">", "");
+
+ List scheduleDetails = new ArrayList<>();
+
+ for (int i = 1; i < lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.isEmpty()) continue;
+
+ String[] parts = line.split(" ");
+ StringBuilder detail = new StringBuilder();
+ double latitude = 0.0;
+ double longitude = 0.0;
+
+ for (int j = 0; j < parts.length; j++) {
+ try {
+ if (j == parts.length - 2) {
+ latitude = Double.parseDouble(parts[j].replace(",", ""));
+ } else if (j == parts.length - 1) {
+ longitude = Double.parseDouble(parts[j]);
+ } else {
+ if (!detail.isEmpty()) detail.append(" ");
+ detail.append(parts[j]);
+ }
+ } catch (NumberFormatException e) {
+ if (!detail.isEmpty()) detail.append(" ");
+ detail.append(parts[j]);
+ }
+ }
+
+ String detailString = detail.toString().trim();
+ if (detailString.startsWith("-")) {
+ detailString = detailString.substring(1).trim();
+ }
+
+ scheduleDetails.add(new GptScheduleDetail(detailString, new Coordinate(latitude, longitude)));
+ }
+
+ schedules.add(new GptSchedule(date, scheduleDetails));
+ }
+
+ return schedules;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/service/GptService.java b/backend/src/main/java/com/isp/backend/domain/gpt/service/GptService.java
new file mode 100644
index 00000000..cbb9fbb2
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/gpt/service/GptService.java
@@ -0,0 +1,116 @@
+package com.isp.backend.domain.gpt.service;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.gpt.config.GptConfig;
+import com.isp.backend.domain.gpt.constant.ParsingConstants;
+import com.isp.backend.domain.gpt.dto.request.GptRequest;
+import com.isp.backend.domain.gpt.dto.request.GptScheduleRequest;
+import com.isp.backend.domain.gpt.dto.response.GptResponse;
+import com.isp.backend.domain.gpt.dto.response.GptScheduleResponse;
+import com.isp.backend.domain.gpt.dto.response.GptSchedulesResponse;
+import com.isp.backend.domain.gpt.entity.GptMessage;
+import com.isp.backend.domain.gpt.entity.GptSchedule;
+import com.isp.backend.domain.gpt.entity.GptScheduleParser;
+import com.isp.backend.domain.schedule.service.ScheduleService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class GptService {
+
+ private final GptScheduleParser gptScheduleParser;
+ private final ScheduleService scheduleService;
+ private final WebClient webClient;
+
+ @Value("${api-key.gpt-trip}")
+ private String apiKey;
+
+ public GptScheduleResponse getResponse(HttpHeaders headers, GptRequest gptRequest) {
+ GptResponse response = webClient.post()
+ .uri(GptConfig.CHAT_URL)
+ .headers(h -> h.addAll(headers))
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(BodyInserters.fromValue(gptRequest))
+ .retrieve()
+ .bodyToMono(GptResponse.class)
+ .block();
+
+ List gptSchedules = gptScheduleParser.parseScheduleText(extractScheduleText(response));
+ return new GptScheduleResponse(gptSchedules);
+ }
+
+ private String extractScheduleText(GptResponse gptResponse) {
+ return gptResponse.getChoices().get(0).getMessage().getContent();
+ }
+
+ @Async
+ public CompletableFuture askQuestion(GptScheduleRequest questionRequest) {
+ String question = formatQuestion(questionRequest);
+ List messages = Collections.singletonList(createMessage(question));
+ Country country = scheduleService.validateCountry(questionRequest.getDestination());
+ String countryImage = country.getImageUrl();
+
+ ExecutorService executorService = Executors.newFixedThreadPool(5);
+ List> futures = Arrays.asList(
+ sendRequestAsync(messages, executorService),
+ sendRequestAsync(messages, executorService),
+ sendRequestAsync(messages, executorService)
+ );
+
+ CompletableFuture> combinedFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
+ .thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList()));
+
+ return combinedFuture.thenApply(schedules -> new GptSchedulesResponse(countryImage, schedules));
+ }
+
+ private CompletableFuture sendRequestAsync(List messages, ExecutorService executor) {
+ HttpHeaders headers = buildHttpHeaders(apiKey);
+ GptRequest request = createGptRequest(messages);
+ return CompletableFuture.supplyAsync(() -> getResponse(headers, request), executor);
+ }
+
+ private GptRequest createGptRequest(List messages) {
+ return new GptRequest(GptConfig.CHAT_MODEL, GptConfig.MAX_TOKEN, GptConfig.TEMPERATURE, GptConfig.STREAM, messages);
+ }
+
+ private HttpHeaders buildHttpHeaders(String key) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ headers.add(HttpHeaders.AUTHORIZATION, GptConfig.BEARER + key);
+ return headers;
+ }
+
+ private String formatQuestion(GptScheduleRequest questionRequest) {
+ return String.format(GptConfig.PROMPT,
+ questionRequest.getDestination(),
+ questionRequest.getPurpose(),
+ questionRequest.getIncludedActivities(),
+ questionRequest.getExcludedActivities(),
+ questionRequest.getDepartureDate(),
+ questionRequest.getReturnDate(),
+ String.join(ParsingConstants.COMMA, questionRequest.getPurpose())
+ );
+ }
+
+ private GptMessage createMessage(String content) {
+ return GptMessage.builder()
+ .role(GptConfig.ROLE)
+ .content(content)
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/hotel/controller/HotelController.java b/backend/src/main/java/com/isp/backend/domain/hotel/controller/HotelController.java
new file mode 100644
index 00000000..d262634a
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/hotel/controller/HotelController.java
@@ -0,0 +1,43 @@
+package com.isp.backend.domain.hotel.controller;
+
+import com.amadeus.exceptions.ResponseException;
+import com.isp.backend.domain.hotel.dto.request.SearchGeocodeRequest;
+import com.isp.backend.domain.hotel.service.HotelService;
+import com.isp.backend.global.exception.openApi.AmadeusSearchFailedException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/bookings/hotels")
+@RequiredArgsConstructor
+public class HotelController {
+
+ private final HotelService hotelService ;
+
+ /** 좌표 주변 호텔 리스트 API **/
+ @PostMapping("/search")
+ public ResponseEntity searchHotelsByGeocode(@RequestBody SearchGeocodeRequest request) {
+ try {
+ String hotelsJson = hotelService.searchHotelsByGeocode(request);
+ return ResponseEntity.ok(hotelsJson);
+ } catch (ResponseException e) {
+ throw new AmadeusSearchFailedException();
+ }
+ }
+
+ /** 호텔 ì„ íƒì‹œ 스카ì´ìŠ¤ìºë„ˆ 사ì´íŠ¸ë¡œ ì—°ê²° API **/
+
+
+ /** 호텔 좋아요 ì €ìž¥ API **/
+
+
+ /** 호텔 좋아요 ëª©ë¡ ë¶ˆëŸ¬ì˜¤ê¸° API **/
+
+
+ /** 호텔 좋아요 ì‚ì œí•˜ê¸° API **/
+
+
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/hotel/dto/request/SearchCityRequest.java b/backend/src/main/java/com/isp/backend/domain/hotel/dto/request/SearchCityRequest.java
new file mode 100644
index 00000000..1d9aa3ac
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/hotel/dto/request/SearchCityRequest.java
@@ -0,0 +1,4 @@
+package com.isp.backend.domain.hotel.dto.request;
+
+public class SearchCityRequest {
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/hotel/dto/request/SearchGeocodeRequest.java b/backend/src/main/java/com/isp/backend/domain/hotel/dto/request/SearchGeocodeRequest.java
new file mode 100644
index 00000000..3069b085
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/hotel/dto/request/SearchGeocodeRequest.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.hotel.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class SearchGeocodeRequest {
+
+ private String latitude;
+
+ private String longitude;
+
+ private int radius ;
+
+ private String ratings ; // 호텔 등급
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelSearchService.java b/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelSearchService.java
new file mode 100644
index 00000000..d623efaa
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelSearchService.java
@@ -0,0 +1,16 @@
+package com.isp.backend.domain.hotel.service;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+@Service
+public class HotelSearchService {
+
+ /** 좌표 주변 호텔 리스트 API **/
+
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelService.java b/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelService.java
new file mode 100644
index 00000000..bc4fd247
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelService.java
@@ -0,0 +1,10 @@
+package com.isp.backend.domain.hotel.service;
+
+import com.amadeus.exceptions.ResponseException;
+import com.amadeus.resources.Hotel;
+import com.isp.backend.domain.hotel.dto.request.SearchGeocodeRequest;
+
+public interface HotelService {
+ public String searchHotelsByGeocode(SearchGeocodeRequest request) throws ResponseException;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelServiceImpl.java
new file mode 100644
index 00000000..b1d88ea6
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/hotel/service/HotelServiceImpl.java
@@ -0,0 +1,44 @@
+package com.isp.backend.domain.hotel.service;
+
+import com.amadeus.Amadeus;
+import com.amadeus.Params;
+import com.amadeus.exceptions.ResponseException;
+import com.amadeus.resources.Hotel;
+import com.amadeus.shopping.HotelOffersSearch;
+import com.google.gson.Gson;
+import com.isp.backend.domain.hotel.dto.request.SearchGeocodeRequest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+@Service
+public class HotelServiceImpl implements HotelService {
+ private final Amadeus amadeus;
+
+ /**
+ * 좌표 주변 호텔 리스트 API
+ **/
+ @Override
+ public String searchHotelsByGeocode(SearchGeocodeRequest request) throws ResponseException {
+ String latitude = request.getLatitude();
+ String longitude = request.getLongitude();
+ int radius = request.getRadius();
+ String ratings = request.getRatings();
+
+ Hotel[] hotelSearch = amadeus.referenceData.locations.hotels.byGeocode.get(
+ Params.with("latitude", latitude)
+ .and("longitude", longitude)
+ .and("radius", radius)
+ .and("radiusUnit", "KM")
+ .and("ratings", ratings)
+ .and("hotelSource", "ALL")
+ );
+ Gson gson = new Gson();
+ String hotelSearchJson = gson.toJson(hotelSearch);
+ return hotelSearchJson;
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java b/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java
new file mode 100644
index 00000000..1dfe8c9d
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java
@@ -0,0 +1,55 @@
+package com.isp.backend.domain.member.controller;
+
+import com.isp.backend.domain.member.dto.request.AuthRecreateRequest;
+import com.isp.backend.domain.member.dto.request.GoogleLoginRequest;
+import com.isp.backend.domain.member.dto.response.MemberDetailResponse;
+import com.isp.backend.domain.member.dto.request.SignUpRequest;
+import com.isp.backend.domain.member.service.MemberService;
+import com.isp.backend.global.security.CustomUserDetails;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/members")
+@RequiredArgsConstructor
+public class MemberController {
+
+ private final MemberService memberService;
+
+
+ /** ë¡œê·¸ì¸ API **/
+ @PostMapping("/login")
+ public ResponseEntity memberLogin(@RequestBody GoogleLoginRequest request) {
+ return memberService.memberLogin(request);
+ }
+
+
+
+ /** 회ì›ê°€ìž… - 추가 ì •ë³´ API **/
+ @PutMapping("/signUp")
+ public ResponseEntity signUp(@RequestBody SignUpRequest request,
+ @AuthenticationPrincipal CustomUserDetails customUserDetails) {
+ String memberUid = customUserDetails.getUsername();
+ memberService.signUp(request, memberUid);
+ return ResponseEntity.status(HttpStatus.OK).build();
+ }
+
+
+ /** í† í° ìž¬ë°œí–‰ **/
+ @PostMapping("/refresh")
+ public ResponseEntity authRecreate(@RequestBody AuthRecreateRequest authRecreateRequest) {
+ return memberService.authRecreate(authRecreateRequest);
+ }
+
+
+ /** 멤버 ì •ë³´ 조회 **/
+ @GetMapping("/information")
+ public ResponseEntity getMemberInfo(@AuthenticationPrincipal CustomUserDetails customUserDetails) {
+ return ResponseEntity.ok(memberService.getMemberInfo(customUserDetails.getUsername()));
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/dto/request/AuthRecreateRequest.java b/backend/src/main/java/com/isp/backend/domain/member/dto/request/AuthRecreateRequest.java
new file mode 100644
index 00000000..f5dc4732
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/dto/request/AuthRecreateRequest.java
@@ -0,0 +1,14 @@
+package com.isp.backend.domain.member.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class AuthRecreateRequest {
+
+ private String refreshToken;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/dto/request/GoogleLoginRequest.java b/backend/src/main/java/com/isp/backend/domain/member/dto/request/GoogleLoginRequest.java
new file mode 100644
index 00000000..33da9035
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/dto/request/GoogleLoginRequest.java
@@ -0,0 +1,14 @@
+package com.isp.backend.domain.member.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class GoogleLoginRequest {
+
+ private String uid;
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/member/dto/request/SignUpRequest.java b/backend/src/main/java/com/isp/backend/domain/member/dto/request/SignUpRequest.java
new file mode 100644
index 00000000..abca41a0
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/dto/request/SignUpRequest.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.member.dto.request;
+
+import com.isp.backend.domain.member.entity.Member;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class SignUpRequest {
+
+ private String name;
+
+ private String birth;
+
+ private String phoneNumber;
+
+
+ public void toEntity(Member member) {
+ member.setName(this.name);
+ member.setBirth(this.birth);
+ member.setPhoneNumber(this.phoneNumber);
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/dto/response/MemberDetailResponse.java b/backend/src/main/java/com/isp/backend/domain/member/dto/response/MemberDetailResponse.java
new file mode 100644
index 00000000..8eb44212
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/dto/response/MemberDetailResponse.java
@@ -0,0 +1,29 @@
+package com.isp.backend.domain.member.dto.response;
+
+import com.isp.backend.domain.member.entity.Member;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public class MemberDetailResponse {
+
+ private final String uid;
+
+ private final String name;
+
+ private final String birth;
+
+ private final String phoneNumber;
+
+
+ public static MemberDetailResponse fromEntity(Member member) {
+ return new MemberDetailResponse(
+ member.getUid(),
+ member.getName(),
+ member.getBirth(),
+ member.getPhoneNumber());
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/entity/Member.java b/backend/src/main/java/com/isp/backend/domain/member/entity/Member.java
new file mode 100644
index 00000000..c35ee15e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/entity/Member.java
@@ -0,0 +1,34 @@
+package com.isp.backend.domain.member.entity;
+
+import com.isp.backend.global.common.BaseEntity;
+import jakarta.persistence.*;
+import lombok.*;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "member")
+public class Member extends BaseEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(nullable = false)
+ private String uid;
+
+ private String name;
+
+ private String birth;
+
+ private String phoneNumber;
+
+ private String loginType;
+
+ @Builder.Default
+ @Column(nullable = false)
+ private boolean activated = true;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java b/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java
new file mode 100644
index 00000000..f062c07e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java
@@ -0,0 +1,14 @@
+package com.isp.backend.domain.member.repository;
+
+import com.isp.backend.domain.member.entity.Member;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface MemberRepository extends JpaRepository {
+
+ Optional findByUidAndActivatedIsTrue(String Uid);
+
+ Optional findByUid(String Uid);
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java b/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java
new file mode 100644
index 00000000..44f6645c
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java
@@ -0,0 +1,22 @@
+package com.isp.backend.domain.member.service;
+
+import com.isp.backend.domain.member.dto.request.AuthRecreateRequest;
+import com.isp.backend.domain.member.dto.request.GoogleLoginRequest;
+import com.isp.backend.domain.member.dto.response.MemberDetailResponse;
+import com.isp.backend.domain.member.dto.request.SignUpRequest;
+import com.isp.backend.domain.member.entity.Member;
+import org.springframework.http.ResponseEntity;
+
+public interface MemberService {
+ ResponseEntity memberLogin(GoogleLoginRequest request);
+
+ void signUp(SignUpRequest signUpRequest, String memberUid);
+
+ ResponseEntity handleExistingMemberLogin(Member existingMember);
+
+ ResponseEntity handleNewMemberLogin(GoogleLoginRequest request);
+
+ ResponseEntity authRecreate(AuthRecreateRequest authRecreateRequest);
+
+ MemberDetailResponse getMemberInfo(String uid);
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java
new file mode 100644
index 00000000..bc385072
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java
@@ -0,0 +1,129 @@
+package com.isp.backend.domain.member.service;
+
+import com.isp.backend.domain.member.dto.request.AuthRecreateRequest;
+import com.isp.backend.domain.member.dto.request.GoogleLoginRequest;
+import com.isp.backend.domain.member.dto.response.MemberDetailResponse;
+import com.isp.backend.domain.member.dto.request.SignUpRequest;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.member.repository.MemberRepository;
+import com.isp.backend.global.exception.common.MemberNotActivatedException;
+import com.isp.backend.global.exception.common.MemberNotFoundException;
+import com.isp.backend.global.exception.common.RefreshTokenInvalidException;
+import com.isp.backend.global.jwt.TokenProvider;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+@Service
+
+public class MemberServiceImpl implements MemberService {
+
+ private final MemberRepository memberRepository;
+ private final TokenProvider tokenProvider;
+
+
+ /** ë¡œê·¸ì¸ ë©”ì„œë“œ - jwt í† í° ìƒì„±í›„ ì‘답 **/
+ @Transactional
+ @Override
+ public ResponseEntity memberLogin(GoogleLoginRequest request) {
+ Optional existingMemberOptional = memberRepository.findByUid(request.getUid());
+
+ if (existingMemberOptional.isPresent()) {
+ Member existingMember = existingMemberOptional.get();
+ if (existingMember.isActivated()) {
+ return handleExistingMemberLogin(existingMember);
+ } else {
+ throw new MemberNotActivatedException();
+ }
+ } else {
+ return handleNewMemberLogin(request);
+ }
+ }
+
+
+
+ /** 기존 회ì›ì˜ ë¡œê·¸ì¸ **/
+ @Override
+ public ResponseEntity handleExistingMemberLogin(Member existingMember) {
+ String accessToken = tokenProvider.createAccessToken(existingMember.getUid());
+ String refreshToken = tokenProvider.createRefreshToken(existingMember.getUid());
+ return ResponseEntity.ok()
+ .header("Access-Token", accessToken)
+ .header("Refresh-Token", refreshToken)
+ .body("기존 íšŒì› ë¡œê·¸ì¸");
+ }
+
+
+
+ /** ì‹ ê·œ 회ì›ì˜ ë¡œê·¸ì¸ -> DB ì €ìž¥ **/
+ @Override
+ public ResponseEntity handleNewMemberLogin(GoogleLoginRequest request) {
+ Member newMember = Member.builder()
+ .uid(request.getUid())
+ .loginType("google")
+ .build();
+ memberRepository.save(newMember);
+
+ String accessToken = tokenProvider.createAccessToken(newMember.getUid());
+ String refreshToken = tokenProvider.createRefreshToken(newMember.getUid());
+
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .header("Access-Token", accessToken)
+ .header("Refresh-Token", refreshToken)
+ .body("ì‹ ê·œ íšŒì› ë¡œê·¸ì¸");
+ }
+
+
+
+ /** 회ì›ê°€ìž… - ì‹ ê·œ ìœ ì €ì˜ ê²½ìš° 추가 ì •ë³´ ì €ìž¥ **/
+ @Transactional
+ @Override
+ public void signUp(SignUpRequest signUpRequest, String memberUid) {
+ Member findMember = memberRepository.findByUid(memberUid)
+ .orElseThrow(() -> new MemberNotFoundException());
+ signUpRequest.toEntity(findMember);
+ memberRepository.save(findMember);
+ }
+
+
+
+ /** í† í° ìž¬ë°œí–‰ **/
+ @Transactional
+ @Override
+ public ResponseEntity authRecreate(AuthRecreateRequest authRecreateRequest) {
+
+ if (!tokenProvider.validateRefreshToken(authRecreateRequest.getRefreshToken())) {
+ throw new RefreshTokenInvalidException();
+ }
+ String uid = tokenProvider.getUid(authRecreateRequest.getRefreshToken());
+
+ Member member = memberRepository.findByUidAndActivatedIsTrue(uid)
+ .orElseThrow(MemberNotFoundException::new);
+
+ String accessToken = tokenProvider.createAccessToken(member.getUid());
+ String refreshToken = tokenProvider.createRefreshToken(member.getUid());
+
+ return ResponseEntity.ok()
+ .header("Access-Token", accessToken)
+ .header("Refresh-Token", refreshToken)
+ .body(null);
+ }
+
+
+ /** 멤버 ì •ë³´ 조회 **/
+ @Override
+ public MemberDetailResponse getMemberInfo (String uid) {
+ Member member = memberRepository.findByUid(uid)
+ .orElseThrow(MemberNotFoundException::new);
+ return(MemberDetailResponse.fromEntity(member));
+ }
+
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java b/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java
new file mode 100644
index 00000000..394f3d18
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java
@@ -0,0 +1,100 @@
+package com.isp.backend.domain.receipt.controller;
+
+import com.isp.backend.domain.receipt.dto.request.ChangeReceiptOrderRequest;
+import com.isp.backend.domain.receipt.dto.request.SaveReceiptRequest;
+import com.isp.backend.domain.receipt.dto.response.ReceiptResponse;
+import com.isp.backend.domain.receipt.dto.response.ScheduleListWithReceiptResponse;
+import com.isp.backend.domain.receipt.dto.response.ScheduleReceiptResponse;
+import com.isp.backend.domain.receipt.entity.Receipt;
+import com.isp.backend.domain.receipt.service.ReceiptService;
+import com.isp.backend.global.security.CustomUserDetails;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/receipts")
+@RequiredArgsConstructor
+public class ReceiptController {
+
+ private final ReceiptService receiptService;
+
+
+ /** ì˜ìˆ˜ì¦ ì €ìž¥ API **/
+ @PostMapping
+ public ResponseEntity saveReceipt( @RequestPart("request") SaveReceiptRequest request,
+ @RequestPart(value = "receiptImg", required = false) MultipartFile receiptImg) {
+ Long receiptId = receiptService.saveReceipt(request, receiptImg);
+ return ResponseEntity.status(HttpStatus.CREATED).body(receiptId);
+ }
+
+
+ /** ì˜ìˆ˜ì¦ ì‚ì œ API **/
+ @DeleteMapping("/{receiptId}")
+ public ResponseEntity deleteReceipt(@PathVariable Long receiptId) {
+ receiptService.deleteReceipt(receiptId);
+ return ResponseEntity.ok().build();
+ }
+
+
+ /** ì˜ìˆ˜ì¦ ìˆ˜ì • API **/
+ @PutMapping("/{receiptId}")
+ public ResponseEntity updateReceipt(@PathVariable Long receiptId,
+ @RequestPart("request") SaveReceiptRequest request,
+ @RequestPart(value = "receiptImg", required = false) MultipartFile receiptImg) {
+ Long newReceiptId = receiptService.updateReceipt(receiptId, request, receiptImg);
+ return ResponseEntity.status(HttpStatus.OK).body(newReceiptId);
+ }
+
+
+ /** 여행 별 ì˜ìˆ˜ì¦ 리스트 ì „ì²´ 조회 API **/
+ @GetMapping("/{scheduleId}/list")
+ public ResponseEntity getReceiptList(@PathVariable Long scheduleId) {
+ ScheduleReceiptResponse response = receiptService.getReceiptList(scheduleId);
+ return ResponseEntity.ok(response);
+ }
+
+
+ /** ì˜ìˆ˜ì¦ 별 ìƒì„¸ ë‚´ì— ì¡°íšŒ API **/
+ @GetMapping("/detail/{receiptId}/list")
+ public ResponseEntity getReceiptDetail(@PathVariable Long receiptId) {
+ ReceiptResponse receiptResponse = receiptService.getReceiptDetail(receiptId);
+ return ResponseEntity.ok(receiptResponse);
+ }
+
+
+ /** ì˜ìˆ˜ì¦ìš© ì¼ì • 리스트 ëª©ë¡ ì¡°íšŒ API **/
+ @GetMapping("/schedules/list")
+ public ResponseEntity> getScheduleListWithReceipt(@AuthenticationPrincipal CustomUserDetails userDetails) {
+ String memberUid = userDetails.getUsername();
+ List scheduleListWithReceipts = receiptService.getScheduleListWithReceipt(memberUid);
+ return ResponseEntity.ok(scheduleListWithReceipts);
+ }
+
+
+
+ /** ì˜ìˆ˜ì¦ 순서 변경 API **/
+ @PutMapping("/order/{scheduleId}")
+ public ResponseEntity changeOrderReceipt(@PathVariable Long scheduleId,
+ @RequestBody List changeRequests) {
+ receiptService.changeOrderReceipt(scheduleId, changeRequests);
+ return ResponseEntity.ok().build();
+ }
+
+
+
+ /** test - ì˜ìˆ˜ì¦ 사진 ì €ìž¥ API **/
+ @PostMapping("/{receiptId}/image")
+ public ResponseEntity saveReceiptImg(@PathVariable Long receiptId,
+ @RequestParam("receiptImg") MultipartFile receiptImg) {
+ receiptService.saveReceiptImg(receiptId, receiptImg);
+ return ResponseEntity.ok().build();
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/ChangeReceiptOrderRequest.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/ChangeReceiptOrderRequest.java
new file mode 100644
index 00000000..5fbc1424
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/ChangeReceiptOrderRequest.java
@@ -0,0 +1,18 @@
+package com.isp.backend.domain.receipt.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ChangeReceiptOrderRequest {
+
+ private Long receiptId ;
+ private String purchaseDate ;
+ private int orderNum ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/ReceiptDetailRequest.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/ReceiptDetailRequest.java
new file mode 100644
index 00000000..6b7983ba
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/ReceiptDetailRequest.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.receipt.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ReceiptDetailRequest {
+
+ private String item;
+
+ private int count;
+
+ private double itemPrice;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/SaveReceiptRequest.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/SaveReceiptRequest.java
new file mode 100644
index 00000000..e398b42b
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/request/SaveReceiptRequest.java
@@ -0,0 +1,29 @@
+package com.isp.backend.domain.receipt.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class SaveReceiptRequest {
+
+ private Long scheduleId ;
+
+ private String storeName;
+
+ private String storeType ;
+
+ private double totalPrice ;
+
+ private String purchaseDate ;
+
+ private List receiptDetails;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptDetailResponse.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptDetailResponse.java
new file mode 100644
index 00000000..9b1e3118
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptDetailResponse.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.receipt.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ReceiptDetailResponse {
+
+ private String item;
+
+ private int count;
+
+ private double itemPrice;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptListResponse.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptListResponse.java
new file mode 100644
index 00000000..dc838dd4
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptListResponse.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.receipt.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ReceiptListResponse {
+
+ private Long receiptId;
+
+ private String storeName;
+
+ private String storeType ;
+
+ private double price ;
+
+ private int orderNum ;
+
+ private String purchaseDate ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptResponse.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptResponse.java
new file mode 100644
index 00000000..f11c3662
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ReceiptResponse.java
@@ -0,0 +1,27 @@
+package com.isp.backend.domain.receipt.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ReceiptResponse {
+
+ private Long receiptId ;
+
+ private String purchaseDate ;
+
+ private int orderNum ;
+
+ private String receiptImg ;
+
+ private double totalPrice ;
+
+ private List receiptDetailList;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ScheduleListWithReceiptResponse.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ScheduleListWithReceiptResponse.java
new file mode 100644
index 00000000..a64dc3db
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ScheduleListWithReceiptResponse.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.receipt.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ScheduleListWithReceiptResponse {
+
+ private String scheduleName;
+
+ private String startDate;
+
+ private String endDate;
+
+ private String currencyName;
+
+ private double totalReceiptsPrice ;
+
+ private int receiptCount ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ScheduleReceiptResponse.java b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ScheduleReceiptResponse.java
new file mode 100644
index 00000000..4cbc6041
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/dto/response/ScheduleReceiptResponse.java
@@ -0,0 +1,28 @@
+package com.isp.backend.domain.receipt.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class ScheduleReceiptResponse {
+
+ private String scheduleName;
+
+ private String startDate;
+
+ private String endDate;
+
+ private String currencyName; // schedule table -> country tableì˜ currency_name 컬럼
+
+ private double totalReceiptsPrice ;
+
+ private List receiptList;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/entity/Receipt.java b/backend/src/main/java/com/isp/backend/domain/receipt/entity/Receipt.java
new file mode 100644
index 00000000..9a30367a
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/entity/Receipt.java
@@ -0,0 +1,41 @@
+package com.isp.backend.domain.receipt.entity;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.global.common.BaseEntity;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "receipt")
+public class Receipt extends BaseEntity {
+
+ @Id
+ @Column(name = "id", unique = true, nullable = false)
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ private Schedule schedule;
+
+ private String storeName;
+
+ @Enumerated(EnumType.STRING)
+ private StoreType storeType;
+
+ private double totalPrice;
+
+ private String purchaseDate;
+
+ private String receiptImg;
+
+ private int orderNum ;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/entity/ReceiptDetail.java b/backend/src/main/java/com/isp/backend/domain/receipt/entity/ReceiptDetail.java
new file mode 100644
index 00000000..c08b890a
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/entity/ReceiptDetail.java
@@ -0,0 +1,30 @@
+package com.isp.backend.domain.receipt.entity;
+
+import jakarta.persistence.*;
+import lombok.*;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "receipt_detail")
+public class ReceiptDetail {
+
+ @Id
+ @Column(name = "id", unique = true, nullable = false)
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "receipt_id", nullable = false)
+ private Receipt receipt;
+
+ private String item;
+
+ private int count;
+
+ private double itemPrice;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/entity/StoreType.java b/backend/src/main/java/com/isp/backend/domain/receipt/entity/StoreType.java
new file mode 100644
index 00000000..28b3e2d0
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/entity/StoreType.java
@@ -0,0 +1,18 @@
+package com.isp.backend.domain.receipt.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum StoreType {
+
+ AIRPLANE,
+ HOTEL,
+ PLACE,
+ TRANSFER
+
+};
+
+
+
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/mapper/ReceiptMapper.java b/backend/src/main/java/com/isp/backend/domain/receipt/mapper/ReceiptMapper.java
new file mode 100644
index 00000000..0aacc123
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/mapper/ReceiptMapper.java
@@ -0,0 +1,107 @@
+package com.isp.backend.domain.receipt.mapper;
+
+import com.isp.backend.domain.receipt.dto.request.ReceiptDetailRequest;
+import com.isp.backend.domain.receipt.dto.request.SaveReceiptRequest;
+import com.isp.backend.domain.receipt.dto.response.ReceiptDetailResponse;
+import com.isp.backend.domain.receipt.dto.response.ReceiptListResponse;
+import com.isp.backend.domain.receipt.dto.response.ReceiptResponse;
+import com.isp.backend.domain.receipt.dto.response.ScheduleListWithReceiptResponse;
+import com.isp.backend.domain.receipt.entity.Receipt;
+import com.isp.backend.domain.receipt.entity.ReceiptDetail;
+import com.isp.backend.domain.receipt.entity.StoreType;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor
+public class ReceiptMapper {
+
+ // ì˜ìˆ˜ì¦ ì €ìž¥
+ public Receipt toEntity(SaveReceiptRequest request, Schedule schedule, int orderNum) {
+ StoreType storeType = getStoreType(request.getStoreType());
+
+ return Receipt.builder()
+ .schedule(schedule)
+ .storeName(request.getStoreName())
+ .storeType(storeType)
+ .totalPrice(request.getTotalPrice())
+ .purchaseDate(request.getPurchaseDate())
+ .orderNum(orderNum)
+ .build();
+ }
+
+ public ReceiptDetail toEntity(ReceiptDetailRequest request, Receipt receipt) {
+ return ReceiptDetail.builder()
+ .receipt(receipt)
+ .item(request.getItem())
+ .count(request.getCount())
+ .itemPrice(request.getItemPrice())
+ .build();
+ }
+
+
+ // 올바른 ì˜ìˆ˜ì¦ íƒ€ìž…ì„ ê°–ëŠ”ì§€ 확ì¸
+ public StoreType getStoreType(String storeType) {
+ try {
+ return StoreType.valueOf(storeType.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid store type: " + storeType);
+ }
+ }
+
+
+ // ì˜ìˆ˜ì¦ ëª©ë¡ ì¡°íšŒ
+ public ReceiptListResponse toReceiptListResponse(Receipt receipt) {
+ return new ReceiptListResponse(
+ receipt.getId(),
+ receipt.getStoreName(),
+ receipt.getStoreType().name(),
+ receipt.getTotalPrice(),
+ receipt.getOrderNum(),
+ receipt.getPurchaseDate()
+ );
+ }
+
+
+ // ì˜ìˆ˜ì¦ ìƒì„¸ 조회
+ public ReceiptResponse toReceiptResponse(Receipt receipt, List receiptDetailResponses) {
+ return new ReceiptResponse(
+ receipt.getId(),
+ receipt.getPurchaseDate(),
+ receipt.getOrderNum(),
+ receipt.getReceiptImg(),
+ receipt.getTotalPrice(),
+ receiptDetailResponses
+ );
+ }
+
+ public ReceiptDetailResponse toReceiptDetailResponse(ReceiptDetail receiptDetail) {
+ return new ReceiptDetailResponse(
+ receiptDetail.getItem(),
+ receiptDetail.getCount(),
+ receiptDetail.getItemPrice()
+ );
+ }
+
+
+ // ì˜ìˆ˜ì¦ ìš© ì¼ì • 리스트 ëª©ë¡ ì¡°íšŒ
+ public ScheduleListWithReceiptResponse toScheduleListWithReceiptResponse(Schedule schedule, double totalReceiptsPrice, int receiptCount) {
+ String currencyName = schedule.getCountry().getCurrencyName();
+
+ return new ScheduleListWithReceiptResponse(
+ schedule.getScheduleName(),
+ schedule.getStartDate(),
+ schedule.getEndDate(),
+ currencyName,
+ totalReceiptsPrice,
+ receiptCount
+ );
+ }
+
+
+
+}
+
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/repository/ReceiptDetailRepository.java b/backend/src/main/java/com/isp/backend/domain/receipt/repository/ReceiptDetailRepository.java
new file mode 100644
index 00000000..8de4135a
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/repository/ReceiptDetailRepository.java
@@ -0,0 +1,14 @@
+package com.isp.backend.domain.receipt.repository;
+
+import com.isp.backend.domain.receipt.entity.Receipt;
+import com.isp.backend.domain.receipt.entity.ReceiptDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface ReceiptDetailRepository extends JpaRepository {
+ void deleteAllByReceipt(Receipt receipt);
+
+ List findByReceiptId(Long receiptId);
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/repository/ReceiptRepository.java b/backend/src/main/java/com/isp/backend/domain/receipt/repository/ReceiptRepository.java
new file mode 100644
index 00000000..da3e18a5
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/repository/ReceiptRepository.java
@@ -0,0 +1,29 @@
+package com.isp.backend.domain.receipt.repository;
+
+import com.isp.backend.domain.receipt.entity.Receipt;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface ReceiptRepository extends JpaRepository {
+
+ @Query("SELECT COALESCE(MAX(r.orderNum), 0) FROM Receipt r WHERE r.schedule.id = :scheduleId AND r.purchaseDate = :purchaseDate")
+ int findMaxOrderNumByScheduleIdAndPurchaseDate(@Param("scheduleId") Long scheduleId, @Param("purchaseDate") String purchaseDate);
+
+ // ìŠ¤ì¼€ì¤„ì— í•´ë‹¹í•˜ëŠ” ì˜ìˆ˜ì¦ì„ purchaseDate 오름차순, orderNum 오름차순으로 ì •ë ¬í•˜ì—¬ 반환
+ List findByScheduleIdOrderByPurchaseDateAscOrderNumAsc(Long scheduleId);
+
+ List findByScheduleId(Long scheduleId);
+
+ // 스케줄 IDì— í•´ë‹¹í•˜ëŠ” ì˜ìˆ˜ì¦ì˜ totalPrice 합계를 구하는 쿼리
+ @Query("SELECT SUM(r.totalPrice) FROM Receipt r WHERE r.schedule.id = :scheduleId")
+ Double sumTotalPriceByScheduleId(@Param("scheduleId") Long scheduleId);
+
+ // 스케줄 IDì— í•´ë‹¹í•˜ëŠ” ì˜ìˆ˜ì¦ì˜ 개수를 구하는 쿼리
+ @Query("SELECT COUNT(r) FROM Receipt r WHERE r.schedule.id = :scheduleId")
+ int countByScheduleId(@Param("scheduleId") Long scheduleId);
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/service/ReceiptService.java b/backend/src/main/java/com/isp/backend/domain/receipt/service/ReceiptService.java
new file mode 100644
index 00000000..f634b7c7
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/receipt/service/ReceiptService.java
@@ -0,0 +1,284 @@
+package com.isp.backend.domain.receipt.service;
+
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.member.repository.MemberRepository;
+import com.isp.backend.domain.receipt.dto.request.ChangeReceiptOrderRequest;
+import com.isp.backend.domain.receipt.dto.request.ReceiptDetailRequest;
+import com.isp.backend.domain.receipt.dto.request.SaveReceiptRequest;
+import com.isp.backend.domain.receipt.dto.response.*;
+import com.isp.backend.domain.receipt.entity.Receipt;
+import com.isp.backend.domain.receipt.entity.ReceiptDetail;
+import com.isp.backend.domain.receipt.mapper.ReceiptMapper;
+import com.isp.backend.domain.receipt.repository.ReceiptDetailRepository;
+import com.isp.backend.domain.receipt.repository.ReceiptRepository;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.schedule.repository.ScheduleRepository;
+import com.isp.backend.global.exception.Image.ImageAlreadyExistingException;
+import com.isp.backend.global.exception.common.MemberNotFoundException;
+import com.isp.backend.global.exception.receipt.ReceiptNotFoundException;
+import com.isp.backend.global.exception.schedule.ScheduleNotFoundException;
+import com.isp.backend.global.s3.constant.S3BucketDirectory;
+import com.isp.backend.global.s3.service.S3ImageService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+@Service
+@RequiredArgsConstructor
+public class ReceiptService {
+ private final ReceiptRepository receiptRepository;
+ private final ReceiptDetailRepository receiptDetailRepository;
+ private final MemberRepository memberRepository;
+ private final ScheduleRepository scheduleRepository;
+ private final ReceiptMapper receiptMapper;
+ private final S3ImageService s3ImageService;
+
+
+ /** ì˜ìˆ˜ì¦ ì €ìž¥ API **/
+ @Transactional
+ public Long saveReceipt(SaveReceiptRequest request,MultipartFile receiptImg) {
+ // ì¼ì • ì •ë³´ 확ì¸
+ Schedule findSchedule = validateSchedule(request.getScheduleId());
+
+ // ë™ì¼í•œ ë‚ ì§œì˜ ê°€ìž¥ í° orderNum 조회
+ int maxOrderNum = receiptRepository.findMaxOrderNumByScheduleIdAndPurchaseDate(
+ request.getScheduleId(), request.getPurchaseDate()
+ );
+
+ // orderNum ì„¤ì • (해당 ë‚ ì§œì— ì˜ìˆ˜ì¦ì´ 없으면 1ë¡œ ì„¤ì •, 있으면 maxOrderNum + 1)
+ int orderNum = maxOrderNum + 1;
+
+ // ë°ì´í„° 변환 ë° ì €ìž¥
+ Receipt receipt = receiptMapper.toEntity(request, findSchedule, orderNum);
+
+ // ì˜ìˆ˜ì¦ 사진 ì €ìž¥
+ if (receiptImg != null && !receiptImg.isEmpty()) {
+ String receiptImgUrl = s3ImageService.create(receiptImg, "RECEIPT" );
+ receipt.setReceiptImg(receiptImgUrl);
+ }
+
+ receiptRepository.save(receipt);
+
+ for (ReceiptDetailRequest detailRequest : request.getReceiptDetails()) {
+ ReceiptDetail detail = receiptMapper.toEntity(detailRequest, receipt);
+ receiptDetailRepository.save(detail);
+ }
+
+ return receipt.getId();
+ }
+
+
+
+ /** ì˜ìˆ˜ì¦ ì‚ì œ 메소드 **/
+ @Transactional
+ public void deleteReceipt(Long receiptId) {
+ // ìœ íš¨í•œ ì˜ìˆ˜ì¦ 확ì¸
+ Receipt receipt = validateReceipt(receiptId);
+
+ // ì˜ìˆ˜ì¦ì— ì—°ê²°ëœ ì„¸ë¶€ ë‚´ì— ì‚ì œ
+ receiptDetailRepository.deleteAllByReceipt(receipt);
+
+ // ì˜ìˆ˜ì¦ ì‚ì œ
+ receiptRepository.delete(receipt);
+ }
+
+
+
+ /** ì˜ìˆ˜ì¦ ìˆ˜ì • 메소드 **/
+ @Transactional
+ public Long updateReceipt(Long receiptId, SaveReceiptRequest request, MultipartFile receiptImg) {
+ // ìœ íš¨í•œ ì˜ìˆ˜ì¦ 확ì¸
+ Receipt receipt = validateReceipt(receiptId);
+
+ // ì˜ìˆ˜ì¦ ì •ë³´ ì—…ë°ì´íŠ¸
+ receipt.setStoreName(request.getStoreName());
+ receipt.setStoreType(receiptMapper.getStoreType(request.getStoreType()));
+ receipt.setTotalPrice(request.getTotalPrice());
+ receipt.setPurchaseDate(request.getPurchaseDate());
+
+ // ì˜ìˆ˜ì¦ ì´ë¯¸ì§€ê°€ ìžˆì„ ê²½ìš° ì—…ë°ì´íŠ¸
+ if (receiptImg != null && !receiptImg.isEmpty()) {
+ String receiptImgUrl = s3ImageService.create(receiptImg, "RECEIPT");
+ receipt.setReceiptImg(receiptImgUrl);
+ }
+
+ // 기존 ì˜ìˆ˜ì¦ 세부 ë‚´ì— ì‚ì œ
+ receiptDetailRepository.deleteAllByReceipt(receipt);
+
+ // 새 세부 ë‚´ì— ì¶”ê°€
+ for (ReceiptDetailRequest detailRequest : request.getReceiptDetails()) {
+ ReceiptDetail detail = receiptMapper.toEntity(detailRequest, receipt);
+ receiptDetailRepository.save(detail);
+ }
+
+ // ìˆ˜ì •ëœ ì˜ìˆ˜ì¦ ì •ë³´ ì €ìž¥
+ receiptRepository.save(receipt);
+ return receipt.getId();
+ }
+
+
+
+ /** 여행 별 ì˜ìˆ˜ì¦ 리스트 ì „ì²´ 조회 메소드 **/
+ @Transactional(readOnly = true)
+ public ScheduleReceiptResponse getReceiptList(Long scheduleId) {
+ Schedule schedule = validateSchedule(scheduleId);
+ List receipts = receiptRepository.findByScheduleIdOrderByPurchaseDateAscOrderNumAsc(schedule.getId());
+
+ // ì˜ìˆ˜ì¦ì˜ 합계 구하기
+ double totalReceiptsPrice = receipts.stream()
+ .mapToDouble(Receipt::getTotalPrice)
+ .sum();
+ // ì˜ìˆ˜ì¦ë“¤ 매핑
+ List receiptList = receipts.stream()
+ .map(receiptMapper::toReceiptListResponse)
+ .collect(Collectors.toList());
+
+ return new ScheduleReceiptResponse(
+ schedule.getScheduleName(),
+ schedule.getStartDate(),
+ schedule.getEndDate(),
+ schedule.getCountry().getCurrencyName(),
+ totalReceiptsPrice,
+ receiptList
+ );
+ }
+
+
+
+ /** ì˜ìˆ˜ì¦ 별 ìƒì„¸ ë‚´ì— ì¡°íšŒ 메소드 **/
+ @Transactional(readOnly = true)
+ public ReceiptResponse getReceiptDetail(Long receiptId) {
+ Receipt receipt = validateReceipt(receiptId);
+
+ // ì˜ìˆ˜ì¦ì— ì—°ê´€ëœ ìƒì„¸ ë‚´ì— ë¦¬ìŠ¤íŠ¸ë¥¼ 조회
+ List receiptDetails = receiptDetailRepository.findByReceiptId(receiptId);
+
+ // ReceiptDetailì„ ReceiptDetailResponseë¡œ 변환
+ List receiptDetailResponses = receiptDetails.stream()
+ .map(receiptMapper::toReceiptDetailResponse)
+ .collect(Collectors.toList());
+
+ // ReceiptResponse DTO ìƒì„± ë° ë°˜í™˜
+ return receiptMapper.toReceiptResponse(receipt, receiptDetailResponses);
+
+ }
+
+
+
+
+ /** ì˜ìˆ˜ì¦ìš© ì¼ì • 리스트 ëª©ë¡ ì¡°íšŒ API **/
+ @Transactional(readOnly = true)
+ public List getScheduleListWithReceipt(String uid) {
+ // ìœ ì € ì •ë³´ 확ì¸
+ Member findMember = validateUserCheck(uid);
+
+ // 해당 ìœ ì €ì˜ ëª¨ë“ ì¼ì • 불러오기
+ List scheduleList = scheduleRepository.findSchedulesByMember(findMember);
+
+ // ì¼ì • 리스트를 DTOë¡œ 변환
+ return scheduleList.stream()
+ .map(schedule -> {
+ // sumTotalPriceByScheduleIdê°€ nullì„ ë°˜í™˜í•˜ë©´ 0.0ì„ ê¸°ë³¸ê°’ìœ¼ë¡œ ì„¤ì •
+ double totalReceiptsPrice = Optional.ofNullable(receiptRepository.sumTotalPriceByScheduleId(schedule.getId()))
+ .orElse(0.0);
+ int receiptCount = receiptRepository.countByScheduleId(schedule.getId());
+ return receiptMapper.toScheduleListWithReceiptResponse(schedule, totalReceiptsPrice, receiptCount);
+ })
+ .collect(Collectors.toList());
+
+ }
+
+
+
+
+ // ì˜ìˆ˜ì¦ 순서 변경 메서드 ìˆ˜ì • ì˜ˆì •
+ /** 예외처리 ë° ì •í™•í•œ ë¡œì§ ë¶„ì„ í•„ìš” **/
+ @Transactional
+ public void changeOrderReceipt(Long scheduleId, List changeRequests) {
+ // 해당 ìŠ¤ì¼€ì¤„ì— ì¡´ìž¬í•˜ëŠ” ì˜ìˆ˜ì¦ ì „ì²´ ëª©ë¡ ì¡°íšŒ
+ List existingReceipts = receiptRepository.findByScheduleId(scheduleId);
+
+ // í´ë¼ì´ì–¸íŠ¸ê°€ ì œê³µí•œ ì •ë³´ë¡œ ì´ë£¨ì–´ì§„ Map ìƒì„± (key: purchaseDate, receiptId, value: orderNum)
+ Map> providedReceiptsMap = changeRequests.stream()
+ .collect(Collectors.groupingBy(
+ ChangeReceiptOrderRequest::getPurchaseDate,
+ Collectors.toMap(ChangeReceiptOrderRequest::getReceiptId, ChangeReceiptOrderRequest::getOrderNum)
+ ));
+
+ // ì œê³µëœ ëª¨ë“ receiptId와 ë‚ ì§œê°€ 해당 ìŠ¤ì¼€ì¤„ì˜ ì˜ìˆ˜ì¦ì— ì¼ì¹˜í•˜ëŠ”지 확ì¸
+ for (Receipt receipt : existingReceipts) {
+ Map dateSpecificReceipts = providedReceiptsMap.get(receipt.getPurchaseDate());
+ if (dateSpecificReceipts == null || !dateSpecificReceipts.containsKey(receipt.getId())) {
+ throw new IllegalArgumentException("ëª¨ë“ ì˜ìˆ˜ì¦ ID와 ë‚ ì§œë¥¼ ì œê³µí•´ì•¼ 합니다.");
+ }
+ }
+
+ // ë‚ ì§œë³„ë¡œ orderNum ê°’ì´ ì¤‘ë³µë˜ì§€ 않는지 확ì¸
+ for (Map receiptMap : providedReceiptsMap.values()) {
+ Set orderNums = new HashSet<>(receiptMap.values());
+ if (orderNums.size() != receiptMap.size()) {
+ throw new IllegalArgumentException("ë‚ ì§œë³„ orderNum ê°’ì´ ì¤‘ë³µë©ë‹ˆë‹¤.");
+ }
+ }
+
+ // orderNum ì—…ë°ì´íŠ¸
+ for (Receipt receipt : existingReceipts) {
+ int newOrderNum = providedReceiptsMap.get(receipt.getPurchaseDate()).get(receipt.getId());
+ receipt.setOrderNum(newOrderNum);
+ receiptRepository.save(receipt);
+ }
+ }
+
+
+
+ /** ìœ íš¨í•œ ìœ ì € ì •ë³´ í™•ì¸ **/
+ private Member validateUserCheck(String uid) {
+ return memberRepository.findByUid(uid)
+ .orElseThrow(MemberNotFoundException::new);
+ }
+
+
+
+ /** ìœ íš¨í•œ ì¼ì • í™•ì¸ ë©”ì†Œë“œ **/
+ private Schedule validateSchedule(Long scheduleId) {
+ Schedule findSchedule = scheduleRepository.findByIdAndActivatedIsTrue(scheduleId)
+ .orElseThrow(ScheduleNotFoundException::new);
+ return findSchedule;
+ }
+
+
+ /** ìœ íš¨í•œ ì˜ìˆ˜ì¦ í™•ì¸ ë©”ì„œë“œ**/
+ private Receipt validateReceipt(Long receiptId){
+ Receipt findReceipt = receiptRepository.findById(receiptId)
+ .orElseThrow(ReceiptNotFoundException::new);
+ return findReceipt;
+ }
+
+
+ /** test - ì˜ìˆ˜ì¦ ì´ë¯¸ì§€ ì €ìž¥ API **/
+ @Transactional
+ public void saveReceiptImg(Long receiptId, MultipartFile receiptImg) {
+ // ì˜ìˆ˜ì¦ ì •ë³´ 확ì¸
+ Receipt receipt = validateReceipt(receiptId);
+
+ // ì˜ìˆ˜ì¦ 사진 urlì´ ì´ë¯¸ dbì— ìžˆëŠ”ì§€ 여부 확ì¸
+ if (receipt.getReceiptImg() != null && !receipt.getReceiptImg().isEmpty()) {
+ throw new ImageAlreadyExistingException();
+ }
+
+ // ì˜ìˆ˜ì¦ 사진 ì €ìž¥
+ if (receiptImg != null && !receiptImg.isEmpty()) {
+ String receiptImgUrl = s3ImageService.create(receiptImg, "RECEIPT" );
+ receipt.setReceiptImg(receiptImgUrl);
+ receiptRepository.save(receipt);
+ }
+
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java b/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java
new file mode 100644
index 00000000..b903363d
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java
@@ -0,0 +1,91 @@
+package com.isp.backend.domain.schedule.controller;
+
+import com.isp.backend.domain.schedule.dto.response.FastestScheduleResponse;
+import com.isp.backend.domain.schedule.dto.response.LatestCreateResponse;
+import com.isp.backend.domain.schedule.dto.response.ScheduleListResponse;
+import com.isp.backend.domain.schedule.dto.request.ScheduleSaveRequest;
+import com.isp.backend.domain.schedule.service.ScheduleService;
+import com.isp.backend.global.security.CustomUserDetails;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/schedules")
+@RequiredArgsConstructor
+public class ScheduleController {
+
+ private final ScheduleService scheduleService;
+
+ /** 여행 ì¼ì • ì €ìž¥ API **/
+ @PostMapping()
+ public ResponseEntity saveSchedule(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @RequestBody ScheduleSaveRequest requestDTO) {
+ scheduleService.saveSchedule(customUserDetails.getUsername(), requestDTO);
+ return ResponseEntity.ok().build();
+ }
+
+
+ /** 여행 ì¼ì • ëª©ë¡ ì¡°íšŒ API **/
+ @GetMapping()
+ public ResponseEntity> getScheduleList(@AuthenticationPrincipal CustomUserDetails userDetails) {
+ String memberUid = userDetails.getUsername();
+ List scheduleList = scheduleService.getScheduleList(memberUid);
+ return ResponseEntity.ok(scheduleList);
+ }
+
+
+ /** 여행 ì¼ì • ìƒì„¸ 조회 API **/
+ @GetMapping("/details/{scheduleId}")
+ public ResponseEntity getScheduleDetail(@AuthenticationPrincipal CustomUserDetails userDetails,
+ @PathVariable Long scheduleId) {
+ String memberUid = userDetails.getUsername();
+ ScheduleSaveRequest scheduleDetail = scheduleService.getScheduleDetail(memberUid, scheduleId);
+ return ResponseEntity.ok(scheduleDetail);
+ }
+
+
+ /** 여행 ì¼ì • ìˆ˜ì • API **/
+ @PutMapping("/{scheduleId}")
+ public ResponseEntity updateSchedule(@AuthenticationPrincipal CustomUserDetails userDetails,
+ @PathVariable Long scheduleId,
+ @RequestBody ScheduleSaveRequest requestDTO) {
+ ScheduleSaveRequest updatedSchedule = scheduleService.updateSchedule(userDetails.getUsername(), scheduleId, requestDTO);
+ return ResponseEntity.ok(updatedSchedule);
+ }
+
+
+ /** 여행 ì¼ì • ì‚ì œ API **/
+ @DeleteMapping("/{scheduleId}")
+ public ResponseEntity deleteSchedule(@AuthenticationPrincipal CustomUserDetails userDetails,
+ @PathVariable Long scheduleId) {
+ String memberUid = userDetails.getUsername();
+ scheduleService.deleteSchedule(memberUid, scheduleId);
+ return ResponseEntity.ok().build();
+ }
+
+
+ /** ë‚˜ì˜ ê°€ê¹Œìš´ ì¼ì • 조회 API **/
+ @GetMapping("/dday")
+ public ResponseEntity getFastestSchedule(@AuthenticationPrincipal CustomUserDetails userDetails) {
+ String memberUid = userDetails.getUsername();
+ FastestScheduleResponse fastestScheduleResponse = scheduleService.getFastestSchedule(memberUid);
+ return ResponseEntity.ok(fastestScheduleResponse);
+ }
+
+
+ /** ë‚´ê°€ 최근 ìƒì„±í•œ 5ê°œ ì¼ì • 조회 API **/
+ @GetMapping("/latest")
+ public ResponseEntity> getLatestCreatedSchedules(
+ @AuthenticationPrincipal CustomUserDetails userDetails,
+ @RequestParam(value = "limit", defaultValue = "6") int limit) { // ì¶œë ¥í• ì„¸ë¶€ ì¼ì • 개수 ì¡°ì ˆ
+ String memberUid = userDetails.getUsername();
+ List responses = scheduleService.getLatestCreatedSchedules(memberUid, limit);
+ return ResponseEntity.ok(responses);
+ }
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/DailySchedule.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/DailySchedule.java
new file mode 100644
index 00000000..d34f4565
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/DailySchedule.java
@@ -0,0 +1,20 @@
+package com.isp.backend.domain.schedule.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class DailySchedule {
+
+ private String date; // ì¼ì • ë‚ ì§œ
+
+ private List schedules; // 해당 ë‚ ì§œì˜ ì¼ì • 목ë¡
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleDetailRequest.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleDetailRequest.java
new file mode 100644
index 00000000..c5e82f7d
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleDetailRequest.java
@@ -0,0 +1,28 @@
+package com.isp.backend.domain.schedule.dto.request;
+
+
+import com.isp.backend.domain.scheduleDetail.entity.ScheduleType;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class ScheduleDetailRequest {
+
+ private String todo; // í• ì¼
+
+ private String place; // 장소
+
+ private ScheduleType type; // ì¼ì • ìœ í˜•
+
+ private double budget; // 예산
+
+ private double latitude; // 위ë„
+
+ private double longitude; // ê²½ë„
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleRequest.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleRequest.java
new file mode 100644
index 00000000..6834df4e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleRequest.java
@@ -0,0 +1,27 @@
+package com.isp.backend.domain.schedule.dto.request;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class ScheduleRequest {
+ private Country country;
+ private String purpose;
+ private String startDate;
+ private String endDate;
+
+ public Schedule toEntity() {
+ return Schedule.builder()
+ .country(country)
+ .startDate(startDate)
+ .endDate(endDate)
+ .build();
+ }
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleSaveRequest.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleSaveRequest.java
new file mode 100644
index 00000000..ca76eac6
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/request/ScheduleSaveRequest.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.schedule.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class ScheduleSaveRequest {
+
+ private String scheduleName; // 여행 ì¼ì • ì´ë¦„
+
+ private String country; // ì—¬í–‰í• êµê°€
+
+ private String startDate; // 여행 시작 ë‚ ì§œ
+
+ private String endDate; // 여행 종료 ë‚ ì§œ
+
+ private List dailySchedules; // 하루 ì¼ì • 목ë¡
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/FastestScheduleResponse.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/FastestScheduleResponse.java
new file mode 100644
index 00000000..6afbfe8f
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/FastestScheduleResponse.java
@@ -0,0 +1,24 @@
+package com.isp.backend.domain.schedule.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class FastestScheduleResponse {
+
+ private Long id;
+
+ private String scheduleName; // 여행지 ì´ë¦„
+
+ private String dday;
+
+ private String country ;
+
+ private String imageUrl;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/LatestCreateResponse.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/LatestCreateResponse.java
new file mode 100644
index 00000000..d56c9509
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/LatestCreateResponse.java
@@ -0,0 +1,26 @@
+package com.isp.backend.domain.schedule.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class LatestCreateResponse {
+
+ private Long id;
+
+ private String scheduleName;
+
+ private String city; // 여행지 장소
+
+ private String imageUrl; // ì´ë¯¸ì§€ url
+
+ private List plan ; // 여행 ì¼ì • 리스트
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/ScheduleListResponse.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/ScheduleListResponse.java
new file mode 100644
index 00000000..01164a4f
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/ScheduleListResponse.java
@@ -0,0 +1,32 @@
+package com.isp.backend.domain.schedule.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class ScheduleListResponse {
+
+ private Long id;
+
+ private String scheduleName;
+
+ private String startDate;
+
+ private String endDate;
+
+ private double totalPrice;
+
+ private String imageUrl;
+
+ private String country;
+
+ private double latitude ;
+
+ private double longitude ;
+
+ private String currencyName;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/ScheduleResponse.java b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/ScheduleResponse.java
new file mode 100644
index 00000000..b3ce6237
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/dto/response/ScheduleResponse.java
@@ -0,0 +1,13 @@
+package com.isp.backend.domain.schedule.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class ScheduleResponse {
+ private String name;
+ private String email;
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java b/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java
new file mode 100644
index 00000000..2bd92bc8
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java
@@ -0,0 +1,53 @@
+package com.isp.backend.domain.schedule.entity;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.scheduleDetail.entity.ScheduleDetail;
+import com.isp.backend.global.common.BaseEntity;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "schedule")
+public class Schedule extends BaseEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(nullable = false)
+ private String scheduleName;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "country_id")
+ private Country country;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "member_id", nullable = false)
+ private Member member;
+
+ @Builder.Default
+ @OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL)
+ private List scheduleDetails = new ArrayList<>();
+
+ private String startDate;
+
+ private String endDate;
+
+ private double totalPrice;
+
+ @Builder.Default
+ @Column(nullable = false)
+ private boolean activated = true;
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/entity/SharedSchedule.java b/backend/src/main/java/com/isp/backend/domain/schedule/entity/SharedSchedule.java
new file mode 100644
index 00000000..2db55116
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/entity/SharedSchedule.java
@@ -0,0 +1,28 @@
+package com.isp.backend.domain.schedule.entity;
+
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.global.common.BaseEntity;
+import jakarta.persistence.*;
+import lombok.*;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "shared_schedule")
+public class SharedSchedule extends BaseEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "schedules_id", nullable = false) // 컬럼명 ì‚ì œX
+ private Schedule schedule;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "user_id", nullable = false)
+ private Member member;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/mapper/ScheduleMapper.java b/backend/src/main/java/com/isp/backend/domain/schedule/mapper/ScheduleMapper.java
new file mode 100644
index 00000000..d912fa36
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/mapper/ScheduleMapper.java
@@ -0,0 +1,204 @@
+package com.isp.backend.domain.schedule.mapper;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.schedule.dto.request.DailySchedule;
+import com.isp.backend.domain.schedule.dto.request.ScheduleDetailRequest;
+import com.isp.backend.domain.schedule.dto.response.FastestScheduleResponse;
+import com.isp.backend.domain.schedule.dto.response.LatestCreateResponse;
+import com.isp.backend.domain.schedule.dto.response.ScheduleListResponse;
+import com.isp.backend.domain.schedule.dto.request.ScheduleSaveRequest;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.scheduleDetail.entity.ScheduleDetail;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+@Component
+@RequiredArgsConstructor
+public class ScheduleMapper {
+
+ /**
+ * ì¼ì • ì €ìž¥
+ **/
+// 여행 ì¼ì • ìš”ì² DTO -> 엔티티로 변환
+ public Schedule toScheduleEntity(ScheduleSaveRequest scheduleSaveRequest, Member member, Country country) {
+ // 여행 ì¼ì • 엔티티 ìƒì„±
+ Schedule schedule = Schedule.builder()
+ .scheduleName(scheduleSaveRequest.getScheduleName())
+ .country(country)
+ .startDate(scheduleSaveRequest.getStartDate())
+ .endDate(scheduleSaveRequest.getEndDate())
+ .member(member)
+ .build();
+
+ // 여행 ì¼ì • 세부 í•ëª© 리스트 ìƒì„±
+ List scheduleDetails = scheduleSaveRequest.getDailySchedules().stream()
+ .flatMap(dailySchedule -> {
+ AtomicInteger num = new AtomicInteger(1); // ë‚ ì§œë³„ ì¼ì • 순서 ì¹´ìš´í„°
+ return dailySchedule.getSchedules().stream()
+ .map(scheduleDetailDTO -> toScheduleDetailEntity(scheduleDetailDTO, dailySchedule, schedule, num.getAndIncrement()));
+ })
+ .collect(Collectors.toList());
+
+ // ì¼ì • 세부를 ì¼ì • ì—”í‹°í‹°ì— ì„¤ì •
+ schedule.setScheduleDetails(scheduleDetails);
+
+ return schedule;
+ }
+
+ // ì¼ì • 세부 DTO를 엔티티로 변환
+ private ScheduleDetail toScheduleDetailEntity(ScheduleDetailRequest scheduleDetailDTO, DailySchedule dailySchedule, Schedule schedule, int num) {
+ ScheduleDetail scheduleDetail = ScheduleDetail.builder()
+ .todo(scheduleDetailDTO.getTodo())
+ .place(scheduleDetailDTO.getPlace())
+ .budget(scheduleDetailDTO.getBudget())
+ .latitude(scheduleDetailDTO.getLatitude())
+ .longitude(scheduleDetailDTO.getLongitude())
+ .date(dailySchedule.getDate())
+ .num(num) // ì¼ì • 순서 ì €ìž¥
+ .schedule(schedule)
+ .build();
+
+ // ScheduleDetailDTOì—ì„œ ì§ì ‘ ScheduleTypeì„ ê°€ì ¸ì™€ì„œ ì„¤ì •
+ scheduleDetail.setScheduleType(scheduleDetailDTO.getType());
+
+ return scheduleDetail;
+ }
+
+
+ /**
+ * ì¼ì • ì „ì²´ 조회
+ **/
+ public ScheduleListResponse toScheduleListResponseDTO(Schedule schedule) {
+ return new ScheduleListResponse(
+ schedule.getId(),
+ schedule.getScheduleName(),
+ schedule.getStartDate(),
+ schedule.getEndDate(),
+ schedule.getTotalPrice(),
+ schedule.getCountry().getImageUrl(),
+ schedule.getCountry().getCity(),
+ schedule.getCountry().getLatitude(),
+ schedule.getCountry().getLongitude(),
+ schedule.getCountry().getCurrencyName()
+ );
+ }
+
+
+ /**
+ * ì¼ì • ìƒì„¸ 조회
+ **/
+ // 엔티티 -> ScheduleSaveRequestDTO 로 변환
+ public ScheduleSaveRequest toScheduleResponseDTO(Schedule schedule) {
+ // ì¼ì • 세부를 ë‚ ì§œë³„ë¡œ ê·¸ë£¹í™”í•˜ê³ , ë‚ ì§œë¥¼ 기준으로 ì •ë ¬
+ List sortedDailySchedules = schedule.getScheduleDetails().stream()
+ .sorted(Comparator.comparing(ScheduleDetail::getDate))
+ .collect(Collectors.groupingBy(ScheduleDetail::getDate))
+ .entrySet().stream()
+ .map(entry -> new DailySchedule(
+ entry.getKey(),
+ entry.getValue().stream()
+ .sorted(Comparator.comparingInt(ScheduleDetail::getNum))
+ .map(this::toScheduleDetailDTO)
+ .collect(Collectors.toList())
+ ))
+ .sorted(Comparator.comparing(DailySchedule::getDate))
+ .collect(Collectors.toList());
+
+ return new ScheduleSaveRequest(
+ schedule.getScheduleName(),
+ schedule.getCountry().getCity(), // êµê°€ì—ì„œ ë„ì‹œ ê°€ì ¸ì˜¤ê¸°ë¡œ ìˆ˜ì •
+ schedule.getStartDate(),
+ schedule.getEndDate(),
+ sortedDailySchedules
+ );
+ }
+
+ // ScheduleDetail 엔티티를 ScheduleDetailDTO로 변환하는 메서드
+ private ScheduleDetailRequest toScheduleDetailDTO(ScheduleDetail scheduleDetail) {
+ ScheduleDetailRequest scheduleDetailDTO = new ScheduleDetailRequest(
+ scheduleDetail.getTodo(),
+ scheduleDetail.getPlace(),
+ scheduleDetail.getScheduleType(),
+ scheduleDetail.getBudget(),
+ scheduleDetail.getLatitude(),
+ scheduleDetail.getLongitude()
+ );
+ return scheduleDetailDTO;
+ }
+
+
+ /**
+ * ì¼ì • ìˆ˜ì •
+ **/
+ // ScheduleDetailDTO 목ë¡ì„ ScheduleDetail 엔티티 목ë¡ìœ¼ë¡œ 변환하는 메서드
+ public List updateSchedulesEntity(ScheduleSaveRequest scheduleSaveRequest, Schedule schedule) {
+ return scheduleSaveRequest.getDailySchedules().stream()
+ .flatMap(dailySchedule -> {
+ AtomicInteger num = new AtomicInteger(1); // ë‚ ì§œë³„ ì¼ì • 순서 ì¹´ìš´í„°
+ return dailySchedule.getSchedules().stream()
+ .map(scheduleDetail -> toScheduleDetailEntity(scheduleDetail, dailySchedule, schedule, num.getAndIncrement()));
+ })
+ .collect(Collectors.toList());
+ }
+
+
+ /**
+ * D-day
+ **/
+ public FastestScheduleResponse toFastestScheduleDTO(Schedule schedule) {
+ FastestScheduleResponse response = new FastestScheduleResponse();
+ response.setId(schedule.getId());
+ response.setScheduleName(schedule.getScheduleName());
+ response.setDday(calculateDday(schedule.getStartDate()));
+ response.setCountry(schedule.getCountry().getCity());
+ response.setImageUrl(schedule.getCountry().getImageUrl());
+
+ return response;
+ }
+
+
+ /**
+ * D-day 계산 메서드
+ **/
+ private String calculateDday(String startDateString) {
+ LocalDate today = LocalDate.now();
+ LocalDate startDate = LocalDate.parse(startDateString);
+ long dday = ChronoUnit.DAYS.between(today, startDate) + 1; // 오늘-시작ì¼ê¹Œì§€ì˜ ë‚ ì§œ 수 계산
+ return Long.toString(dday);
+ }
+
+
+
+ /**
+ * ìµœê·¼ì— ìƒì„±í•œ 여행 ì¼ì • top 5
+ **/
+ public LatestCreateResponse toLatestCreateResponse(Schedule schedule, int limit) {
+ List limitedPlan = schedule.getScheduleDetails().stream()
+ .sorted(Comparator.comparing(ScheduleDetail::getDate)
+ .thenComparing(ScheduleDetail::getNum))
+ .map(ScheduleDetail::getTodo)
+ .limit(limit) // 최대 개수로 ì œí•œ
+ .collect(Collectors.toList());
+
+ return new LatestCreateResponse(
+ schedule.getId(),
+ schedule.getScheduleName(),
+ schedule.getCountry().getCity(), // êµê°€ì—ì„œ ë„ì‹œ ê°€ì ¸ì˜¤ê¸°ë¡œ ìˆ˜ì •
+ schedule.getCountry().getImageUrl(), // ì´ë¯¸ì§€ URL 추가 (ì—”í‹°í‹°ì— ì´ í•„ë“œê°€ ìžˆë‹¤ê³ ê°€ì •)
+ limitedPlan
+ );
+ }
+
+
+
+}
+
+
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java b/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java
new file mode 100644
index 00000000..ddeaa42f
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java
@@ -0,0 +1,23 @@
+package com.isp.backend.domain.schedule.repository;
+
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Optional;
+public interface ScheduleRepository extends JpaRepository {
+ Optional findById(Long id);
+ Optional findByIdAndActivatedIsTrue(Long scheduleId);
+
+ @Query("SELECT s FROM Schedule s LEFT JOIN FETCH s.country WHERE s.member = :member AND s.activated = true ORDER BY s.updatedAt DESC")
+ List findSchedulesByMember(@Param("member") Member member);
+
+ @Query("SELECT s FROM Schedule s LEFT JOIN FETCH s.scheduleDetails WHERE s.member = :member ORDER BY s.id DESC")
+ List findTop5ByMemberOrderByIdDescWithDetails(@Param("member") Member member);
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/repository/SharedScheduleRepository.java b/backend/src/main/java/com/isp/backend/domain/schedule/repository/SharedScheduleRepository.java
new file mode 100644
index 00000000..88a07e10
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/repository/SharedScheduleRepository.java
@@ -0,0 +1,8 @@
+package com.isp.backend.domain.schedule.repository;
+
+import com.isp.backend.domain.schedule.entity.SharedSchedule;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface SharedScheduleRepository extends JpaRepository {
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java
new file mode 100644
index 00000000..c735b622
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java
@@ -0,0 +1,40 @@
+package com.isp.backend.domain.schedule.service;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.schedule.dto.response.FastestScheduleResponse;
+import com.isp.backend.domain.schedule.dto.response.LatestCreateResponse;
+import com.isp.backend.domain.schedule.dto.response.ScheduleListResponse;
+import com.isp.backend.domain.schedule.dto.request.ScheduleSaveRequest;
+import com.isp.backend.domain.schedule.entity.Schedule;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+public interface ScheduleService {
+
+ void saveSchedule(String uid, ScheduleSaveRequest scheduleSaveRequest);
+
+ List getScheduleList(String uid);
+
+ ScheduleSaveRequest getScheduleDetail(String uid, Long scheduleId);
+
+ void deleteSchedule(String uid, Long scheduleId);
+
+ FastestScheduleResponse getFastestSchedule(String uid);
+
+ ScheduleSaveRequest updateSchedule(String uid, Long scheduleId, ScheduleSaveRequest updateRequestDTO);
+
+ Optional findClosestSchedule(List schedules, LocalDate today);
+
+ void calculateTotalPrice(Schedule schedule);
+
+ Member validateUserCheck(String uid);
+
+ Schedule validateSchedule(Long scheduleId);
+
+ Country validateCountry(String countryName);
+
+ List getLatestCreatedSchedules(String uid, int limit);
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java
new file mode 100644
index 00000000..db840007
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java
@@ -0,0 +1,216 @@
+package com.isp.backend.domain.schedule.service;
+
+import com.isp.backend.domain.country.entity.Country;
+import com.isp.backend.domain.country.repository.CountryRepository;
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.member.repository.MemberRepository;
+import com.isp.backend.domain.schedule.dto.response.FastestScheduleResponse;
+import com.isp.backend.domain.schedule.dto.response.LatestCreateResponse;
+import com.isp.backend.domain.schedule.dto.response.ScheduleListResponse;
+import com.isp.backend.domain.schedule.dto.request.ScheduleSaveRequest;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.schedule.mapper.ScheduleMapper;
+import com.isp.backend.domain.schedule.repository.ScheduleRepository;
+import com.isp.backend.domain.scheduleDetail.entity.ScheduleDetail;
+import com.isp.backend.domain.scheduleDetail.repository.ScheduleDetailRepository;
+import com.isp.backend.global.exception.common.MemberNotFoundException;
+import com.isp.backend.global.exception.schedule.CountryNotFoundException;
+import com.isp.backend.global.exception.schedule.NotYourScheduleException;
+import com.isp.backend.global.exception.schedule.ScheduleNotFoundException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+@Service
+public class ScheduleServiceImpl implements ScheduleService {
+
+ private final ScheduleRepository scheduleRepository;
+ private final ScheduleDetailRepository scheduleDetailRepository;
+ private final CountryRepository countryRepository;
+ private final MemberRepository memberRepository;
+ private final ScheduleMapper scheduleMapper;
+
+
+ /** 여행 ì¼ì • ì €ìž¥ **/
+ @Transactional
+ @Override
+ public void saveSchedule(String uid, ScheduleSaveRequest scheduleSaveRequest) {
+ Member findMember = validateUserCheck(uid);
+ Country findCountry = validateCountry(scheduleSaveRequest.getCountry());
+ // 여행 ì¼ì • ì €ìž¥
+ Schedule schedule = scheduleMapper.toScheduleEntity(scheduleSaveRequest, findMember, findCountry);
+ // 여행 ì „ì²´ ì¼ì • ì´ ê²½ë¹„ ì €ìž¥
+ calculateTotalPrice(schedule);
+
+ scheduleRepository.save(schedule);
+ }
+
+
+ /** 여행 ì¼ì • ëª©ë¡ ì¡°íšŒ **/
+ @Override
+ public List getScheduleList(String uid) {
+ Member findMember = validateUserCheck(uid);
+ // ë‚´ê°€ ì“´ ì¼ì • 불러오기
+ List scheduleList = scheduleRepository.findSchedulesByMember(findMember);
+
+ return scheduleList.stream()
+ .map(scheduleMapper::toScheduleListResponseDTO)
+ .collect(Collectors.toList());
+ }
+
+
+ /** 여행 ì¼ì • ìƒì„¸ 조회 **/
+ @Override
+ public ScheduleSaveRequest getScheduleDetail(String uid, Long scheduleId) {
+ Member findMember = validateUserCheck(uid);
+ Schedule findSchedule = validateSchedule(scheduleId);
+
+ return scheduleMapper.toScheduleResponseDTO(findSchedule);
+ }
+
+
+ /** 여행 ì¼ì • ìˆ˜ì • **/
+ @Transactional
+ @Override
+ public ScheduleSaveRequest updateSchedule(String uid, Long scheduleId, ScheduleSaveRequest updateRequestDTO) {
+ Member findMember = validateUserCheck(uid);
+ Country findCountry = validateCountry(updateRequestDTO.getCountry());
+ Schedule findSchedule = validateSchedule(scheduleId);
+
+ // ìžì‹ ì˜ ì—¬í–‰ ì¼ì •ì¸ì§€ 확ì¸
+ if (!findSchedule.getMember().equals(findMember)) {
+ throw new NotYourScheduleException();
+ }
+
+ scheduleDetailRepository.deleteBySchedule(findSchedule);
+
+ // ê¸°ì¡´ì˜ ì¼ì • 엔티티를 ìˆ˜ì •
+ findSchedule.setScheduleName(updateRequestDTO.getScheduleName());
+ findSchedule.setCountry(findCountry);
+ findSchedule.setStartDate(updateRequestDTO.getStartDate());
+ findSchedule.setEndDate(updateRequestDTO.getEndDate());
+
+ // 새로운 ì¼ì • 세부 ì •ë³´ 추가
+ List scheduleDetails = scheduleMapper.updateSchedulesEntity(updateRequestDTO, findSchedule);
+ findSchedule.setScheduleDetails(scheduleDetails);
+
+ // ì´ê²½ë¹„ 재 계산 후 ì €ìž¥
+ calculateTotalPrice(findSchedule);
+ scheduleRepository.save(findSchedule);
+
+ // ìˆ˜ì •ëœ ì¼ì •ì„ 반환 -- ì—†ì• ë„ ë¨ public void ë¡œ 추후 변경 가능
+ return updateRequestDTO;
+ }
+
+
+ /** 여행 ì¼ì • ì‚ì œ **/
+ @Transactional
+ @Override
+ public void deleteSchedule(String uid, Long scheduleId) {
+ Member findMember = validateUserCheck(uid);
+ Schedule findSchedule = validateSchedule(scheduleId);
+ // ìžì‹ ì˜ ì—¬í–‰ ì¼ì •ì¸ì§€ 확ì¸
+ if (!findSchedule.getMember().equals(findMember)) {
+ throw new NotYourScheduleException();
+ }
+
+ // ScheduleDetail í…Œì´ë¸” ë°ì´í„° ì‚ì œ
+ scheduleDetailRepository.deleteBySchedule(findSchedule);
+ findSchedule.setActivated(false);
+
+ scheduleRepository.save(findSchedule);
+ }
+
+ /** ë‚˜ì˜ ì—¬í–‰ D-day ì¶œë ¥ **/
+ @Override
+ public FastestScheduleResponse getFastestSchedule(String uid) {
+ Member findMember = validateUserCheck(uid);
+ List schedules = scheduleRepository.findSchedulesByMember(findMember);
+
+ // 가장 가까운 여행 ì¼ì • 찾기
+ LocalDate today = LocalDate.now();
+ Optional closestScheduleOptional = findClosestSchedule(schedules, today);
+
+ if (closestScheduleOptional.isPresent()) {
+ Schedule closestSchedule = closestScheduleOptional.get();
+ return scheduleMapper.toFastestScheduleDTO(closestSchedule);
+ } else {
+ throw new ScheduleNotFoundException();
+ }
+ }
+
+
+ /** 가장 가까운 ì¼ì • 찾기 **/
+ @Override
+ public Optional findClosestSchedule(List schedules, LocalDate today) {
+ return schedules.stream()
+ .filter(schedule -> LocalDate.parse(schedule.getStartDate()).isAfter(today)) // 오늘 ì´í›„ì˜ ì¼ì •
+ .min(Comparator.comparing(s -> LocalDate.parse(s.getStartDate()))); // 시작ì¼ì´ 가장 ë¹ ë¥¸ 순으로 ì •ë ¬
+ }
+
+
+ /** 여행 ì¼ì • ì´ ê²½ë¹„ 계산 **/
+ @Override
+ public void calculateTotalPrice(Schedule schedule) {
+ double totalPrice = schedule.getScheduleDetails().stream()
+ .mapToDouble(ScheduleDetail::getBudget)
+ .sum();
+ schedule.setTotalPrice(totalPrice);
+ }
+
+
+ /** ìœ ì € ì •ë³´ í™•ì¸ **/
+ @Override
+ public Member validateUserCheck(String uid) {
+ Member findMember = memberRepository.findByUid(uid)
+ .orElseThrow(MemberNotFoundException::new);
+ return findMember;
+ }
+
+
+
+ /** 여행 ì¼ì • ê²€ì¦ **/
+ @Override
+ public Schedule validateSchedule(Long scheduleId) {
+ Schedule findSchedule = scheduleRepository.findByIdAndActivatedIsTrue(scheduleId)
+ .orElseThrow(ScheduleNotFoundException::new);
+ return findSchedule;
+ }
+
+
+ /** 여행 êµê°€ ê²€ì¦ **/
+ @Override
+ public Country validateCountry(String countryName) {
+ Country findCountry = countryRepository.findIdByCity(countryName)
+ .orElseThrow(() -> new CountryNotFoundException());
+ return findCountry;
+ }
+
+
+ /** ìµœê·¼ì— ìƒì„±í•œ 여행 ì¼ì • top 5**/
+ @Override
+ public List getLatestCreatedSchedules(String uid, int limit) {
+ Member findMember = validateUserCheck(uid);
+ List topSchedules = scheduleRepository.findTop5ByMemberOrderByIdDescWithDetails(findMember);
+
+ if (topSchedules.isEmpty()) {
+ throw new ScheduleNotFoundException();
+ }
+
+ List responses = new ArrayList<>();
+ for (Schedule schedule : topSchedules) {
+ LatestCreateResponse response = scheduleMapper.toLatestCreateResponse(schedule, limit);
+ responses.add(response);
+ }
+ return responses;
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/controller/CheckListController.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/controller/CheckListController.java
new file mode 100644
index 00000000..7aca4cfe
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/controller/CheckListController.java
@@ -0,0 +1,63 @@
+package com.isp.backend.domain.scheduleDetail.controller;
+
+import com.isp.backend.domain.scheduleDetail.dto.request.CheckListRequest;
+import com.isp.backend.domain.scheduleDetail.dto.response.CheckListResponse;
+import com.isp.backend.domain.scheduleDetail.service.CheckListService;
+import com.isp.backend.global.security.CustomUserDetails;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.* ;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/schedules")
+@RequiredArgsConstructor
+public class CheckListController {
+
+ private final CheckListService checkListService;
+
+ /** ì¼ì • ì²´í¬ë¦¬ìŠ¤íŠ¸ ì €ìž¥ API **/
+ @PostMapping("/{scheduleId}/checklists")
+ public ResponseEntity> addCheckLists(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @PathVariable Long scheduleId, @RequestBody List checkListRequests) {
+ String memberUid = customUserDetails.getUsername();
+ List checkListResponses = checkListService.addCheckLists(memberUid, scheduleId, checkListRequests);
+ return ResponseEntity.ok(checkListResponses);
+ }
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ 조회 API **/
+ @GetMapping("/{scheduleId}/checklists")
+ public ResponseEntity> getCheckLists(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @PathVariable Long scheduleId) {
+ String memberUid = customUserDetails.getUsername();
+ List checkListResponses = checkListService.getCheckLists(memberUid, scheduleId);
+ return ResponseEntity.ok(checkListResponses);
+ }
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ ì‚ì œ API **/
+ @DeleteMapping("/{scheduleId}/checklists/{checkListId}")
+ public ResponseEntity> deleteCheckList(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @PathVariable Long scheduleId,
+ @PathVariable Long checkListId) {
+ String memberUid = customUserDetails.getUsername();
+ List checkListResponses = checkListService.deleteCheckList(memberUid, scheduleId, checkListId);
+ return ResponseEntity.ok(checkListResponses);
+ }
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ ìˆ˜ì • API **/
+ @PutMapping("/{scheduleId}/checklists")
+ public ResponseEntity> updateCheckLists(@AuthenticationPrincipal CustomUserDetails customUserDetails,
+ @PathVariable Long scheduleId,
+ @RequestBody List checkListResponses) {
+ String memberUid = customUserDetails.getUsername();
+ List updatedCheckListResponses = checkListService.updateCheckLists(memberUid, scheduleId, checkListResponses);
+ return ResponseEntity.ok(updatedCheckListResponses);
+ }
+
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/dto/request/CheckListRequest.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/dto/request/CheckListRequest.java
new file mode 100644
index 00000000..8c1731d9
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/dto/request/CheckListRequest.java
@@ -0,0 +1,18 @@
+package com.isp.backend.domain.scheduleDetail.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class CheckListRequest {
+
+ private String todo;
+
+ private boolean check;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/dto/response/CheckListResponse.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/dto/response/CheckListResponse.java
new file mode 100644
index 00000000..e029c062
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/dto/response/CheckListResponse.java
@@ -0,0 +1,24 @@
+package com.isp.backend.domain.scheduleDetail.dto.response;
+
+import com.isp.backend.domain.scheduleDetail.entity.CheckList;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class CheckListResponse {
+ private Long id;
+ private String todo;
+ private boolean check;
+
+ public CheckListResponse(CheckList checkList) {
+ this.id = checkList.getId();
+ this.todo = checkList.getTodo();
+ this.check = checkList.isChecked();
+ }
+}
+
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/CheckList.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/CheckList.java
new file mode 100644
index 00000000..f9e68f21
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/CheckList.java
@@ -0,0 +1,31 @@
+package com.isp.backend.domain.scheduleDetail.entity;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.global.common.BaseEntity;
+import jakarta.persistence.*;
+import lombok.*;
+
+@Getter
+@AllArgsConstructor
+@Entity
+@Builder
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "checkList")
+public class CheckList extends BaseEntity {
+
+ @Id
+ @Column(name = "id", unique = true, nullable = false)
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String todo ;
+
+ @Column(nullable = false)
+ private boolean isChecked = false;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "schedule_id", nullable = false)
+ private Schedule schedule;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java
new file mode 100644
index 00000000..2851dc96
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java
@@ -0,0 +1,41 @@
+package com.isp.backend.domain.scheduleDetail.entity;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import jakarta.persistence.*;
+import lombok.*;
+
+@AllArgsConstructor
+@Entity
+@Setter
+@Builder
+@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "schedule_detail")
+public class ScheduleDetail {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String todo;
+
+ private String date;
+
+ private String place;
+
+ private int num;
+
+ @Enumerated(EnumType.STRING)
+ private ScheduleType scheduleType ;
+
+ private double budget;
+
+ private double latitude;
+
+ private double longitude;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "schedules_id" , nullable = false) // 컬럼명 ì‚ì œX
+ private Schedule schedule;
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleType.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleType.java
new file mode 100644
index 00000000..0bafc8dc
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleType.java
@@ -0,0 +1,14 @@
+package com.isp.backend.domain.scheduleDetail.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum ScheduleType {
+
+ AIRPLANE,
+ HOTEL,
+ PLACE,
+
+};
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/repository/CheckListRepository.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/repository/CheckListRepository.java
new file mode 100644
index 00000000..14addd51
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/repository/CheckListRepository.java
@@ -0,0 +1,11 @@
+package com.isp.backend.domain.scheduleDetail.repository;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.scheduleDetail.entity.CheckList;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface CheckListRepository extends JpaRepository {
+ List findBySchedule(Schedule schedule);
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/repository/ScheduleDetailRepository.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/repository/ScheduleDetailRepository.java
new file mode 100644
index 00000000..8061c1b0
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/repository/ScheduleDetailRepository.java
@@ -0,0 +1,10 @@
+package com.isp.backend.domain.scheduleDetail.repository;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.scheduleDetail.entity.ScheduleDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ScheduleDetailRepository extends JpaRepository {
+
+ void deleteBySchedule(Schedule schedule);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/service/CheckListService.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/service/CheckListService.java
new file mode 100644
index 00000000..4c92d7f5
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/service/CheckListService.java
@@ -0,0 +1,21 @@
+package com.isp.backend.domain.scheduleDetail.service;
+
+import com.isp.backend.domain.scheduleDetail.dto.request.CheckListRequest;
+import com.isp.backend.domain.scheduleDetail.dto.response.CheckListResponse;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface CheckListService {
+ @Transactional
+ List addCheckLists(String uid, Long scheduleId, List checkListRequests);
+
+ @Transactional(readOnly = true)
+ List getCheckLists(String uid, Long scheduleId);
+
+ @Transactional
+ List deleteCheckList(String uid, Long scheduleId, Long checkListId);
+
+ @Transactional
+ List updateCheckLists(String uid, Long scheduleId, List checkListResponses);
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/service/CheckListServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/service/CheckListServiceImpl.java
new file mode 100644
index 00000000..904ec9a9
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/service/CheckListServiceImpl.java
@@ -0,0 +1,129 @@
+package com.isp.backend.domain.scheduleDetail.service;
+
+import com.isp.backend.domain.member.entity.Member;
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.schedule.repository.ScheduleRepository;
+import com.isp.backend.domain.schedule.service.ScheduleService;
+import com.isp.backend.domain.scheduleDetail.dto.request.CheckListRequest;
+import com.isp.backend.domain.scheduleDetail.dto.response.CheckListResponse;
+import com.isp.backend.domain.scheduleDetail.entity.CheckList;
+import com.isp.backend.domain.scheduleDetail.repository.CheckListRepository;
+import com.isp.backend.global.exception.schedule.CheckListNotFoundException;
+import com.isp.backend.global.exception.schedule.NotYourScheduleException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RequiredArgsConstructor
+@Transactional
+@Service
+public class CheckListServiceImpl implements CheckListService {
+ private final CheckListRepository checkListRepository;
+ private final ScheduleService scheduleService;
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ 추가 API **/
+ @Override
+ @Transactional
+ public List addCheckLists(String uid, Long scheduleId, List checkListRequests) {
+ Member findMember = scheduleService.validateUserCheck(uid);
+ Schedule findSchedule = scheduleService.validateSchedule(scheduleId);
+ // ìžì‹ ì˜ ì—¬í–‰ ì¼ì •ì¸ì§€ 확ì¸
+ if (!findSchedule.getMember().equals(findMember)) {
+ throw new NotYourScheduleException();
+ }
+
+ List responses = new ArrayList<>();
+ for (CheckListRequest request : checkListRequests) {
+ CheckList checkList = CheckList.builder()
+ .todo(request.getTodo())
+ .isChecked(request.isCheck())
+ .schedule(findSchedule)
+ .build();
+ checkListRepository.save(checkList);
+ responses.add(new CheckListResponse(checkList));
+ }
+
+ return responses;
+ }
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ 조회 API **/
+ @Override
+ @Transactional(readOnly = true)
+ public List getCheckLists(String uid, Long scheduleId) {
+ Member findMember = scheduleService.validateUserCheck(uid);
+ Schedule findSchedule = scheduleService.validateSchedule(scheduleId);
+ // ìžì‹ ì˜ ì—¬í–‰ ì¼ì •ì¸ì§€ 확ì¸
+ if (!findSchedule.getMember().equals(findMember)) {
+ throw new NotYourScheduleException();
+ }
+
+ List checkLists = checkListRepository.findBySchedule(findSchedule);
+ List responses = checkLists.stream()
+ .map(CheckListResponse::new)
+ .collect(Collectors.toList());
+
+ return responses;
+ }
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ ì‚ì œ API **/
+ @Override
+ @Transactional
+ public List deleteCheckList(String uid, Long scheduleId, Long checkListId) {
+ Member findMember = scheduleService.validateUserCheck(uid);
+ Schedule findSchedule = scheduleService.validateSchedule(scheduleId);
+ CheckList checkList = checkListRepository.findById(checkListId)
+ .orElseThrow(CheckListNotFoundException::new);
+
+ // ìžì‹ ì˜ ì—¬í–‰ ì¼ì •ì¸ì§€ í™•ì¸ + ì²´í¬ë¦¬ìŠ¤íŠ¸ê°€ 해당 ìŠ¤ì¼€ì¤„ì— ì†í•˜ëŠ”지 확ì¸
+ if (!findSchedule.getMember().equals(findMember) || !checkList.getSchedule().equals(findSchedule)) {
+ throw new NotYourScheduleException();
+ }
+
+ checkListRepository.delete(checkList);
+
+ List checkLists = checkListRepository.findBySchedule(findSchedule);
+ List responses = checkLists.stream()
+ .map(CheckListResponse::new)
+ .collect(Collectors.toList());
+
+ return responses;
+ }
+
+
+ /** 여행 ì²´í¬ë¦¬ìŠ¤íŠ¸ ìˆ˜ì • API **/
+ @Override
+ @Transactional
+ public List updateCheckLists(String uid, Long scheduleId, List checkListResponses) {
+ Member findMember = scheduleService.validateUserCheck(uid);
+ Schedule findSchedule = scheduleService.validateSchedule(scheduleId);
+
+ if (!findSchedule.getMember().equals(findMember)) {
+ throw new NotYourScheduleException();
+ }
+
+ for (CheckListResponse response : checkListResponses) {
+ CheckList checkList = checkListRepository.findById(response.getId())
+ .orElseThrow(CheckListNotFoundException::new);
+ if (!checkList.getSchedule().equals(findSchedule)) {
+ throw new NotYourScheduleException();
+ }
+ checkList.setTodo(response.getTodo());
+ checkList.setChecked(response.isCheck());
+ }
+
+ List updatedCheckLists = checkListRepository.findBySchedule(findSchedule);
+ List responses = updatedCheckLists.stream()
+ .map(CheckListResponse::new)
+ .collect(Collectors.toList());
+
+ return responses;
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/controller/ScheduleImageController.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/controller/ScheduleImageController.java
new file mode 100644
index 00000000..fb79ca5e
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/controller/ScheduleImageController.java
@@ -0,0 +1,24 @@
+package com.isp.backend.domain.scheduleImage.controller;
+
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageResponse;
+import com.isp.backend.domain.scheduleImage.service.SaveImageService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/scheduleImages")
+public class ScheduleImageController {
+
+ private final SaveImageService saveImageService;
+
+ @PostMapping
+ @ResponseStatus(HttpStatus.CREATED)
+ public SaveScheduleImageResponse create(@RequestPart(value = "image", required = false) MultipartFile image,
+ @RequestPart(value = "saveScheduleImageRequest") SaveScheduleImageRequest request) {
+ return saveImageService.save(request, image);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/dto/SaveScheduleImageRequest.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/dto/SaveScheduleImageRequest.java
new file mode 100644
index 00000000..852acc87
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/dto/SaveScheduleImageRequest.java
@@ -0,0 +1,19 @@
+package com.isp.backend.domain.scheduleImage.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Getter
+@NoArgsConstructor
+public class SaveScheduleImageRequest {
+ private Long scheduleId;
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime saveDate;
+
+// public Long scheduleId() {
+// return scheduleId;
+// }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/dto/SaveScheduleImageResponse.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/dto/SaveScheduleImageResponse.java
new file mode 100644
index 00000000..d6270049
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/dto/SaveScheduleImageResponse.java
@@ -0,0 +1,17 @@
+package com.isp.backend.domain.scheduleImage.dto;
+
+import com.isp.backend.domain.scheduleImage.entity.ScheduleImage;
+import lombok.Getter;
+
+@Getter
+public class SaveScheduleImageResponse {
+ private Long id;
+ private Long scheduleId;
+ private String path;
+
+ public SaveScheduleImageResponse(ScheduleImage scheduleImage) {
+ this.id = scheduleImage.getId();
+ this.scheduleId = scheduleImage.getSchedule().getId();
+ this.path = scheduleImage.getPath();
+ }
+}
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/entity/ScheduleImage.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/entity/ScheduleImage.java
new file mode 100644
index 00000000..49264ecc
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/entity/ScheduleImage.java
@@ -0,0 +1,27 @@
+package com.isp.backend.domain.scheduleImage.entity;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Entity
+@Getter
+@NoArgsConstructor
+@Table(name = "schedule_image")
+public class ScheduleImage {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @ManyToOne
+ @JoinColumn(name = "schedule_id")
+ private Schedule schedule;
+ private String path;
+
+ public ScheduleImage(Schedule schedule, String path) {
+ this.schedule = schedule;
+ this.path = path;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/repository/ScheduleImageRepository.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/repository/ScheduleImageRepository.java
new file mode 100644
index 00000000..bc05c3e5
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/repository/ScheduleImageRepository.java
@@ -0,0 +1,7 @@
+package com.isp.backend.domain.scheduleImage.repository;
+
+import com.isp.backend.domain.scheduleImage.entity.ScheduleImage;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ScheduleImageRepository extends JpaRepository {
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/repository/ScheduleImageS3Repository.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/repository/ScheduleImageS3Repository.java
new file mode 100644
index 00000000..991f460f
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/repository/ScheduleImageS3Repository.java
@@ -0,0 +1,51 @@
+package com.isp.backend.domain.scheduleImage.repository;
+
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
+import io.awspring.cloud.s3.S3Resource;
+import io.awspring.cloud.s3.S3Template;
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+@Repository
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class ScheduleImageS3Repository {
+ private static final String IMAGE = "HowAboutTrip-Backend-ScheduleImage/";
+ private static final String SLASH = "/";
+
+ private final S3Template s3template;
+ private final String bucketName;
+
+ public ScheduleImageS3Repository(S3Template s3template,
+ @Value("${spring.cloud.aws.s3.bucket}") String bucketName) {
+ this.s3template = s3template;
+ this.bucketName = bucketName;
+ }
+
+ public String save(SaveScheduleImageRequest request, MultipartFile image) {
+ String path = IMAGE + request.getScheduleId() + SLASH + image.getOriginalFilename();
+ S3Resource result = s3template.upload(bucketName, path, getInputStream(image));
+ return getUrl(result);
+ }
+
+ private InputStream getInputStream(MultipartFile image) {
+ try {
+ return image.getInputStream();
+ } catch (IOException e) {
+ throw new RuntimeException("Error getting input stream from MultipartFile", e);
+ }
+ }
+
+ private String getUrl(S3Resource s3Resource) {
+ try {
+ return s3Resource.getURL().toString();
+ } catch (IOException e) {
+ throw new RuntimeException("Error getting URL from S3Resource", e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/service/SaveImageService.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/service/SaveImageService.java
new file mode 100644
index 00000000..17f55751
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/service/SaveImageService.java
@@ -0,0 +1,10 @@
+package com.isp.backend.domain.scheduleImage.service;
+
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageResponse;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface SaveImageService {
+
+ SaveScheduleImageResponse save(SaveScheduleImageRequest request, MultipartFile image);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleImage/service/ScheduleImageService.java b/backend/src/main/java/com/isp/backend/domain/scheduleImage/service/ScheduleImageService.java
new file mode 100644
index 00000000..989eef97
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/domain/scheduleImage/service/ScheduleImageService.java
@@ -0,0 +1,31 @@
+package com.isp.backend.domain.scheduleImage.service;
+
+import com.isp.backend.domain.schedule.entity.Schedule;
+import com.isp.backend.domain.schedule.repository.ScheduleRepository;
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
+import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageResponse;
+import com.isp.backend.domain.scheduleImage.entity.ScheduleImage;
+import com.isp.backend.domain.scheduleImage.repository.ScheduleImageRepository;
+import com.isp.backend.domain.scheduleImage.repository.ScheduleImageS3Repository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+@Service
+@RequiredArgsConstructor
+public class ScheduleImageService implements SaveImageService {
+
+ private final ScheduleImageS3Repository scheduleImageS3Repository;
+ private final ScheduleRepository scheduleRepository;
+ private final ScheduleImageRepository scheduleImageRepository;
+
+ @Override
+ public SaveScheduleImageResponse save(SaveScheduleImageRequest request, MultipartFile image) {
+ String imagePath = scheduleImageS3Repository.save(request, image);
+ Schedule schedule = scheduleRepository.findById(request.getScheduleId()).orElseThrow(IllegalArgumentException::new);
+ ScheduleImage scheduleImage = new ScheduleImage(schedule, imagePath);
+
+ scheduleImageRepository.save(scheduleImage);
+ return new SaveScheduleImageResponse(scheduleImage);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/global/common/BaseEntity.java b/backend/src/main/java/com/isp/backend/global/common/BaseEntity.java
new file mode 100644
index 00000000..6bcc8beb
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/global/common/BaseEntity.java
@@ -0,0 +1,38 @@
+package com.isp.backend.global.common;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Getter
+@Setter
+@MappedSuperclass
+@EntityListeners(AuditingEntityListener.class)
+public class BaseEntity {
+
+ @CreatedDate
+ @Column(name = "created_at", updatable = false)
+ private String createdAt;
+
+ @LastModifiedDate
+ @Column(name = "updated_at")
+ private String updatedAt;
+
+
+ @PrePersist
+ public void onPrePersist() {
+ this.createdAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"));
+ this.updatedAt = this.createdAt;
+ }
+
+ @PreUpdate
+ public void onPreUpdate() {
+ this.updatedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"));
+ }
+}
diff --git a/backend/src/main/java/com/isp/backend/global/exception/CustomException.java b/backend/src/main/java/com/isp/backend/global/exception/CustomException.java
new file mode 100644
index 00000000..9ef09c26
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/global/exception/CustomException.java
@@ -0,0 +1,14 @@
+package com.isp.backend.global.exception;
+
+import lombok.Getter;
+
+@Getter
+public class CustomException extends RuntimeException {
+
+ private final ErrorCode errorCode;
+
+ public CustomException(ErrorCode errorCode) {
+ super(errorCode.getMessage());
+ this.errorCode = errorCode;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/global/exception/ErrorCode.java b/backend/src/main/java/com/isp/backend/global/exception/ErrorCode.java
new file mode 100644
index 00000000..60ebb2b0
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/global/exception/ErrorCode.java
@@ -0,0 +1,55 @@
+package com.isp.backend.global.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+
+@RequiredArgsConstructor
+@Getter
+public enum ErrorCode {
+
+
+ // Common
+ MEMBER_NOT_FOUND(HttpStatus.UNAUTHORIZED, "U001", "사용ìžë¥¼ ì°¾ì„ ìˆ˜ 없습니다."),
+ MEMBER_NOT_ACTIVATED(HttpStatus.BAD_REQUEST, "U002", "사용ìžê°€ 활성화 ìƒíƒœê°€ 아닙니다."),
+ AUTHENTICATION_FAILED(HttpStatus.FORBIDDEN, "U003", "ê¶Œí•œì´ ì—†ëŠ” ìš”ì²ìž…니다. í† í°ì„ 추가해주세요."),
+ ACCESS_TOKEN_IS_INVALID(HttpStatus.UNAUTHORIZED, "U004", "엑세스 í† í°ì´ ìœ íš¨í•˜ì§€ 않습니다."),
+ REFRESH_TOKEN_IS_INVALID(HttpStatus.UNAUTHORIZED, "U005", "ë¦¬í”„ë ˆì‹œ í† í°ì´ ìœ íš¨í•˜ì§€ 않습니다."),
+
+ // Image
+ DIRECTORY_NAME_NOTFOUND(HttpStatus.NOT_FOUND,"I001","S3ì—ì„œ 해당 ë””ë ‰í† ë¦¬ì˜ ì´ë¦„ì„ ì°¾ì„ ìˆ˜ 없습니다."),
+ IMAGE_ALREADY_EXISTING(HttpStatus.BAD_REQUEST, "I002", "ì´ë¯¸ì§€ê°€ ì´ë¯¸ ì €ìž¥ë˜ì–´ 있습니다."),
+
+ // Schedule
+ COUNTRY_NOT_FOUND(HttpStatus.NOT_FOUND, "S001", "ì—¬í–‰í• êµê°€ë¥¼ ì°¾ì„ ìˆ˜ 없습니다."),
+ SCHEDULE_NOT_FOUND(HttpStatus.NOT_FOUND, "S002", "여행 ì¼ì •ì„ ì°¾ì„ ìˆ˜ 없습니다."),
+ NOT_YOUR_SCHEDULE(HttpStatus.UNAUTHORIZED, "S003", "사용ìžì˜ 여행 ì¼ì •ì´ 아닙니다."),
+ IMAGE_NOT_FOUND(HttpStatus.NOT_FOUND, "S004", "ì´ë¯¸ì§€ë¥¼ ì°¾ì„ ìˆ˜ 없습니다."),
+ IATA_CODE_NOT_FOUND(HttpStatus.NOT_FOUND, "S005", "해당 êµê°€ì˜ ê³µí• ì½”ë“œë¥¼ ì°¾ì„ ìˆ˜ 없습니다."),
+ CHECK_LIST_NOT_FOUND(HttpStatus.NOT_FOUND, "S006", "ì²´í¬ë¦¬ìŠ¤íŠ¸ë¥¼ ì°¾ì„ ìˆ˜ 없습니다"),
+
+ // Receipt
+ RECEIPT_NOT_FOUND(HttpStatus.NOT_FOUND, "R001", "헤딩 ì˜ìˆ˜ì¦ ID를 ì°¾ì„ ìˆ˜ 없습니다."),
+
+ // Open API
+ AMADEUS_SEARCH_FAILED(HttpStatus.INTERNAL_SERVER_ERROR,"F001", "아마ë°ìš°ìŠ¤ ìš”ì²ì„ ê°€ì ¸ì˜¤ëŠ” 중 오류를 ë°œìƒí–ˆìŠµë‹ˆë‹¤."),
+ SKY_SCANNER_GENERATE_FAILED(HttpStatus.INTERNAL_SERVER_ERROR,"F002", "스카ì´ìŠ¤ìºë„ˆ URLì„ ìƒì„±í• 수 없습니다."),
+ FLIGHT_NOT_FOUND(HttpStatus.NOT_FOUND, "F003", "해당 idì˜ í•ê³µê¶Œì„ ì°¾ì„ ìˆ˜ 없습니다."),
+ NOT_YOUR_FLIGHT(HttpStatus.UNAUTHORIZED, "F004", "사용ìžì˜ í•ê³µê¶Œì´ 아닙니다"),
+ OPEN_WEATHER_SEARCH_FAILED(HttpStatus.NOT_FOUND,"F005", "ë‚ ì”¨ ì •ë³´ íŒŒì‹±ì— ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤"),
+ EXCHANGE_RATE_SEARCH_FAILED(HttpStatus.INTERNAL_SERVER_ERROR,"F006", "환율 ìš”ì²ì„ ê°€ì ¸ì˜¤ëŠ” 중 오류를 ë°œìƒí–ˆìŠµë‹ˆë‹¤."),
+ EXCHANGE_RATE_IS_FAILED(HttpStatus.BAD_REQUEST,"F007", "환율 DB를 ì €ìž¥í•˜ë˜ ì¤‘ 오류가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤.");
+
+
+ private HttpStatus status;
+ private String code;
+ private String message;
+
+
+ ErrorCode(HttpStatus status, String code, String message) {
+ this.status = status;
+ this.code = code;
+ this.message = message;
+ }
+
+}
diff --git a/backend/src/main/java/com/isp/backend/global/exception/ErrorResponse.java b/backend/src/main/java/com/isp/backend/global/exception/ErrorResponse.java
new file mode 100644
index 00000000..07c04b7a
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/global/exception/ErrorResponse.java
@@ -0,0 +1,35 @@
+package com.isp.backend.global.exception;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.http.HttpStatus;
+
+@Getter
+@Setter
+@NoArgsConstructor
+public class ErrorResponse {
+ private String errorMessage;
+ private HttpStatus httpStatus;
+ private String code;
+
+
+ public ErrorResponse(HttpStatus status, String s) {
+ this.errorMessage = s;
+ this.httpStatus = status;
+ }
+
+ public ErrorResponse(ErrorCode code) {
+ this.errorMessage = code.getMessage();
+ this.httpStatus = code.getStatus();
+ this.code = code.getCode();
+ }
+
+ @Override
+ public String toString() {
+ return "Error Message: " + errorMessage + "\n" +
+ "HTTP Status: " + httpStatus + "\n" +
+ "Error Code: " + code + "\n";
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/isp/backend/global/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/isp/backend/global/exception/GlobalExceptionHandler.java
new file mode 100644
index 00000000..8b21f520
--- /dev/null
+++ b/backend/src/main/java/com/isp/backend/global/exception/GlobalExceptionHandler.java
@@ -0,0 +1,24 @@
+package com.isp.backend.global.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity