diff --git a/.gitignore b/.gitignore
index e69de29b..7a7c00c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,291 @@
+# 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/
+
+# 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
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/1/2/12e74ec3d058fd5c3591dbd03535b11ce2aa099a b/.idea/sonarlint/issuestore/1/2/12e74ec3d058fd5c3591dbd03535b11ce2aa099a
deleted file mode 100644
index e69de29b..00000000
diff --git a/.idea/sonarlint/issuestore/1/9/1971a7780cde29eecf35980e90fd6a543f2272ce b/.idea/sonarlint/issuestore/1/9/1971a7780cde29eecf35980e90fd6a543f2272ce
deleted file mode 100644
index e69de29b..00000000
diff --git a/.idea/sonarlint/issuestore/1/a/1a222870c2bab9d606c7f94739b8a006ed8ce06f b/.idea/sonarlint/issuestore/1/a/1a222870c2bab9d606c7f94739b8a006ed8ce06f
deleted file mode 100644
index e69de29b..00000000
diff --git a/.idea/sonarlint/issuestore/b/2/b29bd1f7028776d53a3de51178113ae25a5efa01 b/.idea/sonarlint/issuestore/b/2/b29bd1f7028776d53a3de51178113ae25a5efa01
deleted file mode 100644
index e69de29b..00000000
diff --git a/.idea/sonarlint/securityhotspotstore/2/3/2363d464b7abe433f93c6cab2d693ce0bd00ed52 b/.idea/sonarlint/securityhotspotstore/2/3/2363d464b7abe433f93c6cab2d693ce0bd00ed52
deleted file mode 100644
index e69de29b..00000000
diff --git a/.idea/sonarlint/securityhotspotstore/b/2/b29bd1f7028776d53a3de51178113ae25a5efa01 b/.idea/sonarlint/securityhotspotstore/b/2/b29bd1f7028776d53a3de51178113ae25a5efa01
deleted file mode 100644
index e69de29b..00000000
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/app/build.gradle.kts b/android/HowAboutTrip/app/build.gradle.kts
index 6205d766..b3331632 100644
--- a/android/HowAboutTrip/app/build.gradle.kts
+++ b/android/HowAboutTrip/app/build.gradle.kts
@@ -25,9 +25,12 @@ android {
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 {
@@ -58,15 +61,24 @@ dependencies {
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("com.airbnb.android:lottie:6.3.0")
- implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
- implementation("androidx.fragment:fragment-ktx:1.7.0-alpha07")
- implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
+ 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.0")
+ 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")
diff --git a/android/HowAboutTrip/app/src/main/AndroidManifest.xml b/android/HowAboutTrip/app/src/main/AndroidManifest.xml
index 67856c38..af2348be 100644
--- a/android/HowAboutTrip/app/src/main/AndroidManifest.xml
+++ b/android/HowAboutTrip/app/src/main/AndroidManifest.xml
@@ -2,7 +2,8 @@
-
+
+
+ android:exported="true">
+
+
+
+ android:exported="true"
+ android:theme="@style/Theme.HowAboutTrip.BlackStatusBar">
@@ -29,7 +37,9 @@
+ android:theme="@style/Theme.HowAboutTrip.BlackStatusBar"
+ android:exported="true">
+
\ 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/LoginRepository.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/model/LoginRepository.kt
deleted file mode 100644
index 40d3617f..00000000
--- a/android/HowAboutTrip/app/src/main/java/com/project/how/model/LoginRepository.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.project.how.model
-
-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
-
-class LoginRepository {
- private val firebaseAuth = FirebaseAuth.getInstance()
- private val _userLiveData = MutableLiveData()
- val userLiveData: LiveData
- get() = _userLiveData
-
- 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}")
- }
- }
- }
-}
\ 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
index 354a3599..27587970 100644
--- 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
@@ -6,32 +6,35 @@ import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
-import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
-import com.google.android.gms.auth.api.identity.BeginSignInRequest
+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.google.android.gms.common.api.ApiException
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.LoginViewModel
+import com.project.how.view_model.MemberViewModel
+import kotlinx.coroutines.launch
class LoginActivity : AppCompatActivity() {
private lateinit var binding : ActivityLoginBinding
- private val viewModel: LoginViewModel by viewModels()
+ 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
- val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
+ binding.lifecycleOwner = this
+
+ gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(BuildConfig.GOOGLE_SERVER_ID)
.requestEmail()
.build()
@@ -42,17 +45,85 @@ class LoginActivity : AppCompatActivity() {
try {
val account = task.result
viewModel.getUser(account.idToken!!)
- Log.d("activityResultLauncher", "Login Success\nidToken : ${account.idToken}\nid : ${account.id}\nemail : ${account.email}")
- startActivity(Intent(this, MainActivity::class.java))
+ 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()
+ }
+ }
- binding.googleLogin.setOnClickListener {
- activityResultLauncher.launch(googleSignInRequest.signInIntent)
- binding.lottie.pauseAnimation()
+ 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
index ad1649f3..c2664fbc 100644
--- 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
@@ -5,12 +5,42 @@ 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
index 91971ab6..fda55d68 100644
--- 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
@@ -3,23 +3,55 @@ 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 {
- delay(1000)
- startActivity(Intent(this@SplashActivity, LoginActivity::class.java))
+ 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/LoginViewModel.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/LoginViewModel.kt
deleted file mode 100644
index c18e0a5e..00000000
--- a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/LoginViewModel.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.project.how.view_model
-
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.ViewModel
-import com.google.firebase.auth.FirebaseUser
-import com.project.how.model.LoginRepository
-
-class LoginViewModel : ViewModel() {
- private var loginRepository : LoginRepository = LoginRepository()
- private val _userLiveData = loginRepository.userLiveData
- val userLiveData: LiveData
- get() = _userLiveData
-
- fun getUser(idToken: String){
- loginRepository.getUser(idToken)
- }
-}
\ 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/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/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/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/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/layout/activity_login.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_login.xml
index 835729db..038709f2 100644
--- a/android/HowAboutTrip/app/src/main/res/layout/activity_login.xml
+++ b/android/HowAboutTrip/app/src/main/res/layout/activity_login.xml
@@ -34,6 +34,7 @@
android:fontFamily="@font/bm_hanna"
android:gravity="center"
android:text="@string/login_under_text"
+ android:textColor="@color/black"
android:textSize="16sp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
@@ -47,6 +48,7 @@
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/google_login"
+ android:onClick="@{() -> login.login()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
diff --git a/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml
index 2832d141..cc7b6ff2 100644
--- a/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml
+++ b/android/HowAboutTrip/app/src/main/res/layout/activity_main.xml
@@ -8,33 +8,105 @@
name="main"
type="com.project.how.view.activity.MainActivity" />
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+ android:layout_height="wrap_content"
+ style="@style/Widget.MaterialComponents.BottomAppBar"
+ android:background="@drawable/white_rectangle_top_shadow"
+ android:backgroundTint="@color/white"
+ android:layout_marginTop="30dp"
+ android:paddingTop="10dp"
+ app:fabAnchorMode="cradle"
+ app:fabCradleMargin="-20dp"
+ app:fabAlignmentMode="center">
+
+
+
+
+
+
+
-
+
+
-
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.9" />
-
+
\ 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/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/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
index 7496c57d..95d02503 100644
--- a/android/HowAboutTrip/app/src/main/res/values-night/themes.xml
+++ b/android/HowAboutTrip/app/src/main/res/values-night/themes.xml
@@ -1,12 +1,31 @@
+
+
+
+
+
\ 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
index 1eb546af..9cc5ec15 100644
--- a/android/HowAboutTrip/app/src/main/res/values/strings.xml
+++ b/android/HowAboutTrip/app/src/main/res/values/strings.xml
@@ -3,4 +3,33 @@
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
index 7496c57d..eb54e315 100644
--- a/android/HowAboutTrip/app/src/main/res/values/themes.xml
+++ b/android/HowAboutTrip/app/src/main/res/values/themes.xml
@@ -9,4 +9,23 @@
- @color/black
- false
+
+
+
+
+
+
+
\ 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/build.gradle.kts b/android/HowAboutTrip/build.gradle.kts
index 591e568c..817165d5 100644
--- a/android/HowAboutTrip/build.gradle.kts
+++ b/android/HowAboutTrip/build.gradle.kts
@@ -5,7 +5,7 @@ buildscript {
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id("com.android.application") version "8.2.1" apply false
+ 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"
diff --git a/backend/.gitignore b/backend/.gitignore
deleted file mode 100644
index 52dd9f22..00000000
--- a/backend/.gitignore
+++ /dev/null
@@ -1,42 +0,0 @@
-HELP.md
-.gradle
-build/
-!gradle/wrapper/gradle-wrapper.jar
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-bin/
-!**/src/main/**/bin/
-!**/src/test/**/bin/
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-out/
-!**/src/main/**/out/
-!**/src/test/**/out/
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-
-### VS Code ###
-.vscode/
-
-# Elastic Beanstalk Files
-.elasticbeanstalk/*
-!.elasticbeanstalk/*.cfg.yml
-!.elasticbeanstalk/*.global.yml