diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e691c560..90a7473d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -57,6 +57,7 @@ dependencies { implementation(projects.feature.home) implementation(projects.feature.match) implementation(projects.feature.onboarding) + implementation(projects.feature.collection) // implementation(libs.coil.core) implementation(libs.startup) // implementation(libs.security) diff --git a/app/src/main/java/com/moya/funch/MainActivity.kt b/app/src/main/java/com/moya/funch/MainActivity.kt index 7867ebe2..5b2c97ae 100644 --- a/app/src/main/java/com/moya/funch/MainActivity.kt +++ b/app/src/main/java/com/moya/funch/MainActivity.kt @@ -6,7 +6,7 @@ import androidx.activity.compose.setContent import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.moya.funch.datastore.UserDataStore @@ -28,7 +28,7 @@ class MainActivity : ComponentActivity() { installSplashScreen() setContent { FunchTheme { - var showLoading by remember { mutableStateOf(true) } + var showLoading by rememberSaveable { mutableStateOf(true) } LaunchedEffect(Unit) { delay(1500) diff --git a/app/src/main/java/com/moya/funch/di/MbtiCollectionModule.kt b/app/src/main/java/com/moya/funch/di/MbtiCollectionModule.kt new file mode 100644 index 00000000..d8f719d2 --- /dev/null +++ b/app/src/main/java/com/moya/funch/di/MbtiCollectionModule.kt @@ -0,0 +1,32 @@ +package com.moya.funch.di + +import com.moya.funch.repository.MbtiCollectionRepository +import com.moya.funch.repository.MbtiCollectionRepositoryImpl +import com.moya.funch.usecase.LoadMbtiCollectionUseCase +import com.moya.funch.usecase.LoadMbtiCollectionUseCaseImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object MbtiCollectionModule { + + @Module + @InstallIn(SingletonComponent::class) + interface UseCaseBinder { + @Binds + @Singleton + fun bindLoadMbtiCollectionUseCase(useCase: LoadMbtiCollectionUseCaseImpl): LoadMbtiCollectionUseCase + } + + @Module + @InstallIn(SingletonComponent::class) + interface RepositoryBinder { + @Binds + @Singleton + fun bindMbtiCollectionRepository(repository: MbtiCollectionRepositoryImpl): MbtiCollectionRepository + } +} diff --git a/app/src/main/java/com/moya/funch/navigation/FunchNavHost.kt b/app/src/main/java/com/moya/funch/navigation/FunchNavHost.kt index 4b580a22..29c68e4b 100644 --- a/app/src/main/java/com/moya/funch/navigation/FunchNavHost.kt +++ b/app/src/main/java/com/moya/funch/navigation/FunchNavHost.kt @@ -6,9 +6,12 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions +import com.moya.funch.collection.navigation.collectionScreen +import com.moya.funch.collection.navigation.navigateToCollection import com.moya.funch.match.navigation.matchingScreen import com.moya.funch.match.navigation.navigateToMatching import com.moya.funch.onboarding.navigation.ON_BOARDING_ROUTE +import com.moya.funch.onboarding.navigation.navigateToOnBoarding import com.moya.funch.onboarding.navigation.onBoardingScreen @Composable @@ -20,15 +23,17 @@ fun FunchNavHost(hasProfile: Boolean, navController: NavHostController = remembe with(navController) { profileGraph( onNavigateToHome = ::onNavigateToHome, - onCloseMyProfile = ::onCloseMyProfile, - onNavigateCreateProfile = ::onNavigateToCreateProfile + onCloseMyProfile = { onPopBackstackUpTo(HOME_ROUTE) }, + onNavigateOnBoarding = ::onNavigateOnBoarding ) homeScreen( onNavigateToMatching = ::onNavigateToMatching, - onNavigateToMyProfile = ::onNavigateToMyProfile + onNavigateToMyProfile = ::onNavigateToMyProfile, + onNavigateToCollection = ::navigateToCollection ) matchingScreen(onClose = { popBackStack(HOME_ROUTE, false) }) onBoardingScreen(onNavigateToCreateProfile = ::navigateToCreateProfile) + collectionScreen(onNavigateToHome = ::onNavigateToHome) } } } @@ -36,13 +41,20 @@ fun FunchNavHost(hasProfile: Boolean, navController: NavHostController = remembe private fun NavController.onNavigateToCreateProfile() = navigateToCreateProfile(navOptions { popUpTo(graph.id) { inclusive = true } }) -private fun NavController.onNavigateToMyProfile() = navigateToMyProfile(singleTopNavOptions) +private fun NavController.onNavigateOnBoarding() = navigateToOnBoarding { + launchSingleTop = true + popUpTo(HOME_ROUTE) { inclusive = true } +} + +private fun NavController.onNavigateToMyProfile() = navigateToMyProfile(singleTopPopUpTo()) + +private fun NavController.onNavigateToMatching(route: String) = navigateToMatching(route, singleTopPopUpTo()) -private fun NavController.onNavigateToMatching(route: String) = navigateToMatching(route, singleTopNavOptions) +private fun NavController.onPopBackstackUpTo(route: String) = popBackStack(route = route, inclusive = false) -private val singleTopNavOptions = navOptions { +private fun singleTopPopUpTo(route: String = HOME_ROUTE) = navOptions { launchSingleTop = true - popUpTo(HOME_ROUTE) + popUpTo(route) } private fun determineStartDestination(hasProfile: Boolean): String { diff --git a/app/src/main/java/com/moya/funch/splash/SplashScreen.kt b/app/src/main/java/com/moya/funch/splash/SplashScreen.kt index 4b096ce9..f9bdfb0d 100644 --- a/app/src/main/java/com/moya/funch/splash/SplashScreen.kt +++ b/app/src/main/java/com/moya/funch/splash/SplashScreen.kt @@ -2,7 +2,6 @@ package com.moya.funch.splash import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -19,7 +18,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.airbnb.lottie.compose.LottieAnimation import com.airbnb.lottie.compose.LottieCompositionSpec -import com.airbnb.lottie.compose.LottieConstants import com.airbnb.lottie.compose.rememberLottieComposition import com.moya.funch.R import com.moya.funch.theme.FunchTheme @@ -42,28 +40,21 @@ fun LoadingScreen() { Surface( color = FunchTheme.colors.background ) { - Column( + Box( modifier = Modifier - .fillMaxSize() + .fillMaxSize(), + contentAlignment = Alignment.Center ) { LottieAnimation( - composition = splashIcon, - iterations = LottieConstants.IterateForever + composition = splashBackground, + iterations = 1 ) LottieAnimation( - composition = splashBackground, - iterations = LottieConstants.IterateForever + composition = splashIcon, + iterations = 1 ) } - Box( - modifier = Modifier - .fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Image(painter = painterResource(id = R.drawable.ic_splash_logo), contentDescription = "Splash Logo") - } - Box( modifier = Modifier .fillMaxSize(), diff --git a/app/src/main/res/raw/funch_splash_icon_lottie.json b/app/src/main/res/raw/funch_splash_icon_lottie.json index a24e0315..0150295d 100644 --- a/app/src/main/res/raw/funch_splash_icon_lottie.json +++ b/app/src/main/res/raw/funch_splash_icon_lottie.json @@ -1 +1 @@ -{"nm":"Flow 2","ddd":0,"h":350,"w":350,"meta":{"g":"LottieFiles Figma v51"},"layers":[{"ty":4,"nm":"boom","sr":1,"st":0,"op":46.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0.63,0.5],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0.63,0.5],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[80.36,67.99],"t":27},{"s":[65.66,55.56],"t":45}]},"s":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[100,100],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[100,100],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[100,100],"t":27},{"s":[100,100],"t":45}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[204.63,175.5],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[204.63,175.5],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[207.19,174.5],"t":27},{"s":[207.19,174.5],"t":45}]},"r":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[-5.14],"t":27},{"s":[-5.14],"t":45}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[100],"t":27},{"s":[100],"t":45}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[-0.04,-0.02],[0,0],[0,0],[-0.03,-0.03],[0,0],[0,0],[0,-0.04],[0,0],[0,0],[0.04,-0.03],[0,0],[0,0],[0.05,0.01],[0,0],[0,0],[0.03,0.02],[0,0],[0,0],[0.01,0.04],[0,0],[0,0],[-0.03,0.03]],"o":[[0,0],[0,0],[0,0],[-0.03,-0.04],[0,0],[0,0],[0,-0.04],[0,0],[0,0],[0.03,-0.02],[0,0],[0,0],[0.05,0],[0,0],[0,0],[0.04,0.03],[0,0],[0,0],[0,0.03],[0,0],[0,0],[-0.02,0.03],[0,0],[0,0],[-0.04,0],[0,0]],"v":[[0.18,0.52],[0.18,0.52],[0,0.49],[0.22,0.47],[0.22,0.36],[0.31,0.33],[0.31,0.27],[0.43,0.17],[0.59,0],[0.85,0.1],[1.05,0.17],[1.12,0.21],[1.15,0.23],[1.09,0.49],[1.25,0.52],[1.12,0.58],[1.11,0.73],[1.15,0.87],[1.05,0.76],[0.94,0.83],[0.77,0.87],[0.59,0.83],[0.59,0.99],[0.22,0.88],[0.09,0.49],[0.18,0.52]]}],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[-0.04,-0.02],[0,0],[0,0],[-0.03,-0.03],[0,0],[0,0],[0,-0.04],[0,0],[0,0],[0.04,-0.03],[0,0],[0,0],[0.05,0.01],[0,0],[0,0],[0.03,0.02],[0,0],[0,0],[0.01,0.04],[0,0],[0,0],[-0.03,0.03]],"o":[[0,0],[0,0],[0,0],[-0.03,-0.04],[0,0],[0,0],[0,-0.04],[0,0],[0,0],[0.03,-0.02],[0,0],[0,0],[0.05,0],[0,0],[0,0],[0.04,0.03],[0,0],[0,0],[0,0.03],[0,0],[0,0],[-0.02,0.03],[0,0],[0,0],[-0.04,0],[0,0]],"v":[[0.18,0.52],[0.18,0.52],[0,0.49],[0.22,0.47],[0.22,0.36],[0.31,0.33],[0.31,0.27],[0.43,0.17],[0.59,0],[0.85,0.1],[1.05,0.17],[1.12,0.21],[1.15,0.23],[1.09,0.49],[1.25,0.52],[1.12,0.58],[1.11,0.73],[1.15,0.87],[1.05,0.76],[0.94,0.83],[0.77,0.87],[0.59,0.83],[0.59,0.99],[0.22,0.88],[0.09,0.49],[0.18,0.52]]}],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[-3.04,-1],[0,0],[0,0],[-2.12,-2.13],[0,0],[0,0],[0.33,-2.68],[0,0],[0,0],[2.58,-1.94],[0,0],[0,0],[3.53,0.36],[0,0],[0,0],[2.03,1.16],[0,0],[0,0],[0.52,2.65],[0,0],[0,0],[-2.48,1.97],[0,0]],"o":[[0,0],[0,0],[-1.96,-2.52],[0,0],[0,0],[-0.2,-2.98],[0,0],[0,0],[2.35,-1.36],[0,0],[0,0],[3.24,-0.19],[0,0],[0,0],[3.1,1.71],[0,0],[0,0],[-0.29,2.3],[0,0],[0,0],[-1.76,2.07],[0,0],[0,0],[-3.17,0.13],[0,0],[0,0]],"v":[[1.18,88.89],[29.27,66.47],[12.9,45.22],[16.53,40.18],[35.87,46.55],[33.16,3.43],[38.74,0.98],[71.35,33.77],[108.36,12.13],[113.26,15.34],[109.15,47.58],[138.55,45.87],[140.7,51.69],[118.36,68.28],[159.03,90.57],[157.1,96.62],[111.04,91.83],[108.39,112.89],[103.53,115.28],[84.91,104.74],[58.97,134.85],[53.28,133.36],[45.21,92.64],[3.43,94.55],[1.24,88.79],[1.18,88.89]]}],"t":27},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[-2.48,-0.82],[0,0],[0,0],[-1.74,-1.74],[0,0],[0,0],[0.27,-2.19],[0,0],[0,0],[2.11,-1.59],[0,0],[0,0],[2.88,0.29],[0,0],[0,0],[1.66,0.95],[0,0],[0,0],[0.43,2.17],[0,0],[0,0],[-2.03,1.61],[0,0]],"o":[[0,0],[0,0],[-1.6,-2.06],[0,0],[0,0],[-0.16,-2.43],[0,0],[0,0],[1.92,-1.11],[0,0],[0,0],[2.64,-0.16],[0,0],[0,0],[2.54,1.4],[0,0],[0,0],[-0.24,1.88],[0,0],[0,0],[-1.44,1.69],[0,0],[0,0],[-2.59,0.11],[0,0],[0,0]],"v":[[0.96,72.63],[23.92,54.32],[10.54,36.95],[13.51,32.83],[29.31,38.04],[27.09,2.81],[31.66,0.8],[58.3,27.6],[88.54,9.92],[92.55,12.53],[89.19,38.88],[113.21,37.48],[114.97,42.24],[96.71,55.8],[129.95,74.01],[128.37,78.95],[90.73,75.04],[88.57,92.24],[84.59,94.2],[69.38,85.58],[48.18,110.19],[43.54,108.97],[36.94,75.7],[2.8,77.26],[1.01,72.55],[0.96,72.63]]}],"t":45}]}},{"ty":"gf","bm":0,"hd":false,"nm":"","e":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[-1.13,2.04],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[-1.13,2.04],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[80.35679626464844,135.98800659179688],"t":27},{"s":[65.6614990234375,111.11900329589844],"t":45}]},"g":{"p":2,"k":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0,1,0.9375764685892591,0.3721242803358564,1,0.9686666685366163,0.8314117747568617,0.3686666744970808],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[0,1,0.9375764685892591,0.3721242803358564,1,0.9686666685366163,0.8314117747568617,0.3686666744970808],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[0,1,0.9372941213869581,0.37258824289078807,1,0.9686666685366163,0.8314117747568617,0.3686666744970808],"t":27},{"s":[0,1,0.9372941213869581,0.37258824289078807,1,0.9686666685366163,0.8314117747568617,0.3686666744970808],"t":45}]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"s":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[-1.13,0],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[-1.13,0],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[80.35679626464844,0],"t":27},{"s":[65.6614990234375,0],"t":45}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[100],"t":0},{"o":{"x":0.65,"y":0},"i":{"x":0.35,"y":0},"s":[100],"t":9},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":0.95},"s":[100],"t":27},{"s":[100],"t":45}]}}],"ind":1}],"v":"5.7.0","fr":60,"op":45.06,"ip":0,"assets":[]} +{"nm":"Flow 1","ddd":0,"h":41,"w":160,"meta":{"g":"LottieFiles Figma v51"},"layers":[{"ty":4,"nm":"Fblack","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.36,18.09],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.36,18.09],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[12.36,18.09],"t":12},{"s":[12.36,18.09],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.25,19.55],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.25,19.55],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[32.25,19.55],"t":12},{"s":[28.25,19.55],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[-1.12,0],[0,0],[0.09,1.18],[0,0],[0,0],[-1.87,0.99],[-0.73,1.19],[-0.09,0.18],[1.83,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,3.61],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0]],"o":[[0,0],[0,1.12],[0,0],[1.18,0],[0,0],[0,0],[1.88,0.98],[1.23,-0.65],[0.11,-0.17],[0.84,-1.64],[0,0],[0,0],[-1.37,-1.17],[0.82,1.36],[0,0],[3.59,0.31],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,0]],"v":[[0,2.04],[0,34.14],[2.03,36.18],[6.81,36.18],[8.83,33.98],[7.8,21.45],[10.3,22.71],[16.31,22.79],[19.32,19.97],[19.61,19.45],[17.38,15.87],[7.35,15.87],[6.71,8.06],[3.94,4.78],[8.43,7.89],[18.06,8.72],[24.73,2.58],[24.73,2.03],[22.7,0],[2.03,0],[0,2.03],[0,2.04]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[-1.12,0],[0,0],[0.09,1.18],[0,0],[0,0],[-1.87,0.99],[-0.73,1.19],[-0.09,0.18],[1.83,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,3.61],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0]],"o":[[0,0],[0,1.12],[0,0],[1.18,0],[0,0],[0,0],[1.88,0.98],[1.23,-0.65],[0.11,-0.17],[0.84,-1.64],[0,0],[0,0],[-1.37,-1.17],[0.82,1.36],[0,0],[3.59,0.31],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,0]],"v":[[0,2.04],[0,34.14],[2.03,36.18],[6.81,36.18],[8.83,33.98],[7.8,21.45],[10.3,22.71],[16.31,22.79],[19.32,19.97],[19.61,19.45],[17.38,15.87],[7.35,15.87],[6.71,8.06],[3.94,4.78],[8.43,7.89],[18.06,8.72],[24.73,2.58],[24.73,2.03],[22.7,0],[2.03,0],[0,2.03],[0,2.04]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0,0],[-1.12,0],[0,0],[0.09,1.18],[0,0],[0,0],[-1.87,0.99],[-0.73,1.19],[-0.09,0.18],[1.83,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,3.61],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0]],"o":[[0,0],[0,1.12],[0,0],[1.18,0],[0,0],[0,0],[1.88,0.98],[1.23,-0.65],[0.11,-0.17],[0.84,-1.64],[0,0],[0,0],[-1.37,-1.17],[0.82,1.36],[0,0],[3.59,0.31],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,0]],"v":[[0,2.04],[0,34.14],[2.03,36.18],[6.81,36.18],[8.83,33.98],[7.8,21.45],[10.3,22.71],[16.31,22.79],[19.32,19.97],[19.61,19.45],[17.38,15.87],[7.35,15.87],[6.71,8.06],[3.94,4.78],[8.43,7.89],[18.06,8.72],[24.73,2.58],[24.73,2.03],[22.7,0],[2.03,0],[0,2.03],[0,2.04]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,0],[-1.12,0],[0,0],[0.09,1.18],[0,0],[0,0],[-1.87,0.99],[-0.73,1.19],[-0.09,0.18],[1.83,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,3.61],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0]],"o":[[0,0],[0,1.12],[0,0],[1.18,0],[0,0],[0,0],[1.88,0.98],[1.23,-0.65],[0.11,-0.17],[0.84,-1.64],[0,0],[0,0],[-1.37,-1.17],[0.82,1.36],[0,0],[3.59,0.31],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,0]],"v":[[0,2.04],[0,34.14],[2.03,36.18],[6.81,36.18],[8.83,33.98],[7.8,21.45],[10.3,22.71],[16.31,22.79],[19.32,19.97],[19.61,19.45],[17.38,15.87],[7.35,15.87],[6.71,8.06],[3.94,4.78],[8.43,7.89],[18.06,8.72],[24.73,2.58],[24.73,2.03],[22.7,0],[2.03,0],[0,2.03],[0,2.04]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0,0,0],"t":12},{"s":[0,0,0],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":1},{"ty":4,"nm":"Ublack","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.78,12.92],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.78,12.92],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[12.78,12.92],"t":12},{"s":[12.78,12.92],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35.79,25.53],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[40.66,25.53],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[54.79,25.53],"t":12},{"s":[49.79,25.53],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[3.31,0],[0,3.98],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0],[-5.43,0],[0,0],[0.89,-1.27],[0.71,-1.02],[-1.13,0.12],[0,0],[0,1.04],[0,0],[3.07,0],[0,0],[0,0]],"o":[[0,0],[0,4.75],[-2.92,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[-0.03,7.22],[6.31,0],[0,0],[-0.7,1],[-0.65,0.93],[0,0],[1.03,-0.11],[0,0],[0,-3.08],[0,0],[0,0],[0,0]],"v":[[17.76,0.01],[17.76,11.74],[12.42,19.3],[7.82,12.95],[7.82,2.04],[5.79,0.01],[2.06,0.01],[0.03,2.03],[0,14.16],[8.84,25.85],[19.47,18.34],[19.03,20.53],[16.79,23.72],[18.01,25.8],[23.74,25.21],[25.56,23.19],[25.56,5.58],[20,0],[17.75,0],[17.76,0.01]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[3.31,0],[0,3.98],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0],[-5.43,0],[0,0],[0.89,-1.27],[0.71,-1.02],[-1.13,0.12],[0,0],[0,1.04],[0,0],[3.07,0],[0,0],[0,0]],"o":[[0,0],[0,4.75],[-2.92,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[-0.03,7.22],[6.31,0],[0,0],[-0.7,1],[-0.65,0.93],[0,0],[1.03,-0.11],[0,0],[0,-3.08],[0,0],[0,0],[0,0]],"v":[[17.76,0.01],[17.76,11.74],[12.42,19.3],[7.82,12.95],[7.82,2.04],[5.79,0.01],[2.06,0.01],[0.03,2.03],[0,14.16],[8.84,25.85],[19.47,18.34],[19.03,20.53],[16.79,23.72],[18.01,25.8],[23.74,25.21],[25.56,23.19],[25.56,5.58],[20,0],[17.75,0],[17.76,0.01]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0,0],[3.31,0],[0,3.98],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0],[-5.43,0],[0,0],[0.89,-1.27],[0.71,-1.02],[-1.13,0.12],[0,0],[0,1.04],[0,0],[3.07,0],[0,0],[0,0]],"o":[[0,0],[0,4.75],[-2.92,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[-0.03,7.22],[6.31,0],[0,0],[-0.7,1],[-0.65,0.93],[0,0],[1.03,-0.11],[0,0],[0,-3.08],[0,0],[0,0],[0,0]],"v":[[17.76,0.01],[17.76,11.74],[12.42,19.3],[7.82,12.95],[7.82,2.04],[5.79,0.01],[2.06,0.01],[0.03,2.03],[0,14.16],[8.84,25.85],[19.47,18.34],[19.03,20.53],[16.79,23.72],[18.01,25.8],[23.74,25.21],[25.56,23.19],[25.56,5.58],[20,0],[17.75,0],[17.76,0.01]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,0],[3.31,0],[0,3.98],[0,0],[1.12,0],[0,0],[0,-1.12],[0,0],[-5.43,0],[0,0],[0.89,-1.27],[0.71,-1.02],[-1.13,0.12],[0,0],[0,1.04],[0,0],[3.07,0],[0,0],[0,0]],"o":[[0,0],[0,4.75],[-2.92,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[-0.03,7.22],[6.31,0],[0,0],[-0.7,1],[-0.65,0.93],[0,0],[1.03,-0.11],[0,0],[0,-3.08],[0,0],[0,0],[0,0]],"v":[[17.76,0.01],[17.76,11.74],[12.42,19.3],[7.82,12.95],[7.82,2.04],[5.79,0.01],[2.06,0.01],[0.03,2.03],[0,14.16],[8.84,25.85],[19.47,18.34],[19.03,20.53],[16.79,23.72],[18.01,25.8],[23.74,25.21],[25.56,23.19],[25.56,5.58],[20,0],[17.75,0],[17.76,0.01]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0,0,0],"t":12},{"s":[0,0,0],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":2},{"ty":4,"nm":"Cblack","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13.25,13.83],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13.25,13.83],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[13.25,13.83],"t":12},{"s":[13.25,13.83],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[119.14,25.27],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[114.14,25.27],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100.33,25.27],"t":12},{"s":[105.33,25.27],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[-7.73,0],[-1.54,-4.98],[1.11,-0.28],[0,0],[0.38,0.95],[1.97,0],[0,-4.09],[-3.77,0],[-0.92,2.72],[-1.01,-0.25],[0,0],[0.3,-1.09],[6.38,0],[-0.04,8.37],[0,0]],"o":[[0,-8.37],[5.7,0],[0.34,1.1],[0,0],[-0.98,0.25],[-0.75,-1.87],[-3.41,0],[0,4.09],[2.71,0],[0.33,-0.99],[0,0],[1.1,0.27],[-1.59,5.86],[-8.22,0],[0,0],[0,0]],"v":[[0,13.86],[12.89,0],[24.49,8.13],[23.04,10.67],[19.78,11.5],[17.4,10.29],[13.21,7.3],[7.61,13.85],[13.66,20.41],[19.38,16.08],[21.79,14.8],[24.95,15.57],[26.44,18.05],[13.57,27.66],[0.01,13.85],[0,13.86]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[-7.73,0],[-1.54,-4.98],[1.11,-0.28],[0,0],[0.38,0.95],[1.97,0],[0,-4.09],[-3.77,0],[-0.92,2.72],[-1.01,-0.25],[0,0],[0.3,-1.09],[6.38,0],[-0.04,8.37],[0,0]],"o":[[0,-8.37],[5.7,0],[0.34,1.1],[0,0],[-0.98,0.25],[-0.75,-1.87],[-3.41,0],[0,4.09],[2.71,0],[0.33,-0.99],[0,0],[1.1,0.27],[-1.59,5.86],[-8.22,0],[0,0],[0,0]],"v":[[0,13.86],[12.89,0],[24.49,8.13],[23.04,10.67],[19.78,11.5],[17.4,10.29],[13.21,7.3],[7.61,13.85],[13.66,20.41],[19.38,16.08],[21.79,14.8],[24.95,15.57],[26.44,18.05],[13.57,27.66],[0.01,13.85],[0,13.86]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[-7.73,0],[-1.54,-4.98],[1.11,-0.28],[0,0],[0.38,0.95],[1.97,0],[0,-4.09],[-3.77,0],[-0.92,2.72],[-1.01,-0.25],[0,0],[0.3,-1.09],[6.38,0],[-0.04,8.37],[0,0]],"o":[[0,-8.37],[5.7,0],[0.34,1.1],[0,0],[-0.98,0.25],[-0.75,-1.87],[-3.41,0],[0,4.09],[2.71,0],[0.33,-0.99],[0,0],[1.1,0.27],[-1.59,5.86],[-8.22,0],[0,0],[0,0]],"v":[[0,13.86],[12.89,0],[24.49,8.13],[23.04,10.67],[19.78,11.5],[17.4,10.29],[13.21,7.3],[7.61,13.85],[13.66,20.41],[19.38,16.08],[21.79,14.8],[24.95,15.57],[26.44,18.05],[13.57,27.66],[0.01,13.85],[0,13.86]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[-7.73,0],[-1.54,-4.98],[1.11,-0.28],[0,0],[0.38,0.95],[1.97,0],[0,-4.09],[-3.77,0],[-0.92,2.72],[-1.01,-0.25],[0,0],[0.3,-1.09],[6.38,0],[-0.04,8.37],[0,0]],"o":[[0,-8.37],[5.7,0],[0.34,1.1],[0,0],[-0.98,0.25],[-0.75,-1.87],[-3.41,0],[0,4.09],[2.71,0],[0.33,-0.99],[0,0],[1.1,0.27],[-1.59,5.86],[-8.22,0],[0,0],[0,0]],"v":[[0,13.86],[12.89,0],[24.49,8.13],[23.04,10.67],[19.78,11.5],[17.4,10.29],[13.21,7.3],[7.61,13.85],[13.66,20.41],[19.38,16.08],[21.79,14.8],[24.95,15.57],[26.44,18.05],[13.57,27.66],[0.01,13.85],[0,13.86]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0,0,0],"t":12},{"s":[0,0,0],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":3},{"ty":4,"nm":"Nblack","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.78,12.92],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.78,12.92],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[12.78,12.92],"t":12},{"s":[12.78,12.92],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[64.04,24.71],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[75.78,24.71],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[81.78,24.71],"t":12},{"s":[78.78,24.71],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[1.59,-4.17],[0.12,-1.23],[0,0],[-1.4,2.83],[1.3,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[-3.31,0],[0,-3.98],[0,0],[0,0],[-0.01,3.32],[0,0],[5.43,0]],"o":[[-4.28,0],[0,0],[0,0],[0,0],[0.58,-1.17],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[1.12,0],[0,0],[0,-4.75],[2.92,0],[0,0],[0,0],[3.31,0],[0,0],[0.03,-7.22],[0,0]],"v":[[16.73,0],[7.62,6.88],[6.75,10.17],[6.63,8.7],[8.32,3.35],[6.76,0.82],[2.03,0.82],[0,2.85],[0,23.81],[2.03,25.84],[5.79,25.84],[7.81,23.81],[7.81,14.11],[13.15,6.54],[17.75,12.89],[17.75,25.84],[19.54,25.84],[25.55,19.83],[25.57,11.68],[16.73,0]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[1.59,-4.17],[0.12,-1.23],[0,0],[-1.4,2.83],[1.3,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[-3.31,0],[0,-3.98],[0,0],[0,0],[-0.01,3.32],[0,0],[5.43,0]],"o":[[-4.28,0],[0,0],[0,0],[0,0],[0.58,-1.17],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[1.12,0],[0,0],[0,-4.75],[2.92,0],[0,0],[0,0],[3.31,0],[0,0],[0.03,-7.22],[0,0]],"v":[[16.73,0],[7.62,6.88],[6.75,10.17],[6.63,8.7],[8.32,3.35],[6.76,0.82],[2.03,0.82],[0,2.85],[0,23.81],[2.03,25.84],[5.79,25.84],[7.81,23.81],[7.81,14.11],[13.15,6.54],[17.75,12.89],[17.75,25.84],[19.54,25.84],[25.55,19.83],[25.57,11.68],[16.73,0]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[1.59,-4.17],[0.12,-1.23],[0,0],[-1.4,2.83],[1.3,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[-3.31,0],[0,-3.98],[0,0],[0,0],[-0.01,3.32],[0,0],[5.43,0]],"o":[[-4.28,0],[0,0],[0,0],[0,0],[0.58,-1.17],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[1.12,0],[0,0],[0,-4.75],[2.92,0],[0,0],[0,0],[3.31,0],[0,0],[0.03,-7.22],[0,0]],"v":[[16.73,0],[7.62,6.88],[6.75,10.17],[6.63,8.7],[8.32,3.35],[6.76,0.82],[2.03,0.82],[0,2.85],[0,23.81],[2.03,25.84],[5.79,25.84],[7.81,23.81],[7.81,14.11],[13.15,6.54],[17.75,12.89],[17.75,25.84],[19.54,25.84],[25.55,19.83],[25.57,11.68],[16.73,0]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[1.59,-4.17],[0.12,-1.23],[0,0],[-1.4,2.83],[1.3,0],[0,0],[0,-1.12],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[-3.31,0],[0,-3.98],[0,0],[0,0],[-0.01,3.32],[0,0],[5.43,0]],"o":[[-4.28,0],[0,0],[0,0],[0,0],[0.58,-1.17],[0,0],[-1.12,0],[0,0],[0,1.12],[0,0],[1.12,0],[0,0],[0,-4.75],[2.92,0],[0,0],[0,0],[3.31,0],[0,0],[0.03,-7.22],[0,0]],"v":[[16.73,0],[7.62,6.88],[6.75,10.17],[6.63,8.7],[8.32,3.35],[6.76,0.82],[2.03,0.82],[0,2.85],[0,23.81],[2.03,25.84],[5.79,25.84],[7.81,23.81],[7.81,14.11],[13.15,6.54],[17.75,12.89],[17.75,25.84],[19.54,25.84],[25.55,19.83],[25.57,11.68],[16.73,0]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0,0,0],"t":12},{"s":[0,0,0],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":4},{"ty":4,"nm":"Fwhite","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.25,19.98],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.25,19.98],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[14.25,19.98],"t":12},{"s":[14.25,19.98],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.25,19.55],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.25,19.55],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[32.25,19.55],"t":12},{"s":[28.25,19.55],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[4.42,0],[0.23,0.02],[0,0],[0,0],[0,0],[-0.81,-1.33],[0.69,-1.35],[0.13,-0.21],[1.54,-0.81],[1.32,0],[1.1,0.49],[0,0],[0.74,-0.8],[1.1,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-2.17],[0,0],[2.16,0],[0,0],[0,4.44],[-0.23,0],[0,0],[0,0],[0,0],[1.54,0],[0.79,1.3],[-0.11,0.22],[-0.9,1.47],[-1.13,0.6],[-1.19,0],[0,0],[0.09,1.09],[-0.74,0.8],[0,0],[0,0],[0,0]],"v":[[3.92,39.96],[0,36.03],[0,3.93],[3.92,0],[24.58,0],[28.5,3.93],[28.5,4.48],[20.48,12.53],[19.78,12.5],[10.63,11.7],[10.97,15.86],[19.26,15.86],[23.02,17.98],[23.18,22.2],[22.81,22.85],[19.07,26.35],[15.33,27.27],[11.84,26.52],[12.59,35.7],[11.57,38.68],[8.69,39.95],[3.92,39.95],[3.92,39.96]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[4.42,0],[0.23,0.02],[0,0],[0,0],[0,0],[-0.81,-1.33],[0.69,-1.35],[0.13,-0.21],[1.54,-0.81],[1.32,0],[1.1,0.49],[0,0],[0.74,-0.8],[1.1,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-2.17],[0,0],[2.16,0],[0,0],[0,4.44],[-0.23,0],[0,0],[0,0],[0,0],[1.54,0],[0.79,1.3],[-0.11,0.22],[-0.9,1.47],[-1.13,0.6],[-1.19,0],[0,0],[0.09,1.09],[-0.74,0.8],[0,0],[0,0],[0,0]],"v":[[3.92,39.96],[0,36.03],[0,3.93],[3.92,0],[24.58,0],[28.5,3.93],[28.5,4.48],[20.48,12.53],[19.78,12.5],[10.63,11.7],[10.97,15.86],[19.26,15.86],[23.02,17.98],[23.18,22.2],[22.81,22.85],[19.07,26.35],[15.33,27.27],[11.84,26.52],[12.59,35.7],[11.57,38.68],[8.69,39.95],[3.92,39.95],[3.92,39.96]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[4.42,0],[0.23,0.02],[0,0],[0,0],[0,0],[-0.81,-1.33],[0.69,-1.35],[0.13,-0.21],[1.54,-0.81],[1.32,0],[1.1,0.49],[0,0],[0.74,-0.8],[1.1,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-2.17],[0,0],[2.16,0],[0,0],[0,4.44],[-0.23,0],[0,0],[0,0],[0,0],[1.54,0],[0.79,1.3],[-0.11,0.22],[-0.9,1.47],[-1.13,0.6],[-1.19,0],[0,0],[0.09,1.09],[-0.74,0.8],[0,0],[0,0],[0,0]],"v":[[3.92,39.96],[0,36.03],[0,3.93],[3.92,0],[24.58,0],[28.5,3.93],[28.5,4.48],[20.48,12.53],[19.78,12.5],[10.63,11.7],[10.97,15.86],[19.26,15.86],[23.02,17.98],[23.18,22.2],[22.81,22.85],[19.07,26.35],[15.33,27.27],[11.84,26.52],[12.59,35.7],[11.57,38.68],[8.69,39.95],[3.92,39.95],[3.92,39.96]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[4.42,0],[0.23,0.02],[0,0],[0,0],[0,0],[-0.81,-1.33],[0.69,-1.35],[0.13,-0.21],[1.54,-0.81],[1.32,0],[1.1,0.49],[0,0],[0.74,-0.8],[1.1,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-2.17],[0,0],[2.16,0],[0,0],[0,4.44],[-0.23,0],[0,0],[0,0],[0,0],[1.54,0],[0.79,1.3],[-0.11,0.22],[-0.9,1.47],[-1.13,0.6],[-1.19,0],[0,0],[0.09,1.09],[-0.74,0.8],[0,0],[0,0],[0,0]],"v":[[3.92,39.96],[0,36.03],[0,3.93],[3.92,0],[24.58,0],[28.5,3.93],[28.5,4.48],[20.48,12.53],[19.78,12.5],[10.63,11.7],[10.97,15.86],[19.26,15.86],[23.02,17.98],[23.18,22.2],[22.81,22.85],[19.07,26.35],[15.33,27.27],[11.84,26.52],[12.59,35.7],[11.57,38.68],[8.69,39.95],[3.92,39.95],[3.92,39.96]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[1,1,1],"t":12},{"s":[1,1,1],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":5},{"ty":4,"nm":"Uwhite","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.67,14.82],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.67,14.82],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[14.67,14.82],"t":12},{"s":[14.67,14.82],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35.8,25.54],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[40.67,25.54],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[54.8,25.54],"t":12},{"s":[49.8,25.54],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[1.86,1.87],[-0.03,4.6],[0,0],[-2.15,0],[0,0],[0,-2.17],[0,0],[-2.24,0],[0,1.7],[0,0],[0,0],[0,-4.12],[0,0],[2,-0.21],[0,0],[0.11,0],[0.55,1.07],[0.03,0.06],[2.31,0],[0,0]],"o":[[-2.78,0],[-2.41,-2.42],[0,0],[0,-2.16],[0,0],[2.16,0],[0,0],[0,2.03],[3.11,0],[0,0],[0,0],[4.11,0],[0,0],[0,2.02],[0,0],[-0.11,0.01],[-1.2,0],[-0.03,-0.05],[-1.74,1.12],[0,0],[0,0]],"v":[[10.73,29.63],[3.65,26.78],[0,16.05],[0.03,3.92],[3.95,0],[7.68,0],[11.6,3.93],[11.6,14.84],[14.31,19.3],[17.76,13.63],[17.76,0],[21.9,0],[29.35,7.47],[29.35,25.08],[25.83,28.99],[20.1,29.58],[19.76,29.6],[16.92,27.87],[16.84,27.71],[10.74,29.64],[10.73,29.63]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[1.86,1.87],[-0.03,4.6],[0,0],[-2.15,0],[0,0],[0,-2.17],[0,0],[-2.24,0],[0,1.7],[0,0],[0,0],[0,-4.12],[0,0],[2,-0.21],[0,0],[0.11,0],[0.55,1.07],[0.03,0.06],[2.31,0],[0,0]],"o":[[-2.78,0],[-2.41,-2.42],[0,0],[0,-2.16],[0,0],[2.16,0],[0,0],[0,2.03],[3.11,0],[0,0],[0,0],[4.11,0],[0,0],[0,2.02],[0,0],[-0.11,0.01],[-1.2,0],[-0.03,-0.05],[-1.74,1.12],[0,0],[0,0]],"v":[[10.73,29.63],[3.65,26.78],[0,16.05],[0.03,3.92],[3.95,0],[7.68,0],[11.6,3.93],[11.6,14.84],[14.31,19.3],[17.76,13.63],[17.76,0],[21.9,0],[29.35,7.47],[29.35,25.08],[25.83,28.99],[20.1,29.58],[19.76,29.6],[16.92,27.87],[16.84,27.71],[10.74,29.64],[10.73,29.63]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[1.86,1.87],[-0.03,4.6],[0,0],[-2.15,0],[0,0],[0,-2.17],[0,0],[-2.24,0],[0,1.7],[0,0],[0,0],[0,-4.12],[0,0],[2,-0.21],[0,0],[0.11,0],[0.55,1.07],[0.03,0.06],[2.31,0],[0,0]],"o":[[-2.78,0],[-2.41,-2.42],[0,0],[0,-2.16],[0,0],[2.16,0],[0,0],[0,2.03],[3.11,0],[0,0],[0,0],[4.11,0],[0,0],[0,2.02],[0,0],[-0.11,0.01],[-1.2,0],[-0.03,-0.05],[-1.74,1.12],[0,0],[0,0]],"v":[[10.73,29.63],[3.65,26.78],[0,16.05],[0.03,3.92],[3.95,0],[7.68,0],[11.6,3.93],[11.6,14.84],[14.31,19.3],[17.76,13.63],[17.76,0],[21.9,0],[29.35,7.47],[29.35,25.08],[25.83,28.99],[20.1,29.58],[19.76,29.6],[16.92,27.87],[16.84,27.71],[10.74,29.64],[10.73,29.63]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[1.86,1.87],[-0.03,4.6],[0,0],[-2.15,0],[0,0],[0,-2.17],[0,0],[-2.24,0],[0,1.7],[0,0],[0,0],[0,-4.12],[0,0],[2,-0.21],[0,0],[0.11,0],[0.55,1.07],[0.03,0.06],[2.31,0],[0,0]],"o":[[-2.78,0],[-2.41,-2.42],[0,0],[0,-2.16],[0,0],[2.16,0],[0,0],[0,2.03],[3.11,0],[0,0],[0,0],[4.11,0],[0,0],[0,2.02],[0,0],[-0.11,0.01],[-1.2,0],[-0.03,-0.05],[-1.74,1.12],[0,0],[0,0]],"v":[[10.73,29.63],[3.65,26.78],[0,16.05],[0.03,3.92],[3.95,0],[7.68,0],[11.6,3.93],[11.6,14.84],[14.31,19.3],[17.76,13.63],[17.76,0],[21.9,0],[29.35,7.47],[29.35,25.08],[25.83,28.99],[20.1,29.58],[19.76,29.6],[16.92,27.87],[16.84,27.71],[10.74,29.64],[10.73,29.63]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[1,1,1],"t":12},{"s":[1,1,1],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":6},{"ty":4,"nm":"Hblack","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.04,18.02],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[12.04,18.02],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[12.04,18.02],"t":12},{"s":[12.04,18.02],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[145.88,19.61],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[145.88,19.61],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[124.07,19.61],"t":12},{"s":[132.07,19.61],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0.21,-4.12],[0.16,-0.69],[0,0],[0,0],[-3.34,0],[0.04,-7.22],[0,0],[1.11,0],[0,0],[0,1.12],[0,0],[2.64,0],[0,-4.75],[0,0],[1.12,0],[0,0],[0,1.12],[0,0],[-1.17,0.23],[0,0]],"o":[[4.04,-0.78],[-0.09,1.73],[-1.83,7.68],[0,0],[1.96,-4.17],[6.55,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-3.98],[-3.08,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-1.19],[0,0],[0,0]],"v":[[2,0.12],[9.53,6.68],[9.16,10.62],[8.08,17.09],[8.12,17.09],[14.03,10.2],[24.08,21.88],[24.05,34.01],[22.02,36.04],[17.3,36.04],[15.27,34.01],[15.27,23.1],[12.04,16.74],[8.8,24.31],[8.8,34.01],[6.77,36.04],[2.03,36.04],[0,34.01],[0,2.57],[2.01,0.12],[2,0.12]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0.21,-4.12],[0.16,-0.69],[0,0],[0,0],[-3.34,0],[0.04,-7.22],[0,0],[1.11,0],[0,0],[0,1.12],[0,0],[2.64,0],[0,-4.75],[0,0],[1.12,0],[0,0],[0,1.12],[0,0],[-1.17,0.23],[0,0]],"o":[[4.04,-0.78],[-0.09,1.73],[-1.83,7.68],[0,0],[1.96,-4.17],[6.55,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-3.98],[-3.08,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-1.19],[0,0],[0,0]],"v":[[2,0.12],[9.53,6.68],[9.16,10.62],[8.08,17.09],[8.12,17.09],[14.03,10.2],[24.08,21.88],[24.05,34.01],[22.02,36.04],[17.3,36.04],[15.27,34.01],[15.27,23.1],[12.04,16.74],[8.8,24.31],[8.8,34.01],[6.77,36.04],[2.03,36.04],[0,34.01],[0,2.57],[2.01,0.12],[2,0.12]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0.21,-4.12],[0.16,-0.69],[0,0],[0,0],[-3.34,0],[0.04,-7.22],[0,0],[1.11,0],[0,0],[0,1.12],[0,0],[2.64,0],[0,-4.75],[0,0],[1.12,0],[0,0],[0,1.12],[0,0],[-1.17,0.23],[0,0]],"o":[[4.04,-0.78],[-0.09,1.73],[-1.83,7.68],[0,0],[1.96,-4.17],[6.55,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-3.98],[-3.08,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-1.19],[0,0],[0,0]],"v":[[2,0.12],[9.53,6.68],[9.16,10.62],[8.08,17.09],[8.12,17.09],[14.03,10.2],[24.08,21.88],[24.05,34.01],[22.02,36.04],[17.3,36.04],[15.27,34.01],[15.27,23.1],[12.04,16.74],[8.8,24.31],[8.8,34.01],[6.77,36.04],[2.03,36.04],[0,34.01],[0,2.57],[2.01,0.12],[2,0.12]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0.21,-4.12],[0.16,-0.69],[0,0],[0,0],[-3.34,0],[0.04,-7.22],[0,0],[1.11,0],[0,0],[0,1.12],[0,0],[2.64,0],[0,-4.75],[0,0],[1.12,0],[0,0],[0,1.12],[0,0],[-1.17,0.23],[0,0]],"o":[[4.04,-0.78],[-0.09,1.73],[-1.83,7.68],[0,0],[1.96,-4.17],[6.55,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-3.98],[-3.08,0],[0,0],[0,1.12],[0,0],[-1.12,0],[0,0],[0,-1.19],[0,0],[0,0]],"v":[[2,0.12],[9.53,6.68],[9.16,10.62],[8.08,17.09],[8.12,17.09],[14.03,10.2],[24.08,21.88],[24.05,34.01],[22.02,36.04],[17.3,36.04],[15.27,34.01],[15.27,23.1],[12.04,16.74],[8.8,24.31],[8.8,34.01],[6.77,36.04],[2.03,36.04],[0,34.01],[0,2.57],[2.01,0.12],[2,0.12]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0,0,0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0,0,0],"t":12},{"s":[0,0,0],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":7},{"ty":4,"nm":"Nwhite","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.67,14.82],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[14.67,14.82],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[14.67,14.82],"t":12},{"s":[14.67,14.82],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[64.04,24.71],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[75.67,24.71],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[81.67,24.71],"t":12},{"s":[78.67,24.71],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[2.24,0],[0,-1.7],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[-0.67,-1.02],[-2.61,0],[-1.85,-1.87],[0.03,-4.59],[0,0],[4.34,0],[0,0],[0,0]],"o":[[0,0],[0,-2.03],[-3.11,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[1.23,0],[1.95,-1.59],[2.78,0],[2.41,2.42],[0,0],[-0.01,4.36],[0,0],[0,0],[0,0]],"v":[[17.75,29.63],[17.75,14.8],[15.04,10.34],[11.59,16.01],[11.59,25.71],[7.68,29.63],[3.92,29.63],[0,25.71],[0,4.75],[3.92,0.83],[8.64,0.83],[11.68,2.46],[18.62,0],[25.7,2.85],[29.35,13.58],[29.33,21.73],[21.43,29.63],[17.75,29.63],[17.75,29.63]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[2.24,0],[0,-1.7],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[-0.67,-1.02],[-2.61,0],[-1.85,-1.87],[0.03,-4.59],[0,0],[4.34,0],[0,0],[0,0]],"o":[[0,0],[0,-2.03],[-3.11,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[1.23,0],[1.95,-1.59],[2.78,0],[2.41,2.42],[0,0],[-0.01,4.36],[0,0],[0,0],[0,0]],"v":[[17.75,29.63],[17.75,14.8],[15.04,10.34],[11.59,16.01],[11.59,25.71],[7.68,29.63],[3.92,29.63],[0,25.71],[0,4.75],[3.92,0.83],[8.64,0.83],[11.68,2.46],[18.62,0],[25.7,2.85],[29.35,13.58],[29.33,21.73],[21.43,29.63],[17.75,29.63],[17.75,29.63]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0,0],[2.24,0],[0,-1.7],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[-0.67,-1.02],[-2.61,0],[-1.85,-1.87],[0.03,-4.59],[0,0],[4.34,0],[0,0],[0,0]],"o":[[0,0],[0,-2.03],[-3.11,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[1.23,0],[1.95,-1.59],[2.78,0],[2.41,2.42],[0,0],[-0.01,4.36],[0,0],[0,0],[0,0]],"v":[[17.75,29.63],[17.75,14.8],[15.04,10.34],[11.59,16.01],[11.59,25.71],[7.68,29.63],[3.92,29.63],[0,25.71],[0,4.75],[3.92,0.83],[8.64,0.83],[11.68,2.46],[18.62,0],[25.7,2.85],[29.35,13.58],[29.33,21.73],[21.43,29.63],[17.75,29.63],[17.75,29.63]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,0],[2.24,0],[0,-1.7],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[-0.67,-1.02],[-2.61,0],[-1.85,-1.87],[0.03,-4.59],[0,0],[4.34,0],[0,0],[0,0]],"o":[[0,0],[0,-2.03],[-3.11,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.17],[0,0],[1.23,0],[1.95,-1.59],[2.78,0],[2.41,2.42],[0,0],[-0.01,4.36],[0,0],[0,0],[0,0]],"v":[[17.75,29.63],[17.75,14.8],[15.04,10.34],[11.59,16.01],[11.59,25.71],[7.68,29.63],[3.92,29.63],[0,25.71],[0,4.75],[3.92,0.83],[8.64,0.83],[11.68,2.46],[18.62,0],[25.7,2.85],[29.35,13.58],[29.33,21.73],[21.43,29.63],[17.75,29.63],[17.75,29.63]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[1,1,1],"t":12},{"s":[1,1,1],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":8},{"ty":4,"nm":"Cwhite","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[15.14,15.73],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[15.14,15.73],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[15.14,15.73],"t":12},{"s":[15.14,15.73],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[119.14,25.27],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[114.14,25.27],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100.33,25.27],"t":12},{"s":[105.33,25.27],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[2.78,2.8],[-0.02,4.63],[-8.84,0],[-1.8,-5.83],[0.53,-0.93],[1.04,-0.27],[0,0],[-0.09,-0.02],[0,0],[-0.54,-0.92],[0.28,-1.02],[7.21,0],[0,0]],"o":[[-4.53,0],[-2.81,-2.84],[0,-9.42],[6.47,0],[0.31,1.02],[-0.52,0.94],[0,0],[0.09,0.02],[0,0],[1.03,0.25],[0.54,0.92],[-1.85,6.79],[0,0],[0,0]],"v":[[15.45,31.46],[4.28,27.17],[0,15.75],[14.78,0],[28.18,9.46],[27.85,12.5],[25.39,14.39],[23.83,14.79],[24.11,14.85],[27.28,15.61],[29.74,17.44],[30.14,20.43],[15.45,31.45],[15.45,31.46]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[2.78,2.8],[-0.02,4.63],[-8.84,0],[-1.8,-5.83],[0.53,-0.93],[1.04,-0.27],[0,0],[-0.09,-0.02],[0,0],[-0.54,-0.92],[0.28,-1.02],[7.21,0],[0,0]],"o":[[-4.53,0],[-2.81,-2.84],[0,-9.42],[6.47,0],[0.31,1.02],[-0.52,0.94],[0,0],[0.09,0.02],[0,0],[1.03,0.25],[0.54,0.92],[-1.85,6.79],[0,0],[0,0]],"v":[[15.45,31.46],[4.28,27.17],[0,15.75],[14.78,0],[28.18,9.46],[27.85,12.5],[25.39,14.39],[23.83,14.79],[24.11,14.85],[27.28,15.61],[29.74,17.44],[30.14,20.43],[15.45,31.45],[15.45,31.46]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[2.78,2.8],[-0.02,4.63],[-8.84,0],[-1.8,-5.83],[0.53,-0.93],[1.04,-0.27],[0,0],[-0.09,-0.02],[0,0],[-0.54,-0.92],[0.28,-1.02],[7.21,0],[0,0]],"o":[[-4.53,0],[-2.81,-2.84],[0,-9.42],[6.47,0],[0.31,1.02],[-0.52,0.94],[0,0],[0.09,0.02],[0,0],[1.03,0.25],[0.54,0.92],[-1.85,6.79],[0,0],[0,0]],"v":[[15.45,31.46],[4.28,27.17],[0,15.75],[14.78,0],[28.18,9.46],[27.85,12.5],[25.39,14.39],[23.83,14.79],[24.11,14.85],[27.28,15.61],[29.74,17.44],[30.14,20.43],[15.45,31.45],[15.45,31.46]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[2.78,2.8],[-0.02,4.63],[-8.84,0],[-1.8,-5.83],[0.53,-0.93],[1.04,-0.27],[0,0],[-0.09,-0.02],[0,0],[-0.54,-0.92],[0.28,-1.02],[7.21,0],[0,0]],"o":[[-4.53,0],[-2.81,-2.84],[0,-9.42],[6.47,0],[0.31,1.02],[-0.52,0.94],[0,0],[0.09,0.02],[0,0],[1.03,0.25],[0.54,0.92],[-1.85,6.79],[0,0],[0,0]],"v":[[15.45,31.46],[4.28,27.17],[0,15.75],[14.78,0],[28.18,9.46],[27.85,12.5],[25.39,14.39],[23.83,14.79],[24.11,14.85],[27.28,15.61],[29.74,17.44],[30.14,20.43],[15.45,31.45],[15.45,31.46]]}],"t":60}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,-1.74],[-3.63,0],[-0.67,1.97],[-0.73,0.46],[0.59,1.46],[1.15,0]],"o":[[-3.24,0],[0,1.74],[1.87,0],[0.29,-0.85],[-1.56,-0.04],[-0.48,-1.19],[0,0]],"v":[[15.1,11.09],[11.38,15.75],[15.55,20.42],[19.48,17.37],[21.07,15.35],[17.54,12.89],[15.1,11.09]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,-1.74],[-3.63,0],[-0.67,1.97],[-0.73,0.46],[0.59,1.46],[1.15,0]],"o":[[-3.24,0],[0,1.74],[1.87,0],[0.29,-0.85],[-1.56,-0.04],[-0.48,-1.19],[0,0]],"v":[[15.1,11.09],[11.38,15.75],[15.55,20.42],[19.48,17.37],[21.07,15.35],[17.54,12.89],[15.1,11.09]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0,-1.74],[-3.63,0],[-0.67,1.97],[-0.73,0.46],[0.59,1.46],[1.15,0]],"o":[[-3.24,0],[0,1.74],[1.87,0],[0.29,-0.85],[-1.56,-0.04],[-0.48,-1.19],[0,0]],"v":[[15.1,11.09],[11.38,15.75],[15.55,20.42],[19.48,17.37],[21.07,15.35],[17.54,12.89],[15.1,11.09]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,-1.74],[-3.63,0],[-0.67,1.97],[-0.73,0.46],[0.59,1.46],[1.15,0]],"o":[[-3.24,0],[0,1.74],[1.87,0],[0.29,-0.85],[-1.56,-0.04],[-0.48,-1.19],[0,0]],"v":[[15.1,11.09],[11.38,15.75],[15.55,20.42],[19.48,17.37],[21.07,15.35],[17.54,12.89],[15.1,11.09]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[1,1,1],"t":12},{"s":[1,1,1],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":9},{"ty":4,"nm":"Hwhite","sr":1,"st":0,"op":61.18,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13.93,19.92],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13.93,19.92],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[13.93,19.92],"t":12},{"s":[13.93,19.92],"t":60}]},"s":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100,100],"t":12},{"s":[100,100],"t":60}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[145.88,19.61],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[145.88,19.61],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[124.07,19.61],"t":12},{"s":[132.07,19.61],"t":60}]},"r":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[0],"t":12},{"s":[0],"t":60}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[0.54,0],[0,-5.67],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.05,0.4],[-0.52,0],[-1.55,-1.63],[0.12,-2.28],[0.05,-0.56],[-1.1,0],[-2.07,-2.08],[0.03,-4.43],[0,0],[2.15,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-4.46],[-0.81,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.1],[0.52,-0.1],[2.23,0],[1.57,1.65],[-0.04,0.88],[0.76,-0.39],[3.41,0],[2.35,2.38],[0,0],[0,2.16],[0,0],[0,0],[0,0]],"v":[[19.19,39.83],[15.27,35.9],[15.27,24.99],[13.93,20.54],[12.58,26.21],[12.58,35.9],[8.66,39.83],[3.92,39.83],[0,35.9],[0,4.46],[3.54,0.15],[5.12,0],[11.07,2.57],[13.32,8.67],[13.18,10.8],[15.93,10.2],[24.3,13.37],[27.86,23.79],[27.83,35.91],[23.91,39.83],[19.2,39.83],[19.19,39.83]]}],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[0.54,0],[0,-5.67],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.05,0.4],[-0.52,0],[-1.55,-1.63],[0.12,-2.28],[0.05,-0.56],[-1.1,0],[-2.07,-2.08],[0.03,-4.43],[0,0],[2.15,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-4.46],[-0.81,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.1],[0.52,-0.1],[2.23,0],[1.57,1.65],[-0.04,0.88],[0.76,-0.39],[3.41,0],[2.35,2.38],[0,0],[0,2.16],[0,0],[0,0],[0,0]],"v":[[19.19,39.83],[15.27,35.9],[15.27,24.99],[13.93,20.54],[12.58,26.21],[12.58,35.9],[8.66,39.83],[3.92,39.83],[0,35.9],[0,4.46],[3.54,0.15],[5.12,0],[11.07,2.57],[13.32,8.67],[13.18,10.8],[15.93,10.2],[24.3,13.37],[27.86,23.79],[27.83,35.91],[23.91,39.83],[19.2,39.83],[19.19,39.83]]}],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[0.54,0],[0,-5.67],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.05,0.4],[-0.52,0],[-1.55,-1.63],[0.12,-2.28],[0.05,-0.56],[-1.1,0],[-2.07,-2.08],[0.03,-4.43],[0,0],[2.15,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-4.46],[-0.81,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.1],[0.52,-0.1],[2.23,0],[1.57,1.65],[-0.04,0.88],[0.76,-0.39],[3.41,0],[2.35,2.38],[0,0],[0,2.16],[0,0],[0,0],[0,0]],"v":[[19.19,39.83],[15.27,35.9],[15.27,24.99],[13.93,20.54],[12.58,26.21],[12.58,35.9],[8.66,39.83],[3.92,39.83],[0,35.9],[0,4.46],[3.54,0.15],[5.12,0],[11.07,2.57],[13.32,8.67],[13.18,10.8],[15.93,10.2],[24.3,13.37],[27.86,23.79],[27.83,35.91],[23.91,39.83],[19.2,39.83],[19.19,39.83]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,2.17],[0,0],[0.54,0],[0,-5.67],[0,0],[2.16,0],[0,0],[0,2.17],[0,0],[-2.05,0.4],[-0.52,0],[-1.55,-1.63],[0.12,-2.28],[0.05,-0.56],[-1.1,0],[-2.07,-2.08],[0.03,-4.43],[0,0],[2.15,0],[0,0],[0,0]],"o":[[-2.16,0],[0,0],[0,-4.46],[-0.81,0],[0,0],[0,2.17],[0,0],[-2.16,0],[0,0],[0,-2.1],[0.52,-0.1],[2.23,0],[1.57,1.65],[-0.04,0.88],[0.76,-0.39],[3.41,0],[2.35,2.38],[0,0],[0,2.16],[0,0],[0,0],[0,0]],"v":[[19.19,39.83],[15.27,35.9],[15.27,24.99],[13.93,20.54],[12.58,26.21],[12.58,35.9],[8.66,39.83],[3.92,39.83],[0,35.9],[0,4.46],[3.54,0.15],[5.12,0],[11.07,2.57],[13.32,8.67],[13.18,10.8],[15.93,10.2],[24.3,13.37],[27.86,23.79],[27.83,35.91],[23.91,39.83],[19.2,39.83],[19.19,39.83]]}],"t":60}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[1,1,1],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[1,1,1],"t":12},{"s":[1,1,1],"t":60}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":6},{"o":{"x":0,"y":0.88},"i":{"x":0,"y":1.49},"s":[100],"t":12},{"s":[100],"t":60}]}}],"ind":10}],"v":"5.7.0","fr":60,"op":60.18,"ip":0,"assets":[]} diff --git a/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSource.kt b/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSource.kt index 78224da4..e0f152d9 100644 --- a/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSource.kt +++ b/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSource.kt @@ -5,4 +5,6 @@ import com.moya.funch.model.ProfileModel interface LocalUserDataSource : UserDataSource { suspend fun saveUserProfile(userModel: ProfileModel): Result + + suspend fun fetchUserMbtiCollection(): Result> } diff --git a/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSourceImpl.kt b/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSourceImpl.kt index f6127fa8..8e0486f5 100644 --- a/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSourceImpl.kt +++ b/core/data/src/main/java/com/moya/funch/datasource/local/LocalUserDataSourceImpl.kt @@ -45,4 +45,6 @@ class LocalUserDataSourceImpl @Inject constructor( } } } + + override suspend fun fetchUserMbtiCollection(): Result> = runCatching { userDataStore.mbtiCollection } } diff --git a/core/data/src/main/java/com/moya/funch/datasource/remote/RemoteMatchDataSourceImpl.kt b/core/data/src/main/java/com/moya/funch/datasource/remote/RemoteMatchDataSourceImpl.kt index e0f6dce1..47936b3b 100644 --- a/core/data/src/main/java/com/moya/funch/datasource/remote/RemoteMatchDataSourceImpl.kt +++ b/core/data/src/main/java/com/moya/funch/datasource/remote/RemoteMatchDataSourceImpl.kt @@ -19,7 +19,16 @@ class RemoteMatchDataSourceImpl @Inject constructor( targetCode = targetCode ) ) - }.mapCatching { it.data } + }.mapCatching { + saveMbtiCollection(it.data.profile.mbti) + it.data + } + } + + private fun saveMbtiCollection(mbti: String) { + dataStore.mbtiCollection = dataStore.mbtiCollection.toMutableSet().apply { + add(mbti) + }.toSet() } override suspend fun canMatchProfile(targetCode: String): Result { diff --git a/core/data/src/main/java/com/moya/funch/repository/MbtiCollectionRepositoryImpl.kt b/core/data/src/main/java/com/moya/funch/repository/MbtiCollectionRepositoryImpl.kt new file mode 100644 index 00000000..ba3cf02f --- /dev/null +++ b/core/data/src/main/java/com/moya/funch/repository/MbtiCollectionRepositoryImpl.kt @@ -0,0 +1,20 @@ +package com.moya.funch.repository + +import com.moya.funch.datasource.local.LocalUserDataSource +import com.moya.funch.entity.Mbti +import javax.inject.Inject + +class MbtiCollectionRepositoryImpl @Inject constructor( + private val localUserDataSource: LocalUserDataSource +) : MbtiCollectionRepository { + override suspend fun addMbtiCollection(): Result { + // @Gun Hyung Todo : 추후 데이터 레이어 리팩토링 이후 작업 진행 + return Result.success(Unit) + } + + override suspend fun loadMbtiCollection(): Result> { + return localUserDataSource.fetchUserMbtiCollection().mapCatching { mbtiList -> + mbtiList.map { mbti -> Mbti.valueOf(mbti) } + } + } +} diff --git a/core/data/src/test/java/com/moya/funch/datasource/local/LocalUserDataSourceImplTest.kt b/core/data/src/test/java/com/moya/funch/datasource/local/LocalUserDataSourceImplTest.kt index 4e4cd97d..9f47ff74 100644 --- a/core/data/src/test/java/com/moya/funch/datasource/local/LocalUserDataSourceImplTest.kt +++ b/core/data/src/test/java/com/moya/funch/datasource/local/LocalUserDataSourceImplTest.kt @@ -106,6 +106,20 @@ internal class LocalUserDataSourceImplTest { ) } + @Test + fun `MbtiCollection이 비어있으면 emptySet를 가져온다`() = runTest { + // given + coEvery { userDataStore.mbtiCollection } returns emptySet() + // when + val actualResult = localUserDataSource.fetchUserMbtiCollection() + // then + assertAll( + { coVerify(exactly = 1) { userDataStore.mbtiCollection } }, + { assertThat(actualResult.isSuccess).isTrue() }, + { assertThat(actualResult.getOrNull()).isEmpty() } + ) + } + companion object { @JvmField @RegisterExtension diff --git a/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStore.kt b/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStore.kt index c3313976..8977b753 100644 --- a/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStore.kt +++ b/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStore.kt @@ -11,6 +11,7 @@ interface UserDataStore { var subwayName: String var subwayLines: Set var mbti: String + var mbtiCollection: Set fun hasUserCode(): Boolean diff --git a/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStoreImpl.kt b/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStoreImpl.kt index 1581e018..4c54d04e 100644 --- a/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStoreImpl.kt +++ b/core/datastore/src/main/java/com/moya/funch/datastore/UserDataStoreImpl.kt @@ -92,6 +92,14 @@ class UserDataStoreImpl @Inject constructor( } } + override var mbtiCollection: Set + get() = preferences.getStringSet(MBTI_COLLECTION, setOf()).orEmpty() + set(value) { + preferences.edit(commit = true) { + putStringSet(MBTI_COLLECTION, value) + } + } + override fun hasUserCode(): Boolean { return preferences.contains(USER_CODE) } @@ -123,5 +131,6 @@ class UserDataStoreImpl @Inject constructor( const val SUBWAY_NAME = "SUBWAY_NAME" const val SUBWAY_LINE = "SUBWAY_LINE" const val MBTI = "MBTI" + const val MBTI_COLLECTION = "MBTI_COLLECTION" } } diff --git a/core/designsystem/src/main/java/com/moya/funch/common/SearchPainter.kt b/core/designsystem/src/main/java/com/moya/funch/common/SearchPainter.kt index a1cf54a0..c7ffcad1 100644 --- a/core/designsystem/src/main/java/com/moya/funch/common/SearchPainter.kt +++ b/core/designsystem/src/main/java/com/moya/funch/common/SearchPainter.kt @@ -47,3 +47,45 @@ fun subwayLinePainter(value: String): Painter = when (value) { "INCHEON_TWO" -> painterResource(id = FunchIconAsset.SubwayLine.subway_line_incheon_two) else -> throw IllegalArgumentException("Unknown Icon: $value") } + +@Composable +fun activeMbtiBadgePainter(value: String): Painter = when (value) { + "ISTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.istj_active) + "ISFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.isfj_active) + "INFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.infj_active) + "INTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.intj_active) + "ISTP" -> painterResource(id = FunchIconAsset.MbtiBadge.istp_active) + "ISFP" -> painterResource(id = FunchIconAsset.MbtiBadge.isfp_active) + "INFP" -> painterResource(id = FunchIconAsset.MbtiBadge.infp_active) + "INTP" -> painterResource(id = FunchIconAsset.MbtiBadge.intp_active) + "ESTP" -> painterResource(id = FunchIconAsset.MbtiBadge.estp_active) + "ESFP" -> painterResource(id = FunchIconAsset.MbtiBadge.esfp_active) + "ENFP" -> painterResource(id = FunchIconAsset.MbtiBadge.enfp_active) + "ENTP" -> painterResource(id = FunchIconAsset.MbtiBadge.entp_active) + "ESTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.estj_active) + "ESFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.esfj_active) + "ENFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.enfj_active) + "ENTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.entj_active) + else -> throw IllegalArgumentException("Unknown Icon: $value") +} + +@Composable +fun inactiveMbtiBadgePainter(value: String): Painter = when (value) { + "ISTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.istj_inactive) + "ISFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.isfj_inactive) + "INFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.infj_inactive) + "INTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.intj_inactive) + "ISTP" -> painterResource(id = FunchIconAsset.MbtiBadge.istp_inactive) + "ISFP" -> painterResource(id = FunchIconAsset.MbtiBadge.isfp_inactive) + "INFP" -> painterResource(id = FunchIconAsset.MbtiBadge.infp_inactive) + "INTP" -> painterResource(id = FunchIconAsset.MbtiBadge.intp_inactive) + "ESTP" -> painterResource(id = FunchIconAsset.MbtiBadge.estp_inactive) + "ESFP" -> painterResource(id = FunchIconAsset.MbtiBadge.esfp_inactive) + "ENFP" -> painterResource(id = FunchIconAsset.MbtiBadge.enfp_inactive) + "ENTP" -> painterResource(id = FunchIconAsset.MbtiBadge.entp_inactive) + "ESTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.estj_inactive) + "ESFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.esfj_inactive) + "ENFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.enfj_inactive) + "ENTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.entj_inactive) + else -> throw IllegalArgumentException("Unknown Icon: $value") +} diff --git a/core/designsystem/src/main/java/com/moya/funch/icon/FunchIconAsset.kt b/core/designsystem/src/main/java/com/moya/funch/icon/FunchIconAsset.kt index 5bfdce8c..3106f36a 100644 --- a/core/designsystem/src/main/java/com/moya/funch/icon/FunchIconAsset.kt +++ b/core/designsystem/src/main/java/com/moya/funch/icon/FunchIconAsset.kt @@ -28,6 +28,7 @@ object FunchIconAsset { val profile_80 = R.drawable.ic_profile_80 val view_count_80 = R.drawable.ic_view_count_80 val code_80 = R.drawable.ic_code_80 + val trophy_40 = R.drawable.ic_trophy_40 } object Job { @@ -89,4 +90,42 @@ object FunchIconAsset { val eighty = R.drawable.ic_match_percentage80_120 val hundred = R.drawable.ic_match_percentage100_120 } + + object MbtiBadge { + /* active */ + val infj_active = R.drawable.ic_mbti_infj_active_60 + val intj_active = R.drawable.ic_mbti_intj_active_60 + val infp_active = R.drawable.ic_mbti_infp_active_60 + val intp_active = R.drawable.ic_mbti_intp_active_60 + val isfj_active = R.drawable.ic_mbti_isfj_active_60 + val istj_active = R.drawable.ic_mbti_istj_active_60 + val isfp_active = R.drawable.ic_mbti_isfp_active_60 + val istp_active = R.drawable.ic_mbti_istp_active_60 + val entj_active = R.drawable.ic_mbti_entj_active_60 + val enfp_active = R.drawable.ic_mbti_enfp_active_60 + val enfj_active = R.drawable.ic_mbti_enfj_active_60 + val entp_active = R.drawable.ic_mbti_entp_active_60 + val esfj_active = R.drawable.ic_mbti_esfj_active_60 + val esfp_active = R.drawable.ic_mbti_esfp_active_60 + val estj_active = R.drawable.ic_mbti_estj_active_60 + val estp_active = R.drawable.ic_mbti_estp_active_60 + + /* inactive */ + val infj_inactive = R.drawable.ic_mbti_infj_inactive_60 + val intj_inactive = R.drawable.ic_mbti_intj_inactive_60 + val infp_inactive = R.drawable.ic_mbti_infp_inactive_60 + val intp_inactive = R.drawable.ic_mbti_intp_inactive_60 + val isfj_inactive = R.drawable.ic_mbti_isfj_inactive_60 + val istj_inactive = R.drawable.ic_mbti_istj_inactive_60 + val isfp_inactive = R.drawable.ic_mbti_isfp_inactive_60 + val istp_inactive = R.drawable.ic_mbti_istp_inactive_60 + val entj_inactive = R.drawable.ic_mbti_entj_inactive_60 + val enfp_inactive = R.drawable.ic_mbti_enfp_inactive_60 + val enfj_inactive = R.drawable.ic_mbti_enfj_inactive_60 + val entp_inactive = R.drawable.ic_mbti_entp_inactive_60 + val esfj_inactive = R.drawable.ic_mbti_esfj_inactive_60 + val esfp_inactive = R.drawable.ic_mbti_esfp_inactive_60 + val estj_inactive = R.drawable.ic_mbti_estj_inactive_60 + val estp_inactive = R.drawable.ic_mbti_estp_inactive_60 + } } diff --git a/core/designsystem/src/main/java/com/moya/funch/ui/FunchCaption.kt b/core/designsystem/src/main/java/com/moya/funch/ui/FunchCaption.kt index fb631811..6137e3b0 100644 --- a/core/designsystem/src/main/java/com/moya/funch/ui/FunchCaption.kt +++ b/core/designsystem/src/main/java/com/moya/funch/ui/FunchCaption.kt @@ -16,17 +16,15 @@ import com.moya.funch.theme.Coral500 import com.moya.funch.theme.FunchTheme @Composable -fun FunchErrorCaption(modifier: Modifier = Modifier, errorText: String, description: String = "") { +fun FunchErrorCaption(modifier: Modifier = Modifier, errorText: String, errorIcon: @Composable (() -> Unit)? = null) { Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = FunchIconAsset.Etc.information_24), - contentDescription = description, - tint = Coral500 - ) - Spacer(modifier = Modifier.width(4.dp)) + if (errorIcon != null) { + errorIcon() + Spacer(modifier = Modifier.width(4.dp)) + } Text( text = errorText, color = Coral500, @@ -37,9 +35,26 @@ fun FunchErrorCaption(modifier: Modifier = Modifier, errorText: String, descript // ============================== Preview ================================= -@Preview("Error Caption", showBackground = true, backgroundColor = 0xFF2C2C2C) +@Preview("Error Caption With Icon", showBackground = true, backgroundColor = 0xFF2C2C2C) @Composable private fun Preview1() { + FunchTheme { + FunchErrorCaption( + errorIcon = { + Icon( + painter = painterResource(id = FunchIconAsset.Etc.information_24), + tint = Coral500, + contentDescription = null + ) + }, + errorText = "errorText" + ) + } +} + +@Preview("Only Text Error Caption", showBackground = true, backgroundColor = 0xFF2C2C2C) +@Composable +private fun Preview2() { FunchTheme { FunchErrorCaption( errorText = "errorText" diff --git a/core/designsystem/src/main/java/com/moya/funch/ui/FunchDropDown.kt b/core/designsystem/src/main/java/com/moya/funch/ui/FunchDropDown.kt index abf06335..9263f9ec 100644 --- a/core/designsystem/src/main/java/com/moya/funch/ui/FunchDropDown.kt +++ b/core/designsystem/src/main/java/com/moya/funch/ui/FunchDropDown.kt @@ -13,12 +13,14 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.absoluteOffset import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.Surface @@ -32,15 +34,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.layout.boundsInWindow +import androidx.compose.ui.layout.boundsInRoot import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.Popup import com.moya.funch.icon.FunchIconAsset import com.moya.funch.modifier.ScrollBarConfig import com.moya.funch.modifier.verticalScrollWithScrollbar @@ -50,7 +50,6 @@ import com.moya.funch.theme.Gray500 import com.moya.funch.theme.Gray800 import com.moya.funch.theme.LocalBackgroundTheme import com.moya.funch.theme.White -import kotlin.math.roundToInt @Composable fun FunchDropDownButton( @@ -116,59 +115,46 @@ fun FunchDropDownButton( @Composable fun FunchDropDownMenu( - modifier: Modifier = Modifier, items: List, - buttonBounds: Rect, - onItemSelected: (String) -> Unit, - scrollState: ScrollState = rememberScrollState() + modifier: Modifier = Modifier, + scrollState: ScrollState = rememberScrollState(), + onItemSelected: (String) -> Unit ) { - Popup( - alignment = Alignment.TopStart, - offset = IntOffset( - x = 0, - y = with(LocalDensity.current) { - (buttonBounds.height).toInt() + 8.dp.toPx().roundToInt() - } - ) - ) { - Column( - modifier = modifier - .width(with(LocalDensity.current) { buttonBounds.width.toDp() }) - .height(144.dp) - .background( - color = Gray800, - shape = FunchTheme.shapes.medium - ) - .clip(FunchTheme.shapes.medium) - .verticalScrollWithScrollbar( - state = scrollState, - scrollbarConfig = ScrollBarConfig( - indicatorHeight = 39.dp, - indicatorThickness = 4.dp, - indicatorColor = Gray300, - padding = PaddingValues( - top = 16.dp, - bottom = 16.dp, - end = 4.dp - ) + Column( + modifier = modifier + .background( + color = Gray800, + shape = FunchTheme.shapes.medium + ) + .clip(FunchTheme.shapes.medium) + .verticalScrollWithScrollbar( + state = scrollState, + scrollbarConfig = ScrollBarConfig( + indicatorHeight = 39.dp, + indicatorThickness = 4.dp, + indicatorColor = Gray300, + padding = PaddingValues( + top = 16.dp, + bottom = 16.dp, + end = 4.dp ) ) - ) { - items.forEachIndexed { index, option -> - val interactionSource = remember { MutableInteractionSource() } - val isPressed by interactionSource.collectIsPressedAsState() - FunchDropDownItem( - option = option, - onItemSelected = { onItemSelected(option) }, - isPressed = isPressed, - interactionSource = interactionSource + ) + ) { + items.forEachIndexed { index, option -> + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + FunchDropDownItem( + option = option, + onItemSelected = { onItemSelected(option) }, + isPressed = isPressed, + interactionSource = interactionSource + ) + if (index < items.lastIndex) { + Divider( + color = Gray500, + thickness = 0.5f.dp ) - if (index < items.lastIndex) { - Divider( - color = Gray500, - thickness = 0.5f.dp - ) - } } } } @@ -219,35 +205,64 @@ private fun Preview1() { modifier = Modifier.fillMaxSize(), color = backgroundColor ) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - val bloodTypes = listOf("A형", "B형", "O형", "AB형") - var placeHolder by remember { mutableStateOf(bloodTypes[0]) } - var isDropDownMenuExpanded by remember { mutableStateOf(true) } - val buttonBounds = remember { mutableStateOf(Rect.Zero) } + val bloodTypes = listOf("A형", "B형", "O형", "AB형") + var placeHolder by remember { mutableStateOf(bloodTypes[0]) } + var isDropDownMenuExpanded by remember { mutableStateOf(true) } + var buttonBounds by remember { mutableStateOf(Rect.Zero) } + val dropDownMenuHeight = 192.dp - Text( - text = "Hello, World!", - fontSize = 50.sp, - color = White - ) - Box { + Box(modifier = Modifier.fillMaxSize()) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + .verticalScroll(rememberScrollState()) + ) { + Text( + text = "Hello, World!", + fontSize = 50.sp, + color = White + ) + Text( + text = "Hello, World!", + fontSize = 50.sp, + color = White + ) + Text( + text = "Hello, World!", + fontSize = 50.sp, + color = White + ) FunchDropDownButton( placeHolder = placeHolder, onClick = { isDropDownMenuExpanded = !isDropDownMenuExpanded }, isDropDownMenuExpanded = isDropDownMenuExpanded, indication = null, modifier = Modifier.onGloballyPositioned { coordinates -> - buttonBounds.value = coordinates.boundsInWindow() + buttonBounds = coordinates.boundsInRoot() + println(buttonBounds.top) } ) - if (isDropDownMenuExpanded) { + for (i in 0 until 10) { + Text( + text = "Hello, World!", + fontSize = 50.sp, + color = White + ) + } + } + if (isDropDownMenuExpanded) { + Box( + modifier = Modifier + .absoluteOffset( + x = with(LocalDensity.current) { buttonBounds.left.toDp() }, + y = with(LocalDensity.current) { buttonBounds.top.toDp() - dropDownMenuHeight - 8.dp } + ) + .width(with(LocalDensity.current) { buttonBounds.width.toDp() }) + .height(dropDownMenuHeight) + ) { FunchDropDownMenu( items = bloodTypes, - buttonBounds = buttonBounds.value, onItemSelected = { text -> placeHolder = text isDropDownMenuExpanded = false @@ -255,11 +270,6 @@ private fun Preview1() { ) } } - Text( - text = "Hello, World!", - fontSize = 50.sp, - color = White - ) } } } diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_enfj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_enfj_active_60.xml new file mode 100644 index 00000000..3abc69e5 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_enfj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_enfj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_enfj_inactive_60.xml new file mode 100644 index 00000000..2359f5d8 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_enfj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_enfp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_enfp_active_60.xml new file mode 100644 index 00000000..7ba604f4 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_enfp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_enfp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_enfp_inactive_60.xml new file mode 100644 index 00000000..ecf19805 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_enfp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_entj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_entj_active_60.xml new file mode 100644 index 00000000..6169ea5e --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_entj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_entj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_entj_inactive_60.xml new file mode 100644 index 00000000..401ff9da --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_entj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_entp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_entp_active_60.xml new file mode 100644 index 00000000..d4dfb4b1 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_entp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_entp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_entp_inactive_60.xml new file mode 100644 index 00000000..481aec81 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_entp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_esfj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_esfj_active_60.xml new file mode 100644 index 00000000..49d60858 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_esfj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_esfj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_esfj_inactive_60.xml new file mode 100644 index 00000000..4a8a5b22 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_esfj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_esfp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_esfp_active_60.xml new file mode 100644 index 00000000..9cf7d580 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_esfp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_esfp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_esfp_inactive_60.xml new file mode 100644 index 00000000..10acb767 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_esfp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_estj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_estj_active_60.xml new file mode 100644 index 00000000..e66f7b1f --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_estj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_estj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_estj_inactive_60.xml new file mode 100644 index 00000000..244750fa --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_estj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_estp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_estp_active_60.xml new file mode 100644 index 00000000..d0cc4bf0 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_estp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_estp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_estp_inactive_60.xml new file mode 100644 index 00000000..884c38d2 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_estp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_infj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_infj_active_60.xml new file mode 100644 index 00000000..4124ccd8 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_infj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_infj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_infj_inactive_60.xml new file mode 100644 index 00000000..dcff44e0 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_infj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_infp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_infp_active_60.xml new file mode 100644 index 00000000..cceb0547 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_infp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_infp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_infp_inactive_60.xml new file mode 100644 index 00000000..cb8f7f43 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_infp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_intj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_intj_active_60.xml new file mode 100644 index 00000000..e7ee6d2d --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_intj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_intj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_intj_inactive_60.xml new file mode 100644 index 00000000..502d1586 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_intj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_intp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_intp_active_60.xml new file mode 100644 index 00000000..00bf65de --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_intp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_intp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_intp_inactive_60.xml new file mode 100644 index 00000000..044af640 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_intp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_isfj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_isfj_active_60.xml new file mode 100644 index 00000000..18757a17 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_isfj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_isfj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_isfj_inactive_60.xml new file mode 100644 index 00000000..ffad9340 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_isfj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_isfp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_isfp_active_60.xml new file mode 100644 index 00000000..93555441 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_isfp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_isfp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_isfp_inactive_60.xml new file mode 100644 index 00000000..b6172add --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_isfp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_istj_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_istj_active_60.xml new file mode 100644 index 00000000..3e14cfce --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_istj_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_istj_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_istj_inactive_60.xml new file mode 100644 index 00000000..8b953290 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_istj_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_istp_active_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_istp_active_60.xml new file mode 100644 index 00000000..64ab273b --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_istp_active_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_mbti_istp_inactive_60.xml b/core/designsystem/src/main/res/drawable/ic_mbti_istp_inactive_60.xml new file mode 100644 index 00000000..95bfd2c9 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_mbti_istp_inactive_60.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_trophy_40.xml b/core/designsystem/src/main/res/drawable/ic_trophy_40.xml new file mode 100644 index 00000000..5b21b815 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_trophy_40.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/core/domain/src/main/java/com/moya/funch/entity/Mbti.kt b/core/domain/src/main/java/com/moya/funch/entity/Mbti.kt index 7ab5d32f..508eabda 100644 --- a/core/domain/src/main/java/com/moya/funch/entity/Mbti.kt +++ b/core/domain/src/main/java/com/moya/funch/entity/Mbti.kt @@ -1,21 +1,21 @@ package com.moya.funch.entity enum class Mbti { - ENFJ, - ENFP, - ENTJ, - ENTP, - ESFJ, - ESFP, - ESTJ, - ESTP, + ISTJ, + ISFJ, INFJ, - INFP, INTJ, - INTP, - ISFJ, - ISFP, - ISTJ, ISTP, + ISFP, + INFP, + INTP, + ESTP, + ESFP, + ENFP, + ENTP, + ESTJ, + ESFJ, + ENFJ, + ENTJ, IDLE } diff --git a/core/domain/src/main/java/com/moya/funch/repository/MbtiCollectionRepository.kt b/core/domain/src/main/java/com/moya/funch/repository/MbtiCollectionRepository.kt new file mode 100644 index 00000000..03460611 --- /dev/null +++ b/core/domain/src/main/java/com/moya/funch/repository/MbtiCollectionRepository.kt @@ -0,0 +1,10 @@ +package com.moya.funch.repository + +import com.moya.funch.entity.Mbti + +interface MbtiCollectionRepository { + // @Gun Hyung Todo : 추후 데이터 레이어 리팩토링 이후 작업 진행 + suspend fun addMbtiCollection(): Result + + suspend fun loadMbtiCollection(): Result> +} diff --git a/core/domain/src/main/java/com/moya/funch/usecase/LoadMbtiCollectionUseCase.kt b/core/domain/src/main/java/com/moya/funch/usecase/LoadMbtiCollectionUseCase.kt new file mode 100644 index 00000000..e7ace238 --- /dev/null +++ b/core/domain/src/main/java/com/moya/funch/usecase/LoadMbtiCollectionUseCase.kt @@ -0,0 +1,18 @@ +package com.moya.funch.usecase + +import com.moya.funch.entity.Mbti +import com.moya.funch.repository.MbtiCollectionRepository +import javax.inject.Inject + +class LoadMbtiCollectionUseCaseImpl @Inject constructor( + private val mbtiCollectionRepository: MbtiCollectionRepository +) : LoadMbtiCollectionUseCase { + + override suspend operator fun invoke(): Result> { + return mbtiCollectionRepository.loadMbtiCollection() + } +} + +fun interface LoadMbtiCollectionUseCase { + suspend operator fun invoke(): Result> +} diff --git a/feature/collection/.gitignore b/feature/collection/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/collection/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/collection/build.gradle.kts b/feature/collection/build.gradle.kts new file mode 100644 index 00000000..41e6b23a --- /dev/null +++ b/feature/collection/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + alias(libs.plugins.funch.feature) + alias(libs.plugins.funch.compose) +} + +android { + namespace = "com.moya.funch.collection" +} + +dependencies { + implementation(projects.core.designsystem) + implementation(projects.core.domain) +} diff --git a/feature/collection/proguard-rules.pro b/feature/collection/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/feature/collection/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/feature/collection/src/main/AndroidManifest.xml b/feature/collection/src/main/AndroidManifest.xml new file mode 100644 index 00000000..5315d2d6 --- /dev/null +++ b/feature/collection/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/feature/collection/src/main/java/com/moya/funch/collection/CollectionScreen.kt b/feature/collection/src/main/java/com/moya/funch/collection/CollectionScreen.kt new file mode 100644 index 00000000..e9ba3c39 --- /dev/null +++ b/feature/collection/src/main/java/com/moya/funch/collection/CollectionScreen.kt @@ -0,0 +1,159 @@ +package com.moya.funch.collection + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.moya.funch.collection.theme.Gray300 +import com.moya.funch.collection.theme.Gray400 +import com.moya.funch.collection.theme.Gray800 +import com.moya.funch.collection.theme.White +import com.moya.funch.common.activeMbtiBadgePainter +import com.moya.funch.common.inactiveMbtiBadgePainter +import com.moya.funch.component.FunchIcon +import com.moya.funch.entity.Mbti +import com.moya.funch.icon.FunchIconAsset +import com.moya.funch.theme.FunchTheme +import com.moya.funch.theme.LocalBackgroundTheme +import com.moya.funch.ui.FunchTopBar + +@Composable +internal fun CollectionRoute(viewModel: CollectionViewModel = hiltViewModel(), onNavigateToHome: () -> Unit) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + + CollectionScreen( + name = uiState.name, + mbtiCollection = uiState.mbtiCollection, + onNavigateToHome = onNavigateToHome + ) +} + +@Composable +internal fun CollectionScreen(name: String, mbtiCollection: List, onNavigateToHome: () -> Unit) { + Column( + modifier = Modifier.fillMaxSize() + ) { + FunchTopBar( + modifier = Modifier.padding(start = 12.dp), + onClickLeadingIcon = onNavigateToHome, + leadingIcon = FunchIcon( + resId = FunchIconAsset.Arrow.arrow_left_small_24, + description = "", + tint = Gray400 + ), + trailingIcon = null + ) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + ) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = stringResource(id = R.string.collection_title), + color = White, + style = FunchTheme.typography.t2 + ) + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = stringResource(id = R.string.collection_sub_title, name), + color = Gray300, + style = FunchTheme.typography.b + ) + Spacer(modifier = Modifier.height(40.dp)) + Text( + text = "MBTI", + color = Gray400, + style = FunchTheme.typography.sbt2 + ) + Spacer(modifier = Modifier.height(12.dp)) + MbtiCollection(mbtiCollection = mbtiCollection) + } + } +} + +@Composable +private fun MbtiCollection(mbtiCollection: List) { + val mbtiList = Mbti.entries.filter { it != Mbti.IDLE }.toList() + + LazyVerticalGrid( + modifier = Modifier.widthIn(max = 320.dp), + columns = GridCells.Fixed(4), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + content = { + items(count = mbtiList.size) { item -> + Box( + modifier = Modifier + .clip(FunchTheme.shapes.medium) + .background( + color = Gray800, + shape = FunchTheme.shapes.medium + ) + .padding(7.dp), + contentAlignment = Alignment.Center + ) { + Icon( + painter = if (mbtiCollection.contains(mbtiList[item])) { + activeMbtiBadgePainter(value = mbtiList[item].name) + } else { + inactiveMbtiBadgePainter(value = mbtiList[item].name) + }, + contentDescription = "", + tint = Color.Unspecified + ) + } + } + } + ) +} + +@Preview( + "Home UI", + showBackground = true, + widthDp = 360, + heightDp = 640 +) +@Composable +private fun Preview1() { + FunchTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = LocalBackgroundTheme.current.color + ) { + CollectionScreen( + name = "홍길동", + mbtiCollection = listOf( + Mbti.ISTJ, + Mbti.INFJ, + Mbti.INTJ, + Mbti.INFP, + Mbti.INTP + ), + onNavigateToHome = {} + ) + } + } +} diff --git a/feature/collection/src/main/java/com/moya/funch/collection/CollectionViewModel.kt b/feature/collection/src/main/java/com/moya/funch/collection/CollectionViewModel.kt new file mode 100644 index 00000000..b05f02d0 --- /dev/null +++ b/feature/collection/src/main/java/com/moya/funch/collection/CollectionViewModel.kt @@ -0,0 +1,53 @@ +package com.moya.funch.collection + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.moya.funch.entity.Mbti +import com.moya.funch.usecase.LoadMbtiCollectionUseCase +import com.moya.funch.usecase.LoadUserProfileUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import timber.log.Timber + +internal data class CollectionUiState( + val name: String = "", + val mbtiCollection: List = emptyList() +) + +@HiltViewModel +internal class CollectionViewModel @Inject constructor( + private val loadMbtiCollectionUseCase: LoadMbtiCollectionUseCase, + private val loadUserProfileUseCase: LoadUserProfileUseCase +) : ViewModel() { + + private val _uiState = MutableStateFlow(CollectionUiState()) + val uiState = _uiState.asStateFlow() + + init { + loadUserProfile() + loadMbtiCollection() + } + + private fun loadUserProfile() { + viewModelScope.launch { + loadUserProfileUseCase().onSuccess { profile -> + _uiState.value = _uiState.value.copy(name = profile.name) + }.onFailure { + Timber.e(it.message) + } + } + } + + private fun loadMbtiCollection() { + viewModelScope.launch { + loadMbtiCollectionUseCase().onSuccess { mbtiCollection -> + _uiState.value = _uiState.value.copy(mbtiCollection = mbtiCollection) + }.onFailure { + Timber.e(it.message) + } + } + } +} diff --git a/feature/collection/src/main/java/com/moya/funch/collection/navigation/CollectionNavigation.kt b/feature/collection/src/main/java/com/moya/funch/collection/navigation/CollectionNavigation.kt new file mode 100644 index 00000000..d2a9ade7 --- /dev/null +++ b/feature/collection/src/main/java/com/moya/funch/collection/navigation/CollectionNavigation.kt @@ -0,0 +1,19 @@ +package com.moya.funch.collection.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.moya.funch.collection.CollectionRoute + +const val COLLECTION_ROUTE = "collection" + +fun NavController.navigateToCollection(navOptions: NavOptions? = null) = navigate(COLLECTION_ROUTE, navOptions) + +fun NavGraphBuilder.collectionScreen(onNavigateToHome: () -> Unit) { + composable(route = COLLECTION_ROUTE) { + CollectionRoute( + onNavigateToHome = onNavigateToHome + ) + } +} diff --git a/feature/collection/src/main/java/com/moya/funch/collection/theme/CollectionColors.kt b/feature/collection/src/main/java/com/moya/funch/collection/theme/CollectionColors.kt new file mode 100644 index 00000000..6b99ad3a --- /dev/null +++ b/feature/collection/src/main/java/com/moya/funch/collection/theme/CollectionColors.kt @@ -0,0 +1,18 @@ +package com.moya.funch.collection.theme + +import androidx.compose.ui.graphics.Color + +internal val Coral500 = Color(0xFFF86E6F) +internal val Lemon500 = Color(0xFFFFE83B) +internal val Lemon600 = Color(0xFFE1CA13) +internal val Lemon900 = Color(0xFF90720A) +internal val Yellow500 = Color(0xFFFFD240) +internal val Yellow600 = Color(0xFFE1B012) +internal val White = Color(0xFFFFFFFF) +internal val Gray900 = Color(0xFF151515) +internal val Gray800 = Color(0xFF242627) +internal val Gray700 = Color(0xFF2C2C2C) +internal val Gray600 = Color(0xFF363636) +internal val Gray500 = Color(0xFF404040) +internal val Gray400 = Color(0xFF6D6D6D) +internal val Gray300 = Color(0xFF9B9B9B) diff --git a/feature/collection/src/main/res/values/strings.xml b/feature/collection/src/main/res/values/strings.xml new file mode 100644 index 00000000..865f3134 --- /dev/null +++ b/feature/collection/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + 수집 도감 + %s님과 매칭한 친구들이에요! + diff --git a/feature/home/src/main/java/com/moya/funch/HomeScreen.kt b/feature/home/src/main/java/com/moya/funch/HomeScreen.kt index 6b0a2268..8c701dbf 100644 --- a/feature/home/src/main/java/com/moya/funch/HomeScreen.kt +++ b/feature/home/src/main/java/com/moya/funch/HomeScreen.kt @@ -76,7 +76,8 @@ private val brush = Brush.horizontalGradient( internal fun HomeRoute( viewModel: HomeViewModel = hiltViewModel(), onNavigateToMyProfile: () -> Unit, - onNavigateToMatching: (String) -> Unit + onNavigateToMatching: (String) -> Unit, + onNavigateToCollection: () -> Unit ) { val homeModel by viewModel.homeModel.collectAsStateWithLifecycle() val matched by viewModel.matched.collectAsStateWithLifecycle(false) @@ -104,8 +105,10 @@ internal fun HomeRoute( } if (matched) { - matchDone() - onNavigateToMatching(homeModel.matchingCode) + homeModel.matchingCode.also { + matchDone() + onNavigateToMatching(it) + } } HomeScreen( @@ -113,9 +116,10 @@ internal fun HomeRoute( viewCount = homeModel.viewCount, job = homeModel.job, matchingCode = homeModel.matchingCode, - onMatchingCodeChange = viewModel::setMatchingCode, + onMatchingCodeChange = viewModel::updateMatchingCode, matchProfile = viewModel::matchProfile, - onNavigateToMyProfile = onNavigateToMyProfile + onNavigateToMyProfile = onNavigateToMyProfile, + onNavigateToCollection = onNavigateToCollection ) } @@ -127,7 +131,8 @@ internal fun HomeScreen( matchingCode: String, onMatchingCodeChange: (String) -> Unit, matchProfile: () -> Unit, - onNavigateToMyProfile: () -> Unit + onNavigateToMyProfile: () -> Unit, + onNavigateToCollection: () -> Unit ) { val focusManager = LocalFocusManager.current Column( @@ -166,6 +171,9 @@ internal fun HomeScreen( ProfileViewCounterCard( viewCount = viewCount ) + CollectionCard( + onNavigateToCollection = onNavigateToCollection + ) } } @@ -349,6 +357,35 @@ private fun ProfileViewCounterCard(viewCount: Int) { } } +@Composable +private fun CollectionCard(modifier: Modifier = Modifier, onNavigateToCollection: () -> Unit) { + Column( + modifier = modifier + .background( + color = Gray800, + shape = FunchTheme.shapes.medium + ) + .clip(FunchTheme.shapes.medium) + .clickableSingle(onClick = onNavigateToCollection) + .padding( + vertical = 11.5.dp, + horizontal = 24.dp + ), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(space = 8.dp) + ) { + Image( + painter = painterResource(id = FunchIconAsset.Etc.trophy_40), + contentDescription = "" + ) + Text( + text = stringResource(id = R.string.collection_card_caption), + style = FunchTheme.typography.b, + color = Gray400 + ) + } +} + @Preview( "Home UI", showBackground = true, @@ -373,7 +410,8 @@ private fun Preview1() { matchingCode = text, onMatchingCodeChange = { text = it }, matchProfile = {}, - onNavigateToMyProfile = {} + onNavigateToMyProfile = {}, + onNavigateToCollection = {} ) } } diff --git a/feature/home/src/main/java/com/moya/funch/HomeViewModel.kt b/feature/home/src/main/java/com/moya/funch/HomeViewModel.kt index 080f0f5b..0fe5b860 100644 --- a/feature/home/src/main/java/com/moya/funch/HomeViewModel.kt +++ b/feature/home/src/main/java/com/moya/funch/HomeViewModel.kt @@ -50,7 +50,18 @@ internal class HomeViewModel @Inject constructor( initHome() } - fun setMatchingCode(code: String) { + fun fetchViewCount() { + viewModelScope.launch { + loadViewCountUseCase().onSuccess { + setViewCount(it) + }.onFailure { + Timber.e("fetchViewCount(): ${it.stackTraceToString()}") + setViewCount(0) + } + } + } + + fun updateMatchingCode(code: String) { _homeModel.value = _homeModel.value.copy( matchingCode = code.uppercase() ) @@ -69,6 +80,7 @@ internal class HomeViewModel @Inject constructor( fun matchDone() { _matched.value = false + _homeModel.value = _homeModel.value.copy(matchingCode = MATCH_CODE_EMPTY) } private fun initHome() { @@ -88,17 +100,6 @@ internal class HomeViewModel @Inject constructor( } } - fun fetchViewCount() { - viewModelScope.launch { - loadViewCountUseCase().onSuccess { - setViewCount(it) - }.onFailure { - Timber.e("fetchViewCount(): ${it.stackTraceToString()}") - setViewCount(0) - } - } - } - private fun setMyCode(code: String) { _homeModel.value = _homeModel.value.copy( myCode = code.uppercase() @@ -110,4 +111,8 @@ internal class HomeViewModel @Inject constructor( viewCount = count ) } + + companion object { + private const val MATCH_CODE_EMPTY = "" + } } diff --git a/feature/home/src/main/java/com/moya/funch/navigation/HomeNavigation.kt b/feature/home/src/main/java/com/moya/funch/navigation/HomeNavigation.kt index 752a8c2c..1bff1840 100644 --- a/feature/home/src/main/java/com/moya/funch/navigation/HomeNavigation.kt +++ b/feature/home/src/main/java/com/moya/funch/navigation/HomeNavigation.kt @@ -11,11 +11,16 @@ fun NavController.onNavigateToHome() = navigate(HOME_ROUTE) { popUpTo(graph.id) } -fun NavGraphBuilder.homeScreen(onNavigateToMyProfile: () -> Unit, onNavigateToMatching: (String) -> Unit) { +fun NavGraphBuilder.homeScreen( + onNavigateToMyProfile: () -> Unit, + onNavigateToMatching: (String) -> Unit, + onNavigateToCollection: () -> Unit +) { composable(route = HOME_ROUTE) { HomeRoute( onNavigateToMatching = onNavigateToMatching, - onNavigateToMyProfile = onNavigateToMyProfile + onNavigateToMyProfile = onNavigateToMyProfile, + onNavigateToCollection = onNavigateToCollection ) } } diff --git a/feature/home/src/main/res/values/strings.xml b/feature/home/src/main/res/values/strings.xml index fceb6774..f83e6388 100644 --- a/feature/home/src/main/res/values/strings.xml +++ b/feature/home/src/main/res/values/strings.xml @@ -8,4 +8,5 @@ 내 프로필 내 프로필을 %d명이 조회했어요 + 수집 도감 diff --git a/feature/onboarding/src/main/java/com/moya/funch/onboarding/navigation/OnBoardingNavigation.kt b/feature/onboarding/src/main/java/com/moya/funch/onboarding/navigation/OnBoardingNavigation.kt index 48ccd658..6dfac6ff 100644 --- a/feature/onboarding/src/main/java/com/moya/funch/onboarding/navigation/OnBoardingNavigation.kt +++ b/feature/onboarding/src/main/java/com/moya/funch/onboarding/navigation/OnBoardingNavigation.kt @@ -1,11 +1,22 @@ package com.moya.funch.onboarding.navigation +import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.NavOptionsBuilder import androidx.navigation.compose.composable +import androidx.navigation.navOptions import com.moya.funch.onboarding.OnBoardingScreen const val ON_BOARDING_ROUTE = "on_boarding" +fun NavController.navigateToOnBoarding(navOptions: NavOptions? = null) = navigate(ON_BOARDING_ROUTE, navOptions) + +fun NavController.navigateToOnBoarding(navAction: NavOptionsBuilder.() -> Unit) = navigate( + ON_BOARDING_ROUTE, + navOptions(navAction) +) + fun NavGraphBuilder.onBoardingScreen(onNavigateToCreateProfile: () -> Unit) { composable(route = ON_BOARDING_ROUTE) { OnBoardingScreen(onNavigateToCreateProfile = onNavigateToCreateProfile) diff --git a/feature/profile/src/main/java/com/moya/funch/CreatePofileViewModel.kt b/feature/profile/src/main/java/com/moya/funch/CreatePofileViewModel.kt index aff0f376..12a6b984 100644 --- a/feature/profile/src/main/java/com/moya/funch/CreatePofileViewModel.kt +++ b/feature/profile/src/main/java/com/moya/funch/CreatePofileViewModel.kt @@ -29,7 +29,7 @@ data class CreateProfileUiState( ) internal sealed class CreateProfileEvent { - data object NavigateToHome : CreateProfileEvent() + data class NavigateToHome(val message: String) : CreateProfileEvent() data class ShowError(val message: String) : CreateProfileEvent() } @@ -165,7 +165,7 @@ internal class CreateProfileViewModel @Inject constructor( ) ) createUserProfileUseCase(profile).onSuccess { - _event.emit(CreateProfileEvent.NavigateToHome) + _event.emit(CreateProfileEvent.NavigateToHome("프로필을 생성했어요")) }.onFailure { _uiState.update { currentState -> currentState.copy(isLoading = false) } _event.emit(CreateProfileEvent.ShowError(it.message ?: "Error")) diff --git a/feature/profile/src/main/java/com/moya/funch/CreateProflieScreen.kt b/feature/profile/src/main/java/com/moya/funch/CreateProflieScreen.kt index 67406cfd..bf2838e4 100644 --- a/feature/profile/src/main/java/com/moya/funch/CreateProflieScreen.kt +++ b/feature/profile/src/main/java/com/moya/funch/CreateProflieScreen.kt @@ -1,5 +1,6 @@ package com.moya.funch +import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.ScrollState import androidx.compose.foundation.background @@ -18,8 +19,10 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions @@ -30,6 +33,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -41,8 +45,10 @@ import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.boundsInWindow +import androidx.compose.ui.layout.boundsInRoot import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle @@ -85,15 +91,18 @@ import com.moya.funch.uimodel.MbtiItem import com.moya.funch.uimodel.ProfileLabel import com.moya.funch.uimodel.ProfileUiModel import com.moya.funch.uimodel.SubwayTextFieldState +import kotlinx.coroutines.delay @Composable internal fun CreateProfileRoute(onNavigateToHome: () -> Unit, viewModel: CreateProfileViewModel = hiltViewModel()) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val context = LocalContext.current LaunchedEffect(Unit) { viewModel.event.collect { event -> when (event) { is CreateProfileEvent.NavigateToHome -> { + Toast.makeText(context, event.message, Toast.LENGTH_SHORT).show() onNavigateToHome() } @@ -147,14 +156,31 @@ fun CreateProfileScreen( onSendFeedback: () -> Unit ) { val scrollState = rememberScrollState() + val focusManager = LocalFocusManager.current val backgroundColor = LocalBackgroundTheme.current.color var isKeyboardVisible by remember { mutableStateOf(false) } - val focusManager = LocalFocusManager.current + var topBarHeight by remember { mutableFloatStateOf(0f) } + val bloodDropDownMenuHeight = 192.dp + val bloodTypes = Blood.entries.filterNot { it == Blood.IDLE }.map { it.type } + var bloodTypePlaceHolder by remember { mutableStateOf(bloodTypes[0]) } + var bloodButtonRect by remember { mutableStateOf(Rect.Zero) } + var isBloodDropDownMenuExpanded by remember { mutableStateOf(false) } Scaffold( + modifier = Modifier + .pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + isBloodDropDownMenuExpanded = false + }) + }, topBar = { FunchTopBar( - modifier = Modifier.padding(end = 20.dp), + modifier = Modifier + .padding(end = 20.dp) + .onGloballyPositioned { layoutCoordinates -> + topBarHeight = layoutCoordinates.boundsInRoot().height + }, leadingIcon = null, onClickTrailingIcon = onSendFeedback ) @@ -172,52 +198,76 @@ fun CreateProfileScreen( ) { padding -> Column( modifier = Modifier - .pointerInput(Unit) { - detectTapGestures(onTap = { - focusManager.clearFocus() - }) - } .fillMaxSize() .verticalScroll(state = scrollState) .padding(padding) ) { - Column(modifier = Modifier.padding(horizontal = 20.dp)) { - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(id = R.string.create_profile_title), - color = White, - style = FunchTheme.typography.t2 - ) - Spacer(modifier = Modifier.height(2.dp)) - Text( - text = stringResource(id = R.string.create_profile_sub_title), - color = Gray300, - style = FunchTheme.typography.b - ) - Spacer(modifier = Modifier.height(24.dp)) - NicknameRow( - nickname = profile.name, - onNicknameChange = onNicknameChange, - isKeyboardVisible = { isKeyboardVisible = it } - ) - Spacer(modifier = Modifier.height(14.dp)) - Column( - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - JobRow(profile = profile, onSelected = onSelectJob) - ClubRow(onSelectClub = onSelectClub) - MbtiRow(profile = profile, onSelectMbti = onSelectMbti) - BooldTypeRow(onSelectBloodType = onSelectBloodType) - SubwayRow( - subwayStation = profile.subway, - onSubwayStationChange = onSubwayStationChange, - isKeyboardVisible = { isKeyboardVisible = it }, - textFieldState = profile.subwayTextFieldState, - subwayStations = profile.subwayStations, - scrollState = scrollState + Box { + Column(modifier = Modifier.padding(horizontal = 20.dp)) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = stringResource(id = R.string.create_profile_title), + color = White, + style = FunchTheme.typography.t2 + ) + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = stringResource(id = R.string.create_profile_sub_title), + color = Gray300, + style = FunchTheme.typography.b + ) + Spacer(modifier = Modifier.height(24.dp)) + NicknameRow( + nickname = profile.name, + onNicknameChange = onNicknameChange, + isKeyboardVisible = { isKeyboardVisible = it } ) + Spacer(modifier = Modifier.height(14.dp)) + Column( + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + JobRow(profile = profile, onSelected = onSelectJob) + ClubRow(onSelectClub = onSelectClub) + MbtiRow(profile = profile, onSelectMbti = onSelectMbti) + BooldTypeRow( + isExpended = isBloodDropDownMenuExpanded, + placeHolder = bloodTypePlaceHolder, + onClickBloodButton = { isClicked -> isBloodDropDownMenuExpanded = isClicked }, + buttonOffset = { rect -> bloodButtonRect = rect } + ) + SubwayRow( + subwayStation = profile.subway, + onSubwayStationChange = onSubwayStationChange, + isKeyboardVisible = { isKeyboardVisible = it }, + textFieldState = profile.subwayTextFieldState, + subwayStations = profile.subwayStations, + scrollState = scrollState + ) + } + Spacer(modifier = Modifier.height(20.dp)) + } + if (isBloodDropDownMenuExpanded) { + Box( + modifier = Modifier + .offset( + x = with(LocalDensity.current) { bloodButtonRect.left.toDp() }, + y = with(LocalDensity.current) { + bloodButtonRect.top.toDp() - topBarHeight.toDp() - bloodDropDownMenuHeight - 8.dp + } + ) + .width(with(LocalDensity.current) { bloodButtonRect.width.toDp() }) + .height(bloodDropDownMenuHeight) + ) { + FunchDropDownMenu( + items = bloodTypes, + onItemSelected = { bloodType -> + onSelectBloodType(Blood.of(bloodType)) + bloodTypePlaceHolder = bloodType + isBloodDropDownMenuExpanded = false + } + ) + } } - Spacer(modifier = Modifier.height(20.dp)) } if (isKeyboardVisible) { BottomBar( @@ -450,39 +500,32 @@ private fun MbtiButton(mbtiItem: MbtiItem, isSelected: Boolean, onSelected: (Mbt } @Composable -private fun BooldTypeRow(onSelectBloodType: (Blood) -> Unit, focusManager: FocusManager = LocalFocusManager.current) { - val bloodTypes = Blood.entries.filterNot { it == Blood.IDLE }.map { it.type } - var placeHolder by remember { mutableStateOf(bloodTypes[0]) } - var isDropDownMenuExpanded by remember { mutableStateOf(false) } - val buttonBounds = remember { mutableStateOf(Rect.Zero) } +private fun BooldTypeRow( + isExpended: Boolean, + placeHolder: String, + buttonOffset: (Rect) -> Unit, + onClickBloodButton: (Boolean) -> Unit +) { + val focusManager = LocalFocusManager.current + val isPositioned = remember { mutableStateOf(false) } Row { FunchLargeLabel(text = ProfileLabel.BLOOD_TYPE.labelName) - Box { - FunchDropDownButton( - placeHolder = placeHolder, - onClick = { - focusManager.clearFocus() - isDropDownMenuExpanded = !isDropDownMenuExpanded - }, - isDropDownMenuExpanded = isDropDownMenuExpanded, - indication = null, - modifier = Modifier.onGloballyPositioned { coordinates -> - buttonBounds.value = coordinates.boundsInWindow() + FunchDropDownButton( + placeHolder = placeHolder, + onClick = { + focusManager.clearFocus() + onClickBloodButton(!isExpended) + }, + isDropDownMenuExpanded = isExpended, + indication = null, + modifier = Modifier.onGloballyPositioned { layoutCoordinates -> + if (!isPositioned.value) { + isPositioned.value = true + buttonOffset(layoutCoordinates.boundsInRoot()) } - ) - if (isDropDownMenuExpanded) { - FunchDropDownMenu( - items = bloodTypes, - buttonBounds = buttonBounds.value, - onItemSelected = { bloodType -> - onSelectBloodType(Blood.of(bloodType)) - placeHolder = bloodType - isDropDownMenuExpanded = false - } - ) } - } + ) } } @@ -501,13 +544,14 @@ private fun SubwayRow( if (isFocused) { LaunchedEffect(subwayStation) { + delay(100) scrollState.animateScrollTo(scrollState.maxValue) } } Row { FunchLargeLabel(text = ProfileLabel.SUBWAY.labelName) - Column(modifier = Modifier.height(97.dp)) { + Column(modifier = Modifier.height(101.dp)) { FunchIconTextField( modifier = Modifier.onFocusChanged { focusState -> isKeyboardVisible(focusState.isFocused) @@ -579,12 +623,11 @@ private fun HorizontalSubwayStations( ) { val focusManager = LocalFocusManager.current - Spacer(modifier = Modifier.height(4.dp)) + Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier .fillMaxWidth() - .horizontalScroll(rememberScrollState()), - horizontalArrangement = Arrangement.spacedBy(4.dp) + .horizontalScroll(rememberScrollState()) ) { subwayStations.forEach { station -> val annotatedText = buildAnnotatedString { diff --git a/feature/profile/src/main/java/com/moya/funch/MyProfileScreen.kt b/feature/profile/src/main/java/com/moya/funch/MyProfileScreen.kt index 2ac76fc0..edb24c7d 100644 --- a/feature/profile/src/main/java/com/moya/funch/MyProfileScreen.kt +++ b/feature/profile/src/main/java/com/moya/funch/MyProfileScreen.kt @@ -65,14 +65,14 @@ import com.moya.funch.uimodel.ProfileLabel internal fun MyProfileRoute( viewModel: MyProfileViewModel = hiltViewModel(), onCloseMyProfile: () -> Unit, - onNavigateCreateProfile: () -> Unit + onDeleteMyProfile: () -> Unit ) { val uiState = viewModel.uiState.collectAsState().value LaunchedEffect(Unit) { viewModel.event.collect { event -> if (event is MyProfileEvent.DeleteProfile) { - onNavigateCreateProfile() + onDeleteMyProfile() } } } diff --git a/feature/profile/src/main/java/com/moya/funch/navigation/MyProfileNavigatoin.kt b/feature/profile/src/main/java/com/moya/funch/navigation/MyProfileNavigatoin.kt index d737a68e..39cf90af 100644 --- a/feature/profile/src/main/java/com/moya/funch/navigation/MyProfileNavigatoin.kt +++ b/feature/profile/src/main/java/com/moya/funch/navigation/MyProfileNavigatoin.kt @@ -16,12 +16,10 @@ fun NavController.navigateToMyProfile(navOptions: NavOptions? = null) = fun NavController.navigateToCreateProfile(navOptions: NavOptions? = null) = navigate(ProfileScreens.Create.route, navOptions) -fun NavController.onCloseMyProfile() = popBackStack() - fun NavGraphBuilder.profileGraph( onNavigateToHome: () -> Unit, onCloseMyProfile: () -> Unit, - onNavigateCreateProfile: () -> Unit + onNavigateOnBoarding: () -> Unit ) { navigation( route = PROFILE_GRAPH_ROUTE, @@ -35,7 +33,7 @@ fun NavGraphBuilder.profileGraph( composable(route = ProfileScreens.MyProfile.route) { MyProfileRoute( onCloseMyProfile = onCloseMyProfile, - onNavigateCreateProfile = onNavigateCreateProfile + onDeleteMyProfile = onNavigateOnBoarding ) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 178022ec..98dfde7b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,8 +2,8 @@ compileSdk = "34" minSdk = "28" targetSdk = "34" -appVersion = "1.1.0" -versionCode = "10001" +appVersion = "1.2.0" +versionCode = "10002" # kotlin kotlin = "1.9.22" diff --git a/settings.gradle.kts b/settings.gradle.kts index 14caf443..c02923d3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,3 +32,4 @@ include(":feature:profile") include(":feature:home") include(":feature:match") include(":feature:onboarding") +include(":feature:collection")