├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── composeApp ├── build.gradle.kts └── src │ ├── androidMain │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── kotlin │ │ └── com │ │ │ └── osg │ │ │ └── openanimation │ │ │ ├── MainActivity.kt │ │ │ └── preview │ │ │ ├── AnimationDetailsViewAndroidPreview.kt │ │ │ ├── AnimationExploreScreenAndroidPreview.kt │ │ │ ├── AnimationReportPreview.kt │ │ │ ├── DownloadButtonIdlePreview.kt │ │ │ ├── LogoPreview.kt │ │ │ ├── ModalNavigationDrawerContentAndroidPreview.kt │ │ │ ├── color │ │ │ └── ColorsEditViewPreview.kt │ │ │ ├── profile │ │ │ └── ProfileEditorPreview.kt │ │ │ ├── tag │ │ │ └── TagsEditViewPreview.kt │ │ │ └── upload │ │ │ ├── AnimationUploadFormPreview.kt │ │ │ └── ModerationStatusPreview.kt │ └── res │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ └── values │ │ ├── ic_launcher_background.xml │ │ └── strings.xml │ ├── commonMain │ ├── composeResources │ │ └── files │ │ │ ├── loading_emo.json │ │ │ ├── os_99592_checkmark_p0.json │ │ │ ├── os_airplane_p0.json │ │ │ ├── os_bouncing_p0.json │ │ │ ├── os_darkmode_p0.json │ │ │ ├── os_dead_p0.json │ │ │ ├── os_dog_p0.json │ │ │ ├── os_loop_p0_p0.json │ │ │ ├── os_lottie_example_p0_p0.json │ │ │ ├── os_my_anim_p0.json │ │ │ └── os_pageLoad_p0.json │ └── kotlin │ │ └── com │ │ └── osg │ │ └── openanimation │ │ ├── basePreviewApp.kt │ │ └── repo │ │ ├── AnimationDataCollection.kt │ │ ├── AnimationMetadataRepositoryFake.kt │ │ ├── FakeAnimationContentLoader.kt │ │ ├── FakeAnimationInitialUpload.kt │ │ ├── FakeReportSubmissionService.kt │ │ ├── FakeRepositoryState.kt │ │ ├── FakeSignInProviderFactory.kt │ │ └── FakeUserRepo.kt │ ├── iosMain │ └── kotlin │ │ └── com │ │ └── osg │ │ └── openanimation │ │ └── MainViewController.kt │ ├── jsMain │ ├── kotlin │ │ └── main.kt │ └── resources │ │ ├── index.html │ │ ├── logo.png │ │ ├── privacy │ │ └── index.html │ │ ├── styles.css │ │ └── term │ │ └── index.html │ └── jvmMain │ └── kotlin │ └── com │ └── osg │ └── openanimation │ └── main.kt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp ├── Configuration │ └── Config.xcconfig ├── StLaunchScreen.storyboard ├── iosApp │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ └── app-icon-1024.png │ │ ├── Contents.json │ │ ├── background.imageset │ │ │ ├── Contents.json │ │ │ └── background.jpg │ │ └── sit_new_logo.imageset │ │ │ ├── Contents.json │ │ │ └── sit_full.png │ ├── ContentView.swift │ ├── Info.plist │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── iOSApp.swift └── openAnimationApp.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ └── contents.xcworkspacedata ├── readme_images ├── app-icon.png ├── drop_edit.gif ├── multiplatform_open-animation.png └── openanimation.gif └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .kotlin 3 | .gradle 4 | **/build/ 5 | xcuserdata 6 | !src/**/build/ 7 | local.properties 8 | .idea 9 | .DS_Store 10 | captures 11 | .externalNativeBuild 12 | .cxx 13 | *.xcodeproj/* 14 | !*.xcodeproj/project.pbxproj 15 | !*.xcodeproj/xcshareddata/ 16 | !*.xcodeproj/project.xcworkspace/ 17 | !*.xcworkspace/contents.xcworkspacedata 18 | **/xcshareddata/WorkspaceSettings.xcsettings 19 | /kotlin-js-store/package-lock.json 20 | /kotlin-js-store/wasm/package-lock.json 21 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "core"] 2 | path = core 3 | url = https://github.com/orispok/OpenAnimationCore.git 4 | [submodule "compottie"] 5 | path = compottie 6 | url = https://github.com/orispok/compottie.git 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 OpenAnimationApp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | OpenAnimation Logo 3 | 4 |
5 | 6 |

OpenAnimation

7 | 8 |

9 | ✨ Check out the live web version: openanimation.web.app 10 |

11 | 12 |

13 | Discover and draw inspiration from a curated collection of beautiful Lottie animations, all powered by Kotlin Multiplatform. 14 |

15 | 16 |
17 |
18 | Badge Android 19 | Badge iOS 20 | Badge JVM 21 | Badge JS 22 |
23 |
24 |
25 | OpenAnimation Multiplatform 26 |
27 | OpenAnimation Demo 28 |
29 |
30 | 31 | ## 🔥 New Features 32 | Drag and drop and color palette editing 33 | 34 | ## 🙏 Libraries Used 35 | - [Compottie](https://github.com/alexzhirkevich/compottie) 36 | - [Koin](https://github.com/InsertKoinIO/koin) 37 | - [Kotlin Multiplatform](https://kotlinlang.org/docs/multiplatform.html) 38 | 39 | 40 | ## Contributing 41 | 42 | Contributions are welcome! Please feel free to submit a Pull Request. 43 | 44 | ## License 45 | 46 | This project is licensed under the MIT License - see the LICENSE file for details. 47 | 48 | ## 🚀 Roadmap & TODO 49 | 50 | ### Features 51 | - [x] 🎨 **Animation Color Scheme Picker** - Add ability for users to customize animation color palettes 52 | - [x] 👥 **Community Animations** - Implement support for user-submitted animations with voting system 53 | - [ ] ⚡ **Rendering Optimization** - Improve animation playback performance across platforms 54 | - [ ] 📊 **Performance Metrics** - Add analytics for rendering times and resource usage -------------------------------------------------------------------------------- /composeApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | import org.jetbrains.compose.desktop.application.dsl.TargetFormat 3 | import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi 4 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget 5 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask 6 | 7 | plugins { 8 | alias(libs.plugins.kotlinMultiplatform) 9 | alias(libs.plugins.androidApplication) 10 | alias(libs.plugins.composeMultiplatform) 11 | alias(libs.plugins.composeCompiler) 12 | // alias(libs.plugins.composeHotReload) 13 | 14 | alias(libs.plugins.ksp) 15 | } 16 | 17 | 18 | kotlin { 19 | js(IR){ 20 | browser { 21 | commonWebpackConfig { 22 | outputFileName = "openAnimation.js" 23 | } 24 | } 25 | binaries.executable() 26 | } 27 | androidTarget { 28 | @OptIn(ExperimentalKotlinGradlePluginApi::class) 29 | compilerOptions { 30 | jvmTarget.set(JvmTarget.JVM_11) 31 | } 32 | } 33 | listOf( 34 | iosArm64(), 35 | iosSimulatorArm64() 36 | ).forEach { iosTarget -> 37 | iosTarget.binaries.framework { 38 | baseName = "ComposeApp" 39 | isStatic = true 40 | } 41 | } 42 | jvm() 43 | sourceSets { 44 | androidMain.dependencies { 45 | implementation(compose.preview) 46 | implementation(libs.androidx.activity.compose) 47 | } 48 | commonMain { 49 | kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") 50 | dependencies { 51 | implementation(projects.core.data) 52 | implementation(projects.core.ui) 53 | implementation(compose.runtime) 54 | implementation(compose.foundation) 55 | implementation(compose.ui) 56 | implementation(compose.components.resources) 57 | 58 | implementation(libs.material3) 59 | implementation(libs.material3.navigation.suite) 60 | implementation(libs.androidx.navigation.compose) 61 | 62 | implementation(libs.material.icons.core) 63 | implementation(libs.androidx.lifecycle.viewmodel) 64 | implementation(libs.androidx.lifecycle.runtime.compose) 65 | implementation(project.dependencies.platform(libs.koin.bom)) 66 | implementation(libs.koin.core) 67 | } 68 | } 69 | jvmMain.dependencies { 70 | implementation(compose.desktop.currentOs) 71 | implementation(libs.kotlinx.coroutines.swing) 72 | } 73 | } 74 | } 75 | 76 | ksp { 77 | arg("KOIN_USE_COMPOSE_VIEWMODEL","true") 78 | arg("KOIN_CONFIG_CHECK","true") 79 | arg("KOIN_DEFAULT_MODULE","true") 80 | } 81 | 82 | dependencies { 83 | add("kspCommonMainMetadata", libs.koin.ksp.compiler) 84 | } 85 | 86 | project.tasks.withType(KotlinCompilationTask::class.java).configureEach { 87 | if(name != "kspCommonMainKotlinMetadata") { 88 | dependsOn("kspCommonMainKotlinMetadata") 89 | } 90 | } 91 | 92 | 93 | android { 94 | namespace = "org.osg.openanimation" 95 | compileSdk = libs.versions.android.targetSdk.get().toInt() 96 | 97 | defaultConfig { 98 | applicationId = "org.osg.openanimation" 99 | minSdk = libs.versions.android.minSdk.get().toInt() 100 | targetSdk = libs.versions.android.targetSdk.get().toInt() 101 | versionCode = 1 102 | versionName = "1.0" 103 | } 104 | packaging { 105 | resources { 106 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 107 | } 108 | } 109 | buildTypes { 110 | getByName("release") { 111 | isMinifyEnabled = false 112 | } 113 | } 114 | compileOptions { 115 | sourceCompatibility = JavaVersion.VERSION_11 116 | targetCompatibility = JavaVersion.VERSION_11 117 | } 118 | } 119 | 120 | 121 | dependencies { 122 | debugImplementation(compose.uiTooling) 123 | } 124 | 125 | afterEvaluate { 126 | // to avoid kotlinStorePackageLock failing 127 | val kotlinUpgradePackageLock = tasks.findByPath("::kotlinUpgradePackageLock")!! 128 | tasks.findByPath("::kotlinNpmInstall")!!.finalizedBy(kotlinUpgradePackageLock) 129 | } 130 | 131 | compose.desktop { 132 | application { 133 | mainClass = "org.osg.openanimation.MainKt" 134 | 135 | nativeDistributions { 136 | targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) 137 | packageName = "org.osg.openanimation" 138 | packageVersion = "1.0.0" 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/ic_launcher-playstore.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import org.koin.core.module.Module 9 | import org.koin.dsl.bind 10 | import org.koin.dsl.module 11 | 12 | class MainActivity : ComponentActivity() { 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | val basePreviewApp = getBaseApp( 16 | platformModules = listOf( 17 | androidActivityModule 18 | ) 19 | ) 20 | 21 | setContent { 22 | basePreviewApp.AppEntry() 23 | } 24 | } 25 | } 26 | 27 | val Activity.androidActivityModule: Module 28 | get() = module { 29 | single { this@androidActivityModule } bind Context::class 30 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/AnimationDetailsViewAndroidPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview 2 | 3 | import androidx.compose.foundation.layout.fillMaxSize 4 | import androidx.compose.foundation.layout.statusBarsPadding 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.runtime.LaunchedEffect 7 | import androidx.compose.runtime.collectAsState 8 | import androidx.compose.runtime.getValue 9 | import androidx.compose.runtime.mutableStateOf 10 | import androidx.compose.runtime.remember 11 | import androidx.compose.runtime.rememberCoroutineScope 12 | import androidx.compose.runtime.setValue 13 | import androidx.compose.ui.Modifier 14 | import androidx.compose.ui.graphics.Color 15 | import androidx.compose.ui.tooling.preview.Preview 16 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes 17 | import com.osg.openanimation.core.data.stats.AnimationStats 18 | import com.osg.openanimation.core.ui.color.model.ColorsEditHandler 19 | import com.osg.openanimation.core.ui.color.model.ColorsEditPalette 20 | import com.osg.openanimation.core.ui.components.lottie.AnimationDataState 21 | import com.osg.openanimation.core.ui.details.AnimationDetailsPanes 22 | import com.osg.openanimation.core.ui.details.model.ds.DetailsScreenStates 23 | import com.osg.openanimation.core.ui.details.model.ds.DetailsUiPane 24 | import com.osg.openanimation.core.ui.home.domain.ColorPaletteWithMetadata 25 | import com.osg.openanimation.core.ui.theme.TrueTheme 26 | import kotlinx.coroutines.delay 27 | 28 | @Preview(showBackground = true) 29 | @Composable 30 | fun AnimationDetailsPanesAndroidShimmerPreview() { 31 | var isClicked by remember { mutableStateOf(false) } 32 | var isLike by remember { mutableStateOf(true) } 33 | 34 | TrueTheme{ 35 | val a = generateAnimationUiDataList().last() 36 | val detailsScreenState = DetailsScreenStates.Success( 37 | detailsUiPane = DetailsUiPane( 38 | isLiked = isLike, 39 | animationUiData = ColorPaletteWithMetadata( 40 | metadata = a.metadata, 41 | editableAnimation = ColorsEditPalette( 42 | processedJsonState = AnimationDataState.Processing, 43 | options = listOf( 44 | listOf( 45 | Color(0xFF000000), 46 | Color(0xFFFFFFFF), 47 | Color(0xFFFF0000), 48 | Color(0xFF00FF00), 49 | ), 50 | listOf( 51 | Color(0xFF000000), 52 | Color(0xFFFFFFFF), 53 | Color(0xFFFF0000), 54 | Color(0xFF00FF00), 55 | ) 56 | ), 57 | ), 58 | ), 59 | animationStats = AnimationStats( 60 | downloadCount = 5, 61 | likeCount = 10, 62 | ), 63 | ), 64 | relatedAnimations = generateAnimationUiDataList().take(4), 65 | ) 66 | AnimationDetailsPanes( 67 | modifier = Modifier.fillMaxSize().statusBarsPadding(), 68 | detailsUiState = detailsScreenState, 69 | onLikeClick = { 70 | isClicked.not().also { 71 | isClicked = it 72 | } 73 | }, 74 | onDownloadClick = {}, 75 | onTagClick = {}, 76 | onRelatedAnimationClicked = {}, 77 | onDismissSignInDialog = {}, 78 | onPalletSelect = {}, 79 | ) 80 | 81 | LaunchedEffect(isClicked) { 82 | if (isClicked) { 83 | delay(700) 84 | isClicked = false 85 | isLike = !isLike 86 | } 87 | } 88 | } 89 | } 90 | 91 | @PreviewScreenSizes 92 | @Preview(showSystemUi = true) 93 | @Composable 94 | fun AnimationDetailsPanesAndroidPreview() { 95 | TrueTheme{ 96 | val a = generateAnimationUiDataList().last() 97 | val handler = ColorsEditHandler( 98 | path = a.metadata.localFileName, 99 | animationContentLoader = { hash -> 100 | val f = a.animationState as AnimationDataState.LazyLoading 101 | f.lazyLoader() 102 | }, 103 | scope = rememberCoroutineScope() 104 | ) 105 | val s by handler.uiState.collectAsState() 106 | val detailsScreenState = DetailsScreenStates.Success( 107 | detailsUiPane = DetailsUiPane( 108 | animationUiData = ColorPaletteWithMetadata( 109 | metadata = a.metadata, 110 | editableAnimation = s.copy( 111 | processedJsonState = AnimationDataState.Processing, 112 | options = s.options + s.options, 113 | ), 114 | ), 115 | animationStats = AnimationStats( 116 | downloadCount = 5, 117 | likeCount = 10, 118 | ), 119 | ), 120 | relatedAnimations = generateAnimationUiDataList().take(4), 121 | ) 122 | AnimationDetailsPanes( 123 | modifier = Modifier.fillMaxSize(), 124 | detailsUiState = detailsScreenState, 125 | onLikeClick = { 126 | true 127 | }, 128 | onDownloadClick = {}, 129 | onTagClick = {}, 130 | onRelatedAnimationClicked = {}, 131 | onDismissSignInDialog = {}, 132 | onPalletSelect = { index -> 133 | 134 | }, 135 | ) 136 | } 137 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/AnimationExploreScreenAndroidPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.getValue 5 | import androidx.compose.runtime.mutableStateOf 6 | import androidx.compose.runtime.remember 7 | import androidx.compose.runtime.setValue 8 | import androidx.compose.ui.tooling.preview.PreviewLightDark 9 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes 10 | import com.osg.openanimation.core.data.animation.AnimationCategory 11 | import com.osg.openanimation.core.ui.components.lottie.AnimationDataState 12 | import com.osg.openanimation.core.ui.graph.SelectedQueryType 13 | import com.osg.openanimation.core.ui.home.domain.AnimationUiData 14 | import com.osg.openanimation.core.ui.home.domain.ExploreScreenStates 15 | import com.osg.openanimation.core.ui.home.ui.AnimationGrid 16 | import com.osg.openanimation.core.ui.home.ui.strResource 17 | import com.osg.openanimation.core.ui.theme.TrueTheme 18 | import com.osg.openanimation.core.ui.util.resource.string 19 | import com.osg.openanimation.repo.AnimationDataCollection 20 | import com.osg.openanimation.repo.fromLocaleStorage 21 | 22 | 23 | @Composable 24 | fun generateAnimationUiDataList(): List { 25 | val animations = AnimationDataCollection.entries.take(20) 26 | var animationState by remember { mutableStateOf( 27 | animations.map { 28 | AnimationDataState.LazyLoading(it.metadata.hash){ 29 | it.fromLocaleStorage() 30 | } 31 | } 32 | ) } 33 | 34 | return animations.zip(animationState) { it, state -> 35 | AnimationUiData( 36 | animationState = state, 37 | metadata = it.metadata, 38 | ) 39 | } 40 | } 41 | 42 | @PreviewLightDark 43 | @PreviewScreenSizes 44 | @Composable 45 | fun AnimationExploreScreenAndroidPreview() { 46 | TrueTheme { 47 | AnimationGrid( 48 | screenData = ExploreScreenStates.Success( 49 | animations = generateAnimationUiDataList(), 50 | categories = AnimationCategory.entries.map { 51 | SelectedQueryType.Tag(it.strResource.string) 52 | }, 53 | selected = SelectedQueryType.ExploreCategory.Explore 54 | ), 55 | onDestination = {}, 56 | ) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/AnimationReportPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.tooling.preview.Preview 5 | import com.osg.openanimation.core.ui.components.report.AnimationReportContent 6 | import com.osg.openanimation.core.data.animation.AnimationMetadata 7 | 8 | /** 9 | * Preview for Animation Report Dialog 10 | */ 11 | @Preview( 12 | name = "Animation Report Dialog", 13 | showBackground = true, 14 | backgroundColor = 0xFFFFFFFF 15 | ) 16 | @Composable 17 | fun AnimationReportPreview() { 18 | val sampleMetadata = AnimationMetadata( 19 | name = "Sample Animation", 20 | author = "John Doe", 21 | description = "This is a sample animation for preview purposes", 22 | hash = "abc123hash456", 23 | tags = setOf("Preview", "Sample", "Testing"), 24 | ) 25 | 26 | AnimationReportContent( 27 | animationMetadata = sampleMetadata, 28 | onReportClick = { /* Preview only */ }, 29 | onDismiss = { /* Preview only */ } 30 | ) 31 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/DownloadButtonIdlePreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview 2 | 3 | import androidx.compose.material.icons.Icons 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.runtime.LaunchedEffect 6 | import androidx.compose.runtime.getValue 7 | import androidx.compose.runtime.mutableStateOf 8 | import androidx.compose.runtime.remember 9 | import androidx.compose.runtime.setValue 10 | import androidx.compose.ui.tooling.preview.Preview 11 | import com.osg.openanimation.core.ui.details.CopyLinkToClipboardButton 12 | import com.osg.openanimation.core.ui.details.IconLoadingButton 13 | import com.osg.openanimation.core.ui.util.icons.Download 14 | 15 | @Preview(showBackground = true) 16 | @Composable 17 | fun DownloadButtonIdlePreview() { 18 | var isDownloadedTransitionState by remember { mutableStateOf(false) } 19 | IconLoadingButton( 20 | isDownloadedTransition = isDownloadedTransitionState, 21 | primaryIcon = Icons.Default.Download, 22 | onClick = { 23 | isDownloadedTransitionState = !isDownloadedTransitionState 24 | } 25 | ) 26 | LaunchedEffect(isDownloadedTransitionState) { 27 | if (isDownloadedTransitionState) { 28 | // Simulate a delay for the download transition 29 | kotlinx.coroutines.delay(2000) 30 | isDownloadedTransitionState = false // Reset to idle state after transition 31 | } 32 | } 33 | } 34 | 35 | 36 | @Preview(showBackground = true) 37 | @Composable 38 | fun CopyLinkToClipboardButtonPreview() { 39 | CopyLinkToClipboardButton( 40 | generateLink = { "https://example.com" } 41 | ) 42 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/LogoPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview 2 | 3 | import androidx.compose.foundation.Image 4 | import androidx.compose.foundation.layout.Box 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.ui.Modifier 8 | import androidx.compose.ui.tooling.preview.Preview 9 | import androidx.compose.ui.unit.dp 10 | import com.osg.openanimation.core.ui.util.icons.brandingpack.LogoVector 11 | 12 | @Preview 13 | @Composable 14 | private fun Preview(): Unit { 15 | Box(modifier = Modifier.Companion.padding(12.dp)) { 16 | Image(imageVector = LogoVector, contentDescription = "") 17 | } 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/ModalNavigationDrawerContentAndroidPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.tooling.preview.Preview 5 | import com.osg.openanimation.core.ui.components.bar.ModalNavigationDrawerContent 6 | import com.osg.openanimation.core.ui.theme.TrueTheme 7 | 8 | @Preview 9 | @Composable 10 | private fun ModalNavigationDrawerContentAndroidPreview() { 11 | TrueTheme { 12 | ModalNavigationDrawerContent( 13 | currentDestination = null, 14 | isDarkMode = false, 15 | onRailDst = {}, 16 | ) 17 | } 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/color/ColorsEditViewPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview.color 2 | 3 | import androidx.compose.foundation.background 4 | import androidx.compose.foundation.layout.Column 5 | import androidx.compose.foundation.layout.fillMaxWidth 6 | import androidx.compose.foundation.layout.height 7 | import androidx.compose.foundation.layout.padding 8 | import androidx.compose.material3.Scaffold 9 | import androidx.compose.runtime.Composable 10 | import androidx.compose.ui.Modifier 11 | import androidx.compose.ui.graphics.Color 12 | import androidx.compose.ui.tooling.preview.Preview 13 | import androidx.compose.ui.unit.dp 14 | import com.osg.openanimation.core.ui.color.ui.ColorPaletteOptionsView 15 | 16 | @Preview 17 | @Composable 18 | fun ColorsEditViewPreview() { 19 | Scaffold( 20 | modifier = Modifier 21 | .background(color = Color.White) 22 | .fillMaxWidth() 23 | .height(400.dp) 24 | ){ 25 | Column { 26 | ColorsEditView( 27 | modifier = Modifier.padding(it), 28 | ) 29 | } 30 | 31 | } 32 | } 33 | 34 | @Composable 35 | fun ColorsEditView( 36 | modifier: Modifier = Modifier, 37 | ) { 38 | 39 | ColorPaletteOptionsView( 40 | modifier = modifier, 41 | transformOptions = listOf( 42 | listOf( 43 | Color(0xFF000000), 44 | Color(0xFFFFFFFF), 45 | Color(0xFFFF0000), 46 | Color(0xFF00FF00), 47 | ), 48 | listOf( 49 | Color(0xffff9a9e), 50 | Color(0xFFFFFFFF), 51 | Color(0xff0059ff), 52 | Color(0xff238d91), 53 | ) 54 | ), 55 | onPalletSelect = {}, 56 | selectedIndex = 0, 57 | ) 58 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/profile/ProfileEditorPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview.profile 2 | 3 | import androidx.compose.material3.MaterialTheme 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes 6 | import com.osg.openanimation.core.ui.profile.state.ProfileScreenState 7 | import com.osg.openanimation.core.ui.profile.state.UserProfileUi 8 | import com.osg.openanimation.core.ui.profile.ui.ProfileEditorScreenWrapper 9 | 10 | @PreviewScreenSizes 11 | @Composable 12 | fun ProfileEditorPreview() { 13 | MaterialTheme { 14 | ProfileEditorScreenWrapper( 15 | profileScreenState = ProfileScreenState.Success( 16 | UserProfileUi( 17 | displayName = "John Doe", 18 | bio = "Software Developer", 19 | linkedinUrl = "https://www.linkedin.com/in/johndoe", 20 | githubUrl = "https://github.com/johndoe", 21 | ) 22 | ), 23 | saveProfile = { /* Save profile logic */ } 24 | ) 25 | } 26 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/tag/TagsEditViewPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview.tag 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.mutableStateOf 5 | import androidx.compose.runtime.remember 6 | import androidx.compose.ui.tooling.preview.Preview 7 | import com.osg.openanimation.core.ui.dashboard.TagsEditView 8 | 9 | @Preview 10 | @Composable 11 | fun TagsEditViewPreview() { 12 | val tags = remember { mutableStateOf(setOf("tag1", "tag2", "a long tag")) } 13 | TagsEditView( 14 | tags = tags.value, 15 | onTagsChange = { tags.value = it }, 16 | allTags = setOf("tag1", "tag2", "a long tag", "suggestion1", "suggestion2") 17 | ) 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/upload/AnimationUploadFormPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview.upload 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.Modifier 5 | import androidx.compose.ui.graphics.Color 6 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes 7 | import com.osg.openanimation.core.data.upload.ModerationStatus 8 | import com.osg.openanimation.core.data.upload.UploadedAnimationMeta 9 | import com.osg.openanimation.core.ui.color.model.ColorsEditPalette 10 | import com.osg.openanimation.core.ui.components.lottie.AnimationDataState 11 | import com.osg.openanimation.core.ui.dashboard.AnimationUploadForm 12 | 13 | @PreviewScreenSizes 14 | @Composable 15 | private fun AnimationUploadFormPreview( 16 | 17 | ) { 18 | AnimationUploadForm( 19 | modifier = Modifier, 20 | editableAnimation = ColorsEditPalette( 21 | processedJsonState = AnimationDataState.Processing, 22 | options = listOf( 23 | listOf( 24 | Color(0xFF000000), 25 | Color(0xFFFFFFFF), 26 | Color(0xFFFF0000), 27 | Color(0xFF00FF00), 28 | ), 29 | listOf( 30 | Color(0xFF000000), 31 | Color(0xFFFFFFFF), 32 | Color(0xFFFF0000), 33 | Color(0xFF00FF00), 34 | ) 35 | ), 36 | ), 37 | uploadedAnimationMeta = UploadedAnimationMeta( 38 | name = "Sample Animation", 39 | tags = listOf("tag1", "tag2"), 40 | hash = "samplehash", 41 | uploadTimestamp = 0L, 42 | description = "An example description for the sample animation.", 43 | path = "/path/to/animation.json", 44 | isSubmitted = false 45 | ), 46 | isUnsaved = true, 47 | moderationStatus = ModerationStatus.DRAFT, 48 | allTags = setOf("tag1", "tag2", "tag3", "example"), 49 | onPaletteSelected = {}, 50 | onUploadClick = {}, 51 | onTitleChanged = {}, 52 | onTagsChanged = {}, 53 | onRemovalClick = {}, 54 | onSaveClick = {} 55 | ) 56 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/com/osg/openanimation/preview/upload/ModerationStatusPreview.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.preview.upload 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.tooling.preview.Preview 5 | import com.osg.openanimation.core.data.upload.ModerationStatus 6 | import com.osg.openanimation.core.ui.dashboard.ModerationStatusView 7 | 8 | @Preview 9 | @Composable 10 | fun ModerationStatusViewPreview() { 11 | ModerationStatusView(status = ModerationStatus.APPROVED) 12 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 13 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F9F4EC 4 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | OpenAnimation 3 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/files/loading_emo.json: -------------------------------------------------------------------------------- 1 | {"v":"4.8.0","meta":{"g":"LottieFiles AE 3.4.5","a":"","k":"","d":"","tc":""},"fr":30,"ip":0,"op":38,"w":1080,"h":1080,"nm":"Comp 1","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 9","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":12.091,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":25.046,"s":[100]},{"t":38,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-176,-271,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":14,"op":134,"st":14,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 8","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":10.363,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":23.318,"s":[100]},{"t":36.2724609375,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-241,-90,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":12,"op":132,"st":12,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 7","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":8.637,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":21.591,"s":[100]},{"t":34.5458984375,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-165,92,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":130,"st":10,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 6","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":6.909,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":19.863,"s":[100]},{"t":32.818359375,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[18,167,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":128,"st":8,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 5","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":5.182,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":18.137,"s":[100]},{"t":31.0908203125,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[207,87,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":126,"st":6,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 4","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":3.454,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":16.409,"s":[100]},{"t":29.36328125,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[280,-90,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":124,"st":4,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 3","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":1.728,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":14.682,"s":[100]},{"t":27.63671875,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[194,-278,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":122,"st":2,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 2","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":12.954,"s":[100]},{"t":25.9091796875,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[18,-349,0],"ix":2},"a":{"a":0,"k":[0,-283,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-283],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":3,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":38,"s":[180]}],"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[18,-90,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"loading","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[133,133,100],"ix":6}},"ao":0,"w":1080,"h":1080,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Null 1","parent":8,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.704,"y":0.399},"o":{"x":0.388,"y":0},"t":0,"s":[-14,-44,0],"to":[3.441,-1.935,0],"ti":[-9.672,-12.724,0]},{"i":{"x":0.646,"y":0.635},"o":{"x":0.334,"y":0.27},"t":8.012,"s":[6.645,-55.613,0],"to":[9.681,12.736,0],"ti":[19.637,5.855,0]},{"i":{"x":0.61,"y":0.713},"o":{"x":0.29,"y":0.356},"t":15.333,"s":[-34,-13.677,0],"to":[-19.795,-5.902,0],"ti":[-5.403,2.732,0]},{"i":{"x":0.579,"y":1},"o":{"x":0.26,"y":0.59},"t":23.134,"s":[-36.581,-67.871,0],"to":[14.462,-7.312,0],"ti":[-3.763,-3.978,0]},{"t":38,"s":[-14,-44,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[64.516,64.516,100],"ix":6}},"ao":0,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,102,0],"ix":2},"a":{"a":0,"k":[8.5,121,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-66,121],[8,121],[83,121]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[{"i":[[0,0],[-50.134,-0.513],[0,0]],"o":[[0,0],[51.924,0.531],[0,0]],"v":[[-66,121],[9,142.5],[83,121]],"c":false}]},{"t":38,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-66,121],[8,121],[83,121]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":21,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 6","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.689,"y":0.411},"o":{"x":0.373,"y":0.011},"t":0,"s":[-81,-44,0],"to":[2.646,-1.75,0],"ti":[-7.964,-12.646,0]},{"i":{"x":0.647,"y":0.635},"o":{"x":0.325,"y":0.281},"t":7.812,"s":[-65.125,-54.5,0],"to":[7.105,11.28,0],"ti":[14.35,0.726,0]},{"i":{"x":0.601,"y":0.721},"o":{"x":0.284,"y":0.354},"t":13.832,"s":[-80.5,-21.5,0],"to":[-23.114,-1.169,0],"ti":[-14.322,4.271,0]},{"i":{"x":0.59,"y":0.993},"o":{"x":0.268,"y":0.589},"t":23.578,"s":[-96.5,-64,0],"to":[7.842,-2.339,0],"ti":[-2.583,-3.333,0]},{"t":38,"s":[-81,-44,0]}],"ix":2},"a":{"a":0,"k":[-81,-44,0],"ix":1},"s":{"a":0,"k":[45,45,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-81,-44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 3","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[72,-44,0],"ix":2},"a":{"a":0,"k":[-81,-44,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-81,-44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 5","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.69,"y":0.408},"o":{"x":0.372,"y":0.011},"t":0,"s":[-81,-44,0],"to":[2.333,-2.417,0],"ti":[-8.042,-7.958,0]},{"i":{"x":0.641,"y":0.634},"o":{"x":0.324,"y":0.273},"t":7.505,"s":[-67,-58.5,0],"to":[7.633,13.213,0],"ti":[23,1.625,0]},{"i":{"x":0.604,"y":0.722},"o":{"x":0.285,"y":0.359},"t":14.571,"s":[-81.5,-19.5,0],"to":[-19.081,-1.348,0],"ti":[-12.88,4.308,0]},{"i":{"x":0.592,"y":0.993},"o":{"x":0.269,"y":0.591},"t":23.842,"s":[-94,-63,0],"to":[12.208,-4.083,0],"ti":[-2.167,-3.167,0]},{"t":38,"s":[-81,-44,0]}],"ix":2},"a":{"a":0,"k":[-81,-44,0],"ix":1},"s":{"a":0,"k":[45,45,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-81,-44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 2","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-81,-44,0],"ix":2},"a":{"a":0,"k":[-81,-44,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[94,94],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-81,-44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[-14,-44,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[117,117,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":19,"s":[153,153,100]},{"t":38,"s":[117,117,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[280,280],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235294118,0.729447607901,0.321660868327,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-14,-44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/files/os_airplane_p0.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.7","fr":30,"ip":0,"op":90,"w":800,"h":800,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"earth-globe Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":0,"k":[60.938,60.938,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.596,0],[9.007,-0.959],[0,0],[-6.492,-2.161],[-1.298,0],[-1.726,5.186],[0,0]],"o":[[-9.261,0],[0,0],[-2.161,6.492],[1.298,0.435],[5.185,0],[0,0],[-1.589,-0.029]],"v":[[12.835,-18.58],[-14.571,-17.103],[-15.431,2.274],[-7.6,17.943],[-3.681,18.58],[8.069,10.113],[17.592,-18.46]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.567452225031,0.807680257161,0.292991548426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[243.165,18.58],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-23.248,-34.869],[0,0],[3.69,3.559],[0,0]],"o":[[0,0],[0.571,-5.095],[0,0],[3.748,44.083]],"v":[[17.078,59.925],[24.224,-4.989],[19.277,-18.714],[-24.795,-59.926]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.504892326804,0.774827186734,0.212474179735,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[25.795,337.885],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.252,-1.786],[0,0],[-4.323,-1.452],[-0.871,0],[-1.162,3.452],[0,0]],"o":[[0,0],[-1.452,4.323],[0.871,0.29],[3.452,0],[0,0],[-6.438,1.311]],"v":[[-5.106,-14.029],[-12.453,7.863],[-7.251,18.322],[-4.622,18.749],[3.209,13.12],[13.905,-18.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.567452225031,0.807680257161,0.292991548426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[190.679,23.92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.355,0],[1.548,1.298],[-2.936,3.492],[0,0],[-3.492,-2.936],[2.936,-3.492],[0,0]],"o":[[-1.871,0],[-3.492,-2.935],[0,0],[2.927,-3.484],[3.492,2.936],[0,0],[-1.63,1.943]],"v":[[-10.847,21.661],[-16.153,19.726],[-17.161,8.089],[4.516,-17.717],[16.153,-18.725],[17.161,-7.088],[-4.516,18.718]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.567452225031,0.807680257161,0.292991548426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[378.323,369.565],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[49.181,0],[0,141.385],[-24.039,39.005],[0,-92.205],[-141.385,0],[-45.069,73.127]],"o":[[-141.385,0],[0,-49.18],[-73.126,45.069],[0,141.385],[92.205,0],[-39.006,24.04]],"v":[[102.924,153.075],[-153.076,-102.925],[-115.141,-237.032],[-237.033,-18.968],[18.967,237.032],[237.033,115.139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.095535368078,0.652585257736,0.745653638653,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[237.033,274.968],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.782,-2.549],[1.589,0],[1.589,2.363],[0,0],[-3.783,2.549],[-2.541,-3.774],[0,0]],"o":[[-1.411,0.96],[-2.653,0],[0,0],[-2.556,-3.774],[3.766,-2.565],[0,0],[2.556,3.774]],"v":[[84.69,-64.466],[80.077,-63.047],[73.23,-66.684],[56.028,-92.144],[58.246,-103.604],[69.706,-101.386],[86.908,-75.926]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[127.331,14.776],[0,0],[8.072,-2.213],[0,0],[2.213,0],[0,0],[0.547,-4.102],[0,0],[0,0],[0.17,-4.263],[0,0],[-4.945,0.412],[0,0],[-2.538,3.539],[0,0],[0,0],[2.593,-6.66],[0,-1.314],[-4.564,0],[-0.661,3.887],[-3.302,8.376],[-2.072,-3.138],[0,0],[-6.9,1.915],[0,0],[-1.504,3.991],[0,0],[-5.546,1.145],[0,0],[-1.129,-6.525],[6.507,-0.746],[0,0],[0.111,-4.674],[0,0],[-1.574,-0.803],[0,0],[3.175,-4.67],[0,0],[3.107,0],[0,0],[1.697,0.669],[0,0],[3.416,-3.157],[0,0],[-1.437,-5.838],[0,0],[-7.261,-0.391],[0,0],[-1.128,-12.242],[0,0],[-1.669,-3.482],[-6.815,-8.619],[-7.286,6.634],[0,0],[-0.828,5.674],[0,0],[0,0],[4.994,2.143],[0,0],[3.645,-0.323],[0.645,0],[4.024,6.404],[0,0],[-3.855,2.435],[-2.435,-3.847],[0,0],[-2,0.161],[-0.742,0.492],[0,0],[3.079,3.865],[0,0],[2.729,-0.313],[0,0],[1.76,1.574],[0,0],[-3.04,3.403],[-3.411,-3.04],[0,0],[0,0],[-1.75,-2.404],[0,0],[0,0],[-3.225,-5.963],[0,0],[-4.063,-1.299],[0,0],[0,1.633]],"o":[[0,0],[-2.558,7.969],[0,0],[-2.134,0.585],[0,0],[-4.139,0],[0,0],[0,0],[-4.261,0.223],[0,0],[-0.198,4.959],[0,0],[4.34,-0.362],[0,0],[0,0],[7.142,-0.255],[-5.819,14.943],[0,4.565],[4.081,0],[0.564,-1.903],[1.379,-3.498],[0,0],[3.947,5.975],[0,0],[4.11,-1.14],[0,0],[1.997,-5.299],[0,0],[6.485,-1.338],[1.153,6.666],[0,0],[-4.673,0.126],[0,0],[-0.042,1.767],[0,0],[5.03,2.566],[0,0],[-1.747,2.569],[0,0],[-1.824,0],[0,0],[-4.328,-1.705],[0,0],[-4.415,4.081],[0,0],[1.738,7.061],[0,0],[12.277,0.66],[0,0],[0.354,3.844],[5.258,10.969],[8.774,11.097],[0,0],[4.24,-3.86],[0,0],[0,0],[3.924,-4.326],[0,0],[-3.056,2.048],[-0.645,0.056],[-7.468,0],[0,0],[-2.427,-3.863],[3.887,-2.411],[0,0],[1.056,1.694],[0.879,-0.081],[0,0],[4.333,-2.375],[0,0],[-1.712,-2.149],[0,0],[-2.346,0.27],[0,0],[-3.395,-3.04],[3.032,-3.403],[0,0],[0,0],[2.944,-0.363],[0,0],[0,0],[6.731,-0.808],[0,0],[2.029,3.752],[0,0],[0.03,-1.626],[0,-131.297]],"v":[[-22.251,-205.78],[-32.82,-172.852],[-49.858,-156.531],[-76.37,-149.262],[-82.921,-148.38],[-122.593,-148.38],[-130.778,-141.214],[-135.328,-107.09],[-160.668,-105.763],[-168.488,-97.845],[-169.365,-75.822],[-160.428,-67.263],[-143.546,-68.67],[-132.704,-74.819],[-117.091,-96.595],[-83.698,-97.788],[-74.103,-84.197],[-79.93,-66.66],[-71.672,-58.402],[-63.535,-65.257],[-57.147,-82.134],[-48.945,-83.009],[-46.81,-79.778],[-28.614,-72.968],[-13.868,-77.06],[-4.935,-85.225],[-2.107,-92.729],[10.009,-103.079],[19.539,-105.046],[34.029,-95.938],[23.991,-82.47],[1.012,-81.853],[-7.526,-73.288],[-7.578,-71.088],[-5.071,-66.883],[8.143,-60.141],[11.637,-46.509],[11.637,-46.509],[3.879,-42.403],[-65.814,-42.403],[-71.143,-43.415],[-129.625,-66.453],[-142.29,-64.078],[-197.676,-12.888],[-202.503,3.189],[-191.242,48.936],[-176.091,61.481],[-113.693,64.836],[-90.353,87.302],[-85.62,138.689],[-82.584,149.722],[-58.252,194.243],[-20.575,199.146],[30.159,157.631],[37.996,142.886],[43.94,102.114],[84.227,57.716],[81.395,44.614],[80.673,45.098],[70.447,48.711],[68.512,48.8],[50.093,38.606],[19.335,-10.233],[21.924,-21.628],[33.319,-19.039],[64.077,29.808],[69.004,32.26],[71.488,31.381],[113.063,8.597],[115.465,-3.349],[115.465,-3.349],[108.326,-6.3],[99.593,-5.296],[93.138,-7.347],[66.988,-30.739],[66.343,-42.4],[78.004,-43.045],[101.391,-22.126],[115.601,-23.763],[123.214,-20.432],[125.948,-16.69],[139.798,-18.352],[156.294,-9.81],[184.262,41.903],[193.756,49.776],[203.817,53.31],[203.94,48.439]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.567452225031,0.807680257161,0.292991548426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[308.06,207.563],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":4,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-141.385,0],[0,-141.385],[141.385,0],[0,141.385]],"o":[[141.385,0],[0,141.385],[-141.385,0],[0,-141.385]],"v":[[0,-256],[256,0],[0,256],[-256,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.360954135072,0.75495521695,0.790173040652,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"airplane Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[45]},{"t":89,"s":[405]}],"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[1173.671,1093.873,0],"ix":1},"s":{"a":0,"k":[21.267,21.267,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-24.205],[0,0],[0,5.186],[24.205,0],[4.586,-1.665]],"o":[[24.205,0],[0,0],[1.665,-4.602],[0,-24.205],[-5.186,0],[0,0]],"v":[[-29.216,-14.608],[14.608,29.216],[26.367,29.216],[29.216,14.608],[-14.608,-29.216],[-29.216,-26.368]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.280448524625,0.335915180281,0.385741349763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[447.837,64.163],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[65.736,-65.736],[0,0],[-65.736,65.736]],"o":[[0,0],[-65.736,65.736],[0,0],[65.736,-65.736]],"v":[[65.736,-65.736],[7.304,7.304],[-65.736,65.736],[-7.304,-7.304]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.280448524625,0.335915180281,0.385741349763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.764,378.236],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-29.217,29.216],[-14.608,-14.608],[29.216,-29.216],[0,0],[21.912,21.912],[0,0]],"o":[[29.216,-29.216],[14.608,14.608],[-29.216,29.216],[0,0],[-21.912,-21.912],[0,0]],"v":[[103.043,-190.691],[219.907,-219.907],[190.691,-103.043],[-86.862,159.902],[-203.726,203.726],[-159.902,86.862]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8117647058823529,0.8,0.8,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[286.362,225.638],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-43.824,0.569],[0,0],[-0.555,-43.824],[16.069,58.446],[0,0],[44.555,10.022]],"o":[[43.824,-0.569],[0,0],[0.555,43.824],[-16.069,-58.447],[0,0],[-58.359,-13.118]],"v":[[-163.198,-216.048],[202.003,-202.009],[216.055,163.192],[159.639,163.207],[85.138,-85.144],[-163.271,-159.676]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431372549,0.5450980392156862,0.36470588235294116,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[216.611,295.383],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-29.216,0],[0,0],[0,-29.216],[14.608,14.608],[0,0],[14.608,14.608]],"o":[[29.216,0],[0,0],[0,29.216],[-14.608,-14.608],[0,0],[-14.608,-14.608]],"v":[[-75.547,-99.75],[85.142,-85.142],[99.75,75.546],[55.926,90.154],[-2.506,2.506],[-90.155,-55.926]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431372549,0.5450980392156862,0.36470588235294116,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,412.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.711,5.726],[0,0],[-5.726,5.697],[0,0],[-5.711,-5.712],[0,0],[5.726,-5.711]],"o":[[-5.712,5.726],[0,0],[-5.726,-5.712],[0,0],[5.712,-5.712],[0,0],[5.726,5.697],[0,0]],"v":[[-0.001,41.304],[-20.656,41.304],[-41.311,20.649],[-41.311,-0.006],[0,-41.318],[20.656,-41.318],[41.312,-20.663],[41.312,-0.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.280448524625,0.335915180281,0.385741349763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[214.108,78.784],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.711,5.726],[0,0],[-5.726,5.697],[0,0],[-5.711,-5.712],[0,0],[5.727,-5.711]],"o":[[-5.712,5.726],[0,0],[-5.726,-5.712],[0,0],[5.712,-5.712],[0,0],[5.727,5.698],[0,0]],"v":[[0,41.304],[-20.656,41.304],[-41.311,20.649],[-41.311,-0.007],[0.001,-41.318],[20.656,-41.318],[41.311,-20.663],[41.311,-0.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.280448524625,0.335915180281,0.385741349763,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[433.229,297.9],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/files/os_bouncing_p0.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets": [ 3 | { 4 | "id": "comp_1", 5 | "layers": [ 6 | { 7 | "ao": 0, 8 | "bm": 0, 9 | "ddd": 0, 10 | "ind": 0, 11 | "ip": 0, 12 | "ks": { 13 | "a": { 14 | "a": 0, 15 | "k": [ 16 | -55.922, 17 | 214.156, 18 | 0 19 | ] 20 | }, 21 | "o": { 22 | "a": 0, 23 | "k": 100 24 | }, 25 | "p": { 26 | "s": true, 27 | "x": { 28 | "a": 0, 29 | "k": 960 30 | }, 31 | "y": { 32 | "a": 1, 33 | "k": [ 34 | { 35 | "e": [ 36 | 910.934 37 | ], 38 | "i": { 39 | "x": [ 40 | 0.96 41 | ], 42 | "y": [ 43 | 0.317 44 | ] 45 | }, 46 | "n": [ 47 | "0p96_0p317_0p453_0" 48 | ], 49 | "o": { 50 | "x": [ 51 | 0.453 52 | ], 53 | "y": [ 54 | 0 55 | ] 56 | }, 57 | "s": [ 58 | 372.934 59 | ], 60 | "t": 0 61 | }, 62 | { 63 | "e": [ 64 | 910.934 65 | ], 66 | "i": { 67 | "x": [ 68 | 0.491 69 | ], 70 | "y": [ 71 | 0.491 72 | ] 73 | }, 74 | "n": [ 75 | "0p491_0p491_0p405_0p405" 76 | ], 77 | "o": { 78 | "x": [ 79 | 0.405 80 | ], 81 | "y": [ 82 | 0.405 83 | ] 84 | }, 85 | "s": [ 86 | 910.934 87 | ], 88 | "t": 14 89 | }, 90 | { 91 | "e": [ 92 | 372.934 93 | ], 94 | "i": { 95 | "x": [ 96 | 0.328 97 | ], 98 | "y": [ 99 | 1 100 | ] 101 | }, 102 | "n": [ 103 | "0p328_1_0p02_0p674" 104 | ], 105 | "o": { 106 | "x": [ 107 | 0.02 108 | ], 109 | "y": [ 110 | 0.674 111 | ] 112 | }, 113 | "s": [ 114 | 910.934 115 | ], 116 | "t": 16 117 | }, 118 | { 119 | "t": 30 120 | } 121 | ] 122 | } 123 | }, 124 | "r": { 125 | "a": 0, 126 | "k": 0 127 | }, 128 | "s": { 129 | "a": 1, 130 | "k": [ 131 | { 132 | "e": [ 133 | 36.8, 134 | 54.9, 135 | 100 136 | ], 137 | "i": { 138 | "x": [ 139 | 0.833, 140 | 0.833, 141 | 0.833 142 | ], 143 | "y": [ 144 | 0.833, 145 | 0.833, 146 | 0.833 147 | ] 148 | }, 149 | "n": [ 150 | "0p833_0p833_0p167_0p167", 151 | "0p833_0p833_0p167_0p167", 152 | "0p833_0p833_0p167_0p167" 153 | ], 154 | "o": { 155 | "x": [ 156 | 0.167, 157 | 0.167, 158 | 0.167 159 | ], 160 | "y": [ 161 | 0.167, 162 | 0.167, 163 | 0.167 164 | ] 165 | }, 166 | "s": [ 167 | 43, 168 | 43, 169 | 100 170 | ], 171 | "t": 0 172 | }, 173 | { 174 | "e": [ 175 | 56.6, 176 | 27.5, 177 | 100 178 | ], 179 | "i": { 180 | "x": [ 181 | 0.833, 182 | 0.833, 183 | 0.833 184 | ], 185 | "y": [ 186 | 0.833, 187 | 0.833, 188 | 0.833 189 | ] 190 | }, 191 | "n": [ 192 | "0p833_0p833_0p167_0p167", 193 | "0p833_0p833_0p167_0p167", 194 | "0p833_0p833_0p167_0p167" 195 | ], 196 | "o": { 197 | "x": [ 198 | 0.167, 199 | 0.167, 200 | 0.167 201 | ], 202 | "y": [ 203 | 0.167, 204 | 0.167, 205 | 0.167 206 | ] 207 | }, 208 | "s": [ 209 | 36.8, 210 | 54.9, 211 | 100 212 | ], 213 | "t": 14 214 | }, 215 | { 216 | "e": [ 217 | 56.6, 218 | 27.5, 219 | 100 220 | ], 221 | "i": { 222 | "x": [ 223 | 0.833, 224 | 0.833, 225 | 0.833 226 | ], 227 | "y": [ 228 | 0.833, 229 | 0.833, 230 | 0.833 231 | ] 232 | }, 233 | "n": [ 234 | "0p833_0p833_0p167_0p167", 235 | "0p833_0p833_0p167_0p167", 236 | "0p833_0p833_0p167_0p167" 237 | ], 238 | "o": { 239 | "x": [ 240 | 0.167, 241 | 0.167, 242 | 0.167 243 | ], 244 | "y": [ 245 | 0.167, 246 | 0.167, 247 | 0.167 248 | ] 249 | }, 250 | "s": [ 251 | 56.6, 252 | 27.5, 253 | 100 254 | ], 255 | "t": 15 256 | }, 257 | { 258 | "e": [ 259 | 34.58, 260 | 45.3, 261 | 100 262 | ], 263 | "i": { 264 | "x": [ 265 | 0.833, 266 | 0.833, 267 | 0.833 268 | ], 269 | "y": [ 270 | 0.833, 271 | 0.833, 272 | 0.833 273 | ] 274 | }, 275 | "n": [ 276 | "0p833_0p833_0p167_0p167", 277 | "0p833_0p833_0p167_0p167", 278 | "0p833_0p833_0p167_0p167" 279 | ], 280 | "o": { 281 | "x": [ 282 | 0.167, 283 | 0.167, 284 | 0.167 285 | ], 286 | "y": [ 287 | 0.167, 288 | 0.167, 289 | 0.167 290 | ] 291 | }, 292 | "s": [ 293 | 56.6, 294 | 27.5, 295 | 100 296 | ], 297 | "t": 16 298 | }, 299 | { 300 | "e": [ 301 | 47.692, 302 | 41.258, 303 | 100 304 | ], 305 | "i": { 306 | "x": [ 307 | 0.833, 308 | 0.833, 309 | 0.833 310 | ], 311 | "y": [ 312 | 0.833, 313 | 0.833, 314 | 0.833 315 | ] 316 | }, 317 | "n": [ 318 | "0p833_0p833_0p167_0p167", 319 | "0p833_0p833_0p167_0p167", 320 | "0p833_0p833_0p167_0p167" 321 | ], 322 | "o": { 323 | "x": [ 324 | 0.167, 325 | 0.167, 326 | 0.167 327 | ], 328 | "y": [ 329 | 0.167, 330 | 0.167, 331 | 0.167 332 | ] 333 | }, 334 | "s": [ 335 | 34.58, 336 | 45.3, 337 | 100 338 | ], 339 | "t": 18 340 | }, 341 | { 342 | "e": [ 343 | 43, 344 | 43, 345 | 100 346 | ], 347 | "i": { 348 | "x": [ 349 | 0.833, 350 | 0.833, 351 | 0.833 352 | ], 353 | "y": [ 354 | 0.833, 355 | 0.833, 356 | 0.833 357 | ] 358 | }, 359 | "n": [ 360 | "0p833_0p833_0p167_0p167", 361 | "0p833_0p833_0p167_0p167", 362 | "0p833_0p833_0p167_0p167" 363 | ], 364 | "o": { 365 | "x": [ 366 | 0.167, 367 | 0.167, 368 | 0.167 369 | ], 370 | "y": [ 371 | 0.167, 372 | 0.167, 373 | 0.167 374 | ] 375 | }, 376 | "s": [ 377 | 47.692, 378 | 41.258, 379 | 100 380 | ], 381 | "t": 25 382 | }, 383 | { 384 | "t": 30 385 | } 386 | ] 387 | } 388 | }, 389 | "nm": "Shape Layer 4", 390 | "op": 150, 391 | "shapes": [ 392 | { 393 | "it": [ 394 | { 395 | "d": 1, 396 | "mn": "ADBE Vector Shape - Ellipse", 397 | "nm": "Ellipse Path 1", 398 | "p": { 399 | "a": 0, 400 | "k": [ 401 | 0, 402 | 0 403 | ] 404 | }, 405 | "s": { 406 | "a": 0, 407 | "k": [ 408 | 460.156, 409 | 460.156 410 | ] 411 | }, 412 | "ty": "el" 413 | }, 414 | { 415 | "c": { 416 | "a": 0, 417 | "k": [ 418 | 0.2, 419 | 0.77, 420 | 0.61, 421 | 1 422 | ] 423 | }, 424 | "lc": 1, 425 | "lj": 1, 426 | "ml": 4, 427 | "mn": "ADBE Vector Graphic - Stroke", 428 | "nm": "Stroke 1", 429 | "o": { 430 | "a": 0, 431 | "k": 100 432 | }, 433 | "ty": "st", 434 | "w": { 435 | "a": 0, 436 | "k": 0 437 | } 438 | }, 439 | { 440 | "c": { 441 | "a": 0, 442 | "k": [ 443 | 0.95, 444 | 0.31, 445 | 0.56, 446 | 1 447 | ] 448 | }, 449 | "mn": "ADBE Vector Graphic - Fill", 450 | "nm": "Fill 1", 451 | "o": { 452 | "a": 0, 453 | "k": 100 454 | }, 455 | "ty": "fl" 456 | }, 457 | { 458 | "a": { 459 | "a": 0, 460 | "ix": 1, 461 | "k": [ 462 | 0, 463 | 0 464 | ] 465 | }, 466 | "nm": "Transform", 467 | "o": { 468 | "a": 0, 469 | "ix": 7, 470 | "k": 100 471 | }, 472 | "p": { 473 | "a": 0, 474 | "ix": 2, 475 | "k": [ 476 | -55.922, 477 | -15.922 478 | ] 479 | }, 480 | "r": { 481 | "a": 0, 482 | "ix": 6, 483 | "k": 0 484 | }, 485 | "s": { 486 | "a": 0, 487 | "ix": 3, 488 | "k": [ 489 | 100, 490 | 100 491 | ] 492 | }, 493 | "sa": { 494 | "a": 0, 495 | "ix": 5, 496 | "k": 0 497 | }, 498 | "sk": { 499 | "a": 0, 500 | "ix": 4, 501 | "k": 0 502 | }, 503 | "ty": "tr" 504 | } 505 | ], 506 | "mn": "ADBE Vector Group", 507 | "nm": "Ellipse 1", 508 | "np": 3, 509 | "ty": "gr" 510 | } 511 | ], 512 | "sr": 1, 513 | "st": 0, 514 | "td": 1, 515 | "ty": 4 516 | }, 517 | { 518 | "ao": 0, 519 | "bm": 0, 520 | "ddd": 0, 521 | "ind": 1, 522 | "ip": 0, 523 | "ks": { 524 | "a": { 525 | "a": 0, 526 | "k": [ 527 | 7.73, 528 | -318.27, 529 | 0 530 | ] 531 | }, 532 | "o": { 533 | "a": 0, 534 | "k": 12 535 | }, 536 | "p": { 537 | "a": 1, 538 | "k": [ 539 | { 540 | "e": [ 541 | 59.033, 542 | -256.954, 543 | 0 544 | ], 545 | "i": { 546 | "x": 0.667, 547 | "y": 1 548 | }, 549 | "n": "0p667_1_0p333_0", 550 | "o": { 551 | "x": 0.333, 552 | "y": 0 553 | }, 554 | "s": [ 555 | 23.697, 556 | -140.59, 557 | 0 558 | ], 559 | "t": 0, 560 | "ti": [ 561 | 0, 562 | 0, 563 | 0 564 | ], 565 | "to": [ 566 | 0, 567 | 0, 568 | 0 569 | ] 570 | }, 571 | { 572 | "e": [ 573 | 23.697, 574 | -140.59, 575 | 0 576 | ], 577 | "i": { 578 | "x": 0.667, 579 | "y": 1 580 | }, 581 | "n": "0p667_1_0p333_0", 582 | "o": { 583 | "x": 0.333, 584 | "y": 0 585 | }, 586 | "s": [ 587 | 59.033, 588 | -256.954, 589 | 0 590 | ], 591 | "t": 15, 592 | "ti": [ 593 | 0, 594 | 0, 595 | 0 596 | ], 597 | "to": [ 598 | 0, 599 | 0, 600 | 0 601 | ] 602 | }, 603 | { 604 | "t": 30 605 | } 606 | ] 607 | }, 608 | "r": { 609 | "a": 0, 610 | "k": 0 611 | }, 612 | "s": { 613 | "a": 0, 614 | "k": [ 615 | 168.239, 616 | 178.473, 617 | 100 618 | ] 619 | } 620 | }, 621 | "nm": "Shape Layer 3", 622 | "op": 150, 623 | "parent": 2, 624 | "shapes": [ 625 | { 626 | "it": [ 627 | { 628 | "d": 1, 629 | "mn": "ADBE Vector Shape - Ellipse", 630 | "nm": "Ellipse Path 1", 631 | "p": { 632 | "a": 0, 633 | "k": [ 634 | 0, 635 | 0 636 | ] 637 | }, 638 | "s": { 639 | "a": 0, 640 | "k": [ 641 | 36.539, 642 | 36.539 643 | ] 644 | }, 645 | "ty": "el" 646 | }, 647 | { 648 | "c": { 649 | "a": 0, 650 | "k": [ 651 | 0.2, 652 | 0.77, 653 | 0.61, 654 | 1 655 | ] 656 | }, 657 | "lc": 1, 658 | "lj": 1, 659 | "ml": 4, 660 | "mn": "ADBE Vector Graphic - Stroke", 661 | "nm": "Stroke 1", 662 | "o": { 663 | "a": 0, 664 | "k": 100 665 | }, 666 | "ty": "st", 667 | "w": { 668 | "a": 0, 669 | "k": 0 670 | } 671 | }, 672 | { 673 | "c": { 674 | "a": 0, 675 | "k": [ 676 | 1, 677 | 1, 678 | 1, 679 | 1 680 | ] 681 | }, 682 | "mn": "ADBE Vector Graphic - Fill", 683 | "nm": "Fill 1", 684 | "o": { 685 | "a": 0, 686 | "k": 100 687 | }, 688 | "ty": "fl" 689 | }, 690 | { 691 | "a": { 692 | "a": 0, 693 | "ix": 1, 694 | "k": [ 695 | 0, 696 | 0 697 | ] 698 | }, 699 | "nm": "Transform", 700 | "o": { 701 | "a": 0, 702 | "ix": 7, 703 | "k": 100 704 | }, 705 | "p": { 706 | "a": 0, 707 | "ix": 2, 708 | "k": [ 709 | 7.73, 710 | -318.27 711 | ] 712 | }, 713 | "r": { 714 | "a": 0, 715 | "ix": 6, 716 | "k": 0 717 | }, 718 | "s": { 719 | "a": 0, 720 | "ix": 3, 721 | "k": [ 722 | 100, 723 | 100 724 | ] 725 | }, 726 | "sa": { 727 | "a": 0, 728 | "ix": 5, 729 | "k": 0 730 | }, 731 | "sk": { 732 | "a": 0, 733 | "ix": 4, 734 | "k": 0 735 | }, 736 | "ty": "tr" 737 | } 738 | ], 739 | "mn": "ADBE Vector Group", 740 | "nm": "Ellipse 1", 741 | "np": 3, 742 | "ty": "gr" 743 | } 744 | ], 745 | "sr": 1, 746 | "st": 0, 747 | "tt": 1, 748 | "ty": 4 749 | }, 750 | { 751 | "ao": 0, 752 | "bm": 0, 753 | "ddd": 0, 754 | "ind": 2, 755 | "ip": 0, 756 | "ks": { 757 | "a": { 758 | "a": 0, 759 | "k": [ 760 | -55.922, 761 | 214.156, 762 | 0 763 | ] 764 | }, 765 | "o": { 766 | "a": 0, 767 | "k": 100 768 | }, 769 | "p": { 770 | "s": true, 771 | "x": { 772 | "a": 0, 773 | "k": 960 774 | }, 775 | "y": { 776 | "a": 1, 777 | "k": [ 778 | { 779 | "e": [ 780 | 910.934 781 | ], 782 | "i": { 783 | "x": [ 784 | 0.96 785 | ], 786 | "y": [ 787 | 0.317 788 | ] 789 | }, 790 | "n": [ 791 | "0p96_0p317_0p453_0" 792 | ], 793 | "o": { 794 | "x": [ 795 | 0.453 796 | ], 797 | "y": [ 798 | 0 799 | ] 800 | }, 801 | "s": [ 802 | 372.934 803 | ], 804 | "t": 0 805 | }, 806 | { 807 | "e": [ 808 | 910.934 809 | ], 810 | "i": { 811 | "x": [ 812 | 0.491 813 | ], 814 | "y": [ 815 | 0.491 816 | ] 817 | }, 818 | "n": [ 819 | "0p491_0p491_0p405_0p405" 820 | ], 821 | "o": { 822 | "x": [ 823 | 0.405 824 | ], 825 | "y": [ 826 | 0.405 827 | ] 828 | }, 829 | "s": [ 830 | 910.934 831 | ], 832 | "t": 14 833 | }, 834 | { 835 | "e": [ 836 | 372.934 837 | ], 838 | "i": { 839 | "x": [ 840 | 0.328 841 | ], 842 | "y": [ 843 | 1 844 | ] 845 | }, 846 | "n": [ 847 | "0p328_1_0p02_0p674" 848 | ], 849 | "o": { 850 | "x": [ 851 | 0.02 852 | ], 853 | "y": [ 854 | 0.674 855 | ] 856 | }, 857 | "s": [ 858 | 910.934 859 | ], 860 | "t": 16 861 | }, 862 | { 863 | "t": 30 864 | } 865 | ] 866 | } 867 | }, 868 | "r": { 869 | "a": 0, 870 | "k": 0 871 | }, 872 | "s": { 873 | "a": 1, 874 | "k": [ 875 | { 876 | "e": [ 877 | 36.8, 878 | 54.9, 879 | 100 880 | ], 881 | "i": { 882 | "x": [ 883 | 0.833, 884 | 0.833, 885 | 0.833 886 | ], 887 | "y": [ 888 | 0.833, 889 | 0.833, 890 | 0.833 891 | ] 892 | }, 893 | "n": [ 894 | "0p833_0p833_0p167_0p167", 895 | "0p833_0p833_0p167_0p167", 896 | "0p833_0p833_0p167_0p167" 897 | ], 898 | "o": { 899 | "x": [ 900 | 0.167, 901 | 0.167, 902 | 0.167 903 | ], 904 | "y": [ 905 | 0.167, 906 | 0.167, 907 | 0.167 908 | ] 909 | }, 910 | "s": [ 911 | 43, 912 | 43, 913 | 100 914 | ], 915 | "t": 0 916 | }, 917 | { 918 | "e": [ 919 | 56.6, 920 | 27.5, 921 | 100 922 | ], 923 | "i": { 924 | "x": [ 925 | 0.833, 926 | 0.833, 927 | 0.833 928 | ], 929 | "y": [ 930 | 0.833, 931 | 0.833, 932 | 0.833 933 | ] 934 | }, 935 | "n": [ 936 | "0p833_0p833_0p167_0p167", 937 | "0p833_0p833_0p167_0p167", 938 | "0p833_0p833_0p167_0p167" 939 | ], 940 | "o": { 941 | "x": [ 942 | 0.167, 943 | 0.167, 944 | 0.167 945 | ], 946 | "y": [ 947 | 0.167, 948 | 0.167, 949 | 0.167 950 | ] 951 | }, 952 | "s": [ 953 | 36.8, 954 | 54.9, 955 | 100 956 | ], 957 | "t": 14 958 | }, 959 | { 960 | "e": [ 961 | 56.6, 962 | 27.5, 963 | 100 964 | ], 965 | "i": { 966 | "x": [ 967 | 0.833, 968 | 0.833, 969 | 0.833 970 | ], 971 | "y": [ 972 | 0.833, 973 | 0.833, 974 | 0.833 975 | ] 976 | }, 977 | "n": [ 978 | "0p833_0p833_0p167_0p167", 979 | "0p833_0p833_0p167_0p167", 980 | "0p833_0p833_0p167_0p167" 981 | ], 982 | "o": { 983 | "x": [ 984 | 0.167, 985 | 0.167, 986 | 0.167 987 | ], 988 | "y": [ 989 | 0.167, 990 | 0.167, 991 | 0.167 992 | ] 993 | }, 994 | "s": [ 995 | 56.6, 996 | 27.5, 997 | 100 998 | ], 999 | "t": 15 1000 | }, 1001 | { 1002 | "e": [ 1003 | 34.58, 1004 | 45.3, 1005 | 100 1006 | ], 1007 | "i": { 1008 | "x": [ 1009 | 0.833, 1010 | 0.833, 1011 | 0.833 1012 | ], 1013 | "y": [ 1014 | 0.833, 1015 | 0.833, 1016 | 0.833 1017 | ] 1018 | }, 1019 | "n": [ 1020 | "0p833_0p833_0p167_0p167", 1021 | "0p833_0p833_0p167_0p167", 1022 | "0p833_0p833_0p167_0p167" 1023 | ], 1024 | "o": { 1025 | "x": [ 1026 | 0.167, 1027 | 0.167, 1028 | 0.167 1029 | ], 1030 | "y": [ 1031 | 0.167, 1032 | 0.167, 1033 | 0.167 1034 | ] 1035 | }, 1036 | "s": [ 1037 | 56.6, 1038 | 27.5, 1039 | 100 1040 | ], 1041 | "t": 16 1042 | }, 1043 | { 1044 | "e": [ 1045 | 47.692, 1046 | 41.258, 1047 | 100 1048 | ], 1049 | "i": { 1050 | "x": [ 1051 | 0.833, 1052 | 0.833, 1053 | 0.833 1054 | ], 1055 | "y": [ 1056 | 0.833, 1057 | 0.833, 1058 | 0.833 1059 | ] 1060 | }, 1061 | "n": [ 1062 | "0p833_0p833_0p167_0p167", 1063 | "0p833_0p833_0p167_0p167", 1064 | "0p833_0p833_0p167_0p167" 1065 | ], 1066 | "o": { 1067 | "x": [ 1068 | 0.167, 1069 | 0.167, 1070 | 0.167 1071 | ], 1072 | "y": [ 1073 | 0.167, 1074 | 0.167, 1075 | 0.167 1076 | ] 1077 | }, 1078 | "s": [ 1079 | 34.58, 1080 | 45.3, 1081 | 100 1082 | ], 1083 | "t": 18 1084 | }, 1085 | { 1086 | "e": [ 1087 | 43, 1088 | 43, 1089 | 100 1090 | ], 1091 | "i": { 1092 | "x": [ 1093 | 0.833, 1094 | 0.833, 1095 | 0.833 1096 | ], 1097 | "y": [ 1098 | 0.833, 1099 | 0.833, 1100 | 0.833 1101 | ] 1102 | }, 1103 | "n": [ 1104 | "0p833_0p833_0p167_0p167", 1105 | "0p833_0p833_0p167_0p167", 1106 | "0p833_0p833_0p167_0p167" 1107 | ], 1108 | "o": { 1109 | "x": [ 1110 | 0.167, 1111 | 0.167, 1112 | 0.167 1113 | ], 1114 | "y": [ 1115 | 0.167, 1116 | 0.167, 1117 | 0.167 1118 | ] 1119 | }, 1120 | "s": [ 1121 | 47.692, 1122 | 41.258, 1123 | 100 1124 | ], 1125 | "t": 25 1126 | }, 1127 | { 1128 | "t": 30 1129 | } 1130 | ] 1131 | } 1132 | }, 1133 | "nm": "Shape Layer 1", 1134 | "op": 150, 1135 | "shapes": [ 1136 | { 1137 | "it": [ 1138 | { 1139 | "d": 1, 1140 | "mn": "ADBE Vector Shape - Ellipse", 1141 | "nm": "Ellipse Path 1", 1142 | "p": { 1143 | "a": 0, 1144 | "k": [ 1145 | 0, 1146 | 0 1147 | ] 1148 | }, 1149 | "s": { 1150 | "a": 0, 1151 | "k": [ 1152 | 460.156, 1153 | 460.156 1154 | ] 1155 | }, 1156 | "ty": "el" 1157 | }, 1158 | { 1159 | "c": { 1160 | "a": 0, 1161 | "k": [ 1162 | 0.2, 1163 | 0.77, 1164 | 0.61, 1165 | 1 1166 | ] 1167 | }, 1168 | "lc": 1, 1169 | "lj": 1, 1170 | "ml": 4, 1171 | "mn": "ADBE Vector Graphic - Stroke", 1172 | "nm": "Stroke 1", 1173 | "o": { 1174 | "a": 0, 1175 | "k": 100 1176 | }, 1177 | "ty": "st", 1178 | "w": { 1179 | "a": 0, 1180 | "k": 0 1181 | } 1182 | }, 1183 | { 1184 | "c": { 1185 | "a": 0, 1186 | "k": [ 1187 | 0.95, 1188 | 0.31, 1189 | 0.56, 1190 | 1 1191 | ] 1192 | }, 1193 | "mn": "ADBE Vector Graphic - Fill", 1194 | "nm": "Fill 1", 1195 | "o": { 1196 | "a": 0, 1197 | "k": 100 1198 | }, 1199 | "ty": "fl" 1200 | }, 1201 | { 1202 | "a": { 1203 | "a": 0, 1204 | "ix": 1, 1205 | "k": [ 1206 | 0, 1207 | 0 1208 | ] 1209 | }, 1210 | "nm": "Transform", 1211 | "o": { 1212 | "a": 0, 1213 | "ix": 7, 1214 | "k": 100 1215 | }, 1216 | "p": { 1217 | "a": 0, 1218 | "ix": 2, 1219 | "k": [ 1220 | -55.922, 1221 | -15.922 1222 | ] 1223 | }, 1224 | "r": { 1225 | "a": 0, 1226 | "ix": 6, 1227 | "k": 0 1228 | }, 1229 | "s": { 1230 | "a": 0, 1231 | "ix": 3, 1232 | "k": [ 1233 | 100, 1234 | 100 1235 | ] 1236 | }, 1237 | "sa": { 1238 | "a": 0, 1239 | "ix": 5, 1240 | "k": 0 1241 | }, 1242 | "sk": { 1243 | "a": 0, 1244 | "ix": 4, 1245 | "k": 0 1246 | }, 1247 | "ty": "tr" 1248 | } 1249 | ], 1250 | "mn": "ADBE Vector Group", 1251 | "nm": "Ellipse 1", 1252 | "np": 3, 1253 | "ty": "gr" 1254 | } 1255 | ], 1256 | "sr": 1, 1257 | "st": 0, 1258 | "ty": 4 1259 | }, 1260 | { 1261 | "ao": 0, 1262 | "bm": 0, 1263 | "ddd": 0, 1264 | "ind": 3, 1265 | "ip": 0, 1266 | "ks": { 1267 | "a": { 1268 | "a": 0, 1269 | "k": [ 1270 | -2, 1271 | 400, 1272 | 0 1273 | ] 1274 | }, 1275 | "o": { 1276 | "a": 0, 1277 | "k": 45 1278 | }, 1279 | "p": { 1280 | "a": 0, 1281 | "k": [ 1282 | 958, 1283 | 908, 1284 | 0 1285 | ] 1286 | }, 1287 | "r": { 1288 | "a": 0, 1289 | "k": 0 1290 | }, 1291 | "s": { 1292 | "a": 1, 1293 | "k": [ 1294 | { 1295 | "e": [ 1296 | 39.9, 1297 | 51.5, 1298 | 100 1299 | ], 1300 | "i": { 1301 | "x": [ 1302 | 0.893, 1303 | 0.893, 1304 | 1 1305 | ], 1306 | "y": [ 1307 | 0.5, 1308 | -0.195, 1309 | 1 1310 | ] 1311 | }, 1312 | "n": [ 1313 | "0p893_0p5_0p44_0", 1314 | "0p893_-0p195_0p44_0", 1315 | "1_1_0_0" 1316 | ], 1317 | "o": { 1318 | "x": [ 1319 | 0.44, 1320 | 0.44, 1321 | 0 1322 | ], 1323 | "y": [ 1324 | 0, 1325 | 0, 1326 | 0 1327 | ] 1328 | }, 1329 | "s": [ 1330 | 117.1, 1331 | 83.8, 1332 | 100 1333 | ], 1334 | "t": 0 1335 | }, 1336 | { 1337 | "e": [ 1338 | 117.1, 1339 | 83.8, 1340 | 100 1341 | ], 1342 | "i": { 1343 | "x": [ 1344 | 0.539, 1345 | 0.539, 1346 | 1 1347 | ], 1348 | "y": [ 1349 | 1, 1350 | 1, 1351 | 1 1352 | ] 1353 | }, 1354 | "n": [ 1355 | "0p539_1_0p175_0p542", 1356 | "0p539_1_0p175_1p294", 1357 | "1_1_0_0" 1358 | ], 1359 | "o": { 1360 | "x": [ 1361 | 0.175, 1362 | 0.175, 1363 | 0 1364 | ], 1365 | "y": [ 1366 | 0.542, 1367 | 1.294, 1368 | 0 1369 | ] 1370 | }, 1371 | "s": [ 1372 | 39.9, 1373 | 51.5, 1374 | 100 1375 | ], 1376 | "t": 16 1377 | }, 1378 | { 1379 | "t": 30 1380 | } 1381 | ] 1382 | } 1383 | }, 1384 | "nm": "Shape Layer 2", 1385 | "op": 150, 1386 | "shapes": [ 1387 | { 1388 | "it": [ 1389 | { 1390 | "d": 1, 1391 | "mn": "ADBE Vector Shape - Ellipse", 1392 | "nm": "Ellipse Path 1", 1393 | "p": { 1394 | "a": 0, 1395 | "k": [ 1396 | 0, 1397 | 0 1398 | ] 1399 | }, 1400 | "s": { 1401 | "a": 0, 1402 | "k": [ 1403 | 467.797, 1404 | 27.125 1405 | ] 1406 | }, 1407 | "ty": "el" 1408 | }, 1409 | { 1410 | "c": { 1411 | "a": 0, 1412 | "k": [ 1413 | 0.2, 1414 | 0.77, 1415 | 0.61, 1416 | 1 1417 | ] 1418 | }, 1419 | "lc": 1, 1420 | "lj": 1, 1421 | "ml": 4, 1422 | "mn": "ADBE Vector Graphic - Stroke", 1423 | "nm": "Stroke 1", 1424 | "o": { 1425 | "a": 0, 1426 | "k": 100 1427 | }, 1428 | "ty": "st", 1429 | "w": { 1430 | "a": 0, 1431 | "k": 0 1432 | } 1433 | }, 1434 | { 1435 | "c": { 1436 | "a": 0, 1437 | "k": [ 1438 | 0.18, 1439 | 0.62, 1440 | 0.5, 1441 | 1 1442 | ] 1443 | }, 1444 | "mn": "ADBE Vector Graphic - Fill", 1445 | "nm": "Fill 1", 1446 | "o": { 1447 | "a": 0, 1448 | "k": 100 1449 | }, 1450 | "ty": "fl" 1451 | }, 1452 | { 1453 | "a": { 1454 | "a": 0, 1455 | "ix": 1, 1456 | "k": [ 1457 | 0, 1458 | 0 1459 | ] 1460 | }, 1461 | "nm": "Transform", 1462 | "o": { 1463 | "a": 0, 1464 | "ix": 7, 1465 | "k": 100 1466 | }, 1467 | "p": { 1468 | "a": 0, 1469 | "ix": 2, 1470 | "k": [ 1471 | -2, 1472 | 400 1473 | ] 1474 | }, 1475 | "r": { 1476 | "a": 0, 1477 | "ix": 6, 1478 | "k": 0 1479 | }, 1480 | "s": { 1481 | "a": 0, 1482 | "ix": 3, 1483 | "k": [ 1484 | 69.545, 1485 | 100 1486 | ] 1487 | }, 1488 | "sa": { 1489 | "a": 0, 1490 | "ix": 5, 1491 | "k": 0 1492 | }, 1493 | "sk": { 1494 | "a": 0, 1495 | "ix": 4, 1496 | "k": 0 1497 | }, 1498 | "ty": "tr" 1499 | } 1500 | ], 1501 | "mn": "ADBE Vector Group", 1502 | "nm": "Ellipse 1", 1503 | "np": 3, 1504 | "ty": "gr" 1505 | } 1506 | ], 1507 | "sr": 1, 1508 | "st": 0, 1509 | "ty": 4 1510 | } 1511 | ] 1512 | } 1513 | ], 1514 | "ddd": 0, 1515 | "fr": 30, 1516 | "h": 600, 1517 | "ip": 0, 1518 | "layers": [ 1519 | { 1520 | "ao": 0, 1521 | "bm": 0, 1522 | "cl": "1920x1080", 1523 | "ddd": 0, 1524 | "h": 1080, 1525 | "ind": 0, 1526 | "ip": 0, 1527 | "ks": { 1528 | "a": { 1529 | "a": 0, 1530 | "k": [ 1531 | 960, 1532 | 540, 1533 | 0 1534 | ] 1535 | }, 1536 | "o": { 1537 | "a": 0, 1538 | "k": 100 1539 | }, 1540 | "p": { 1541 | "a": 0, 1542 | "k": [ 1543 | 400, 1544 | 300, 1545 | 0 1546 | ] 1547 | }, 1548 | "r": { 1549 | "a": 0, 1550 | "k": 0 1551 | }, 1552 | "s": { 1553 | "a": 0, 1554 | "k": [ 1555 | 55.556, 1556 | 55.556, 1557 | 100 1558 | ] 1559 | } 1560 | }, 1561 | "nm": "bouncing ball.1920x1080", 1562 | "op": 150, 1563 | "refId": "comp_1", 1564 | "sr": 1, 1565 | "st": 0, 1566 | "ty": 0, 1567 | "w": 1920 1568 | } 1569 | ], 1570 | "op": 30, 1571 | "v": "4.5.7", 1572 | "w": 800 1573 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/files/os_loop_p0_p0.json: -------------------------------------------------------------------------------- 1 | {"v":"4.12.0","fr":29.9700012207031,"ip":0,"op":204.00000830909,"w":800,"h":600,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[360,360],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":0,"k":99.7,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":2,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":40,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.973,0.408,0.022,0.491,0.811,0.534,0.34,1,0.649,0.659,0.658],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,20],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[180],"e":[898]},{"t":200.000008146167}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 3","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[360,360],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":0,"k":99.7,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":2,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":40,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.973,0.408,0.022,0.491,0.811,0.534,0.34,1,0.649,0.659,0.658],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,20],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[719]},{"t":200.000008146167}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[280,280],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.519,0.514,0.521,0.5,0.746,0.463,0.274,1,0.973,0.412,0.027],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[218.086,25.777],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1,19.555],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0}]} -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/basePreviewApp.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation 2 | 3 | import com.osg.openanimation.core.ui.BaseApp 4 | import org.koin.core.module.Module 5 | import org.koin.ksp.generated.defaultModule 6 | 7 | 8 | fun getBaseApp( 9 | platformModules : List = emptyList() 10 | ): BaseApp{ 11 | return BaseApp( 12 | baseUrl = "http://localhost:8080", 13 | platformModules = platformModules + defaultModule 14 | ) 15 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/AnimationDataCollection.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.data.animation.AnimationMetadata 4 | import openanimationapp.composeapp.generated.resources.Res 5 | 6 | 7 | enum class AnimationDataCollection( 8 | val metadata: AnimationMetadata 9 | ) { 10 | CHECKMARK( 11 | AnimationMetadata( 12 | name = "Checkmark", 13 | hash = "125804972", 14 | localFileName = "os_99592_checkmark_p0.json", 15 | tags = setOf( 16 | "checkmark", 17 | "confirmation", 18 | "success", 19 | "tick" 20 | ) 21 | ) 22 | ), 23 | AIRPLANE( 24 | AnimationMetadata( 25 | name = "Airplane Travel", 26 | hash = "220165352", 27 | localFileName = "os_airplane_p0.json", 28 | tags = setOf( 29 | "airplane", 30 | "flight", 31 | "globe", 32 | "travel", 33 | "loop", 34 | "minimal" 35 | ) 36 | ) 37 | ), 38 | SIMPLE_JUMP( 39 | AnimationMetadata( 40 | name = "Simple Jump", 41 | hash = "234928409", 42 | localFileName = "os_bouncing_p0.json", 43 | tags = setOf( 44 | "jump", 45 | "bounce", 46 | "character", 47 | "minimal", 48 | "motion" 49 | ) 50 | ) 51 | ), 52 | DAY_NIGHT_CYCLE( 53 | AnimationMetadata( 54 | name = "Day Night Cycle", 55 | hash = "741231865", 56 | localFileName = "os_darkmode_p0.json", 57 | tags = setOf( 58 | "day", 59 | "night", 60 | "sun", 61 | "moon", 62 | "clouds", 63 | "stars", 64 | "cycle" 65 | ) 66 | ) 67 | ), 68 | SURPRISED_FACE( 69 | AnimationMetadata( 70 | name = "Surprised Face", 71 | hash = "-1003861391", 72 | localFileName = "os_dead_p0.json", 73 | tags = setOf( 74 | "face", 75 | "surprised", 76 | "emotion", 77 | "expression" 78 | ) 79 | ) 80 | ), 81 | HAPPY_DOG( 82 | AnimationMetadata( 83 | name = "Happy Dog", 84 | hash = "1388726296", 85 | localFileName = "os_dog_p0.json", 86 | tags = setOf( 87 | "dog", 88 | "happy", 89 | "cute", 90 | "pet", 91 | "white", 92 | "tail" 93 | ) 94 | ) 95 | ), 96 | ORBITING_DOTS( 97 | AnimationMetadata( 98 | name = "Orbiting Dots", 99 | hash = "319645589", 100 | localFileName = "os_loop_p0_p0.json", 101 | tags = setOf( 102 | "loading", 103 | "orbit", 104 | "dots", 105 | "circles", 106 | "rotation", 107 | "spinner" 108 | ) 109 | ) 110 | ), 111 | WALKING_DOG( 112 | AnimationMetadata( 113 | name = "Walking Dog", 114 | hash = "-963052743", 115 | localFileName = "os_lottie_example_p0_p0.json", 116 | tags = setOf( 117 | "dog", 118 | "walking", 119 | "pet", 120 | "movement", 121 | ) 122 | ) 123 | ), 124 | PARTLY_CLOUDY_SUN( 125 | AnimationMetadata( 126 | name = "Partly Cloudy Sun", 127 | hash = "960577", 128 | localFileName = "os_my_anim_p0.json", 129 | tags = setOf( 130 | "sun", 131 | "cloud", 132 | "partly cloudy", 133 | "weather", 134 | "daytime" 135 | ) 136 | ) 137 | ), 138 | LOADING_EMOJI( 139 | AnimationMetadata( 140 | name = "Loading Emoji", 141 | hash = "-20657691543", 142 | localFileName = "loading_emo.json", 143 | tags = setOf( 144 | "loading", 145 | "emoji", 146 | "face", 147 | "expression", 148 | "waiting" 149 | ) 150 | ) 151 | ), 152 | SYNC_DOTS( 153 | AnimationMetadata( 154 | name = "Sync Dots", 155 | hash = "1140977817", 156 | localFileName = "os_pageLoad_p0.json", 157 | tags = setOf( 158 | "dots", 159 | "circle", 160 | "movement", 161 | "sync", 162 | "loading", 163 | "progress" 164 | ) 165 | ) 166 | ); 167 | 168 | companion object { 169 | fun findByHash(hash: String): AnimationDataCollection { 170 | return entries.first { it.metadata.hash == hash } 171 | } 172 | 173 | val metadataList: List 174 | get() = entries.map { it.metadata } 175 | } 176 | } 177 | 178 | 179 | suspend fun AnimationDataCollection.fromLocaleStorage(): String { 180 | return Res.readBytes("files/${metadata.localFileName}").decodeToString() 181 | } 182 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/AnimationMetadataRepositoryFake.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.data.animation.AnimationMetadata 4 | import com.osg.openanimation.core.data.stats.AnimationStats 5 | import com.osg.openanimation.core.ui.di.domain.AnimationMetadataRepository 6 | import com.osg.openanimation.core.ui.graph.FilterQueryType 7 | import com.osg.openanimation.core.ui.graph.GuestQueryType 8 | import com.osg.openanimation.core.ui.graph.SelectedQueryType 9 | import com.osg.openanimation.core.ui.home.model.filterSortByText 10 | import com.osg.openanimation.core.utils.extractSortedTags 11 | import kotlinx.coroutines.delay 12 | import kotlinx.coroutines.flow.Flow 13 | import kotlinx.coroutines.flow.map 14 | import org.koin.core.annotation.Factory 15 | import kotlin.time.Duration 16 | import kotlin.time.Duration.Companion.seconds 17 | 18 | @Factory 19 | class AnimationMetadataRepositoryFake() : AnimationMetadataRepository { 20 | 21 | private val networkSimulateDelay: Duration = 1.seconds 22 | private fun fetchTradingAnimationIds(): Set { 23 | val statsMap = FakeRepositoryState.statsState.value 24 | return statsMap.entries.sortedByDescending {it.value.likeCount + it.value.downloadCount } 25 | .map { it.key } 26 | .toSet() 27 | } 28 | 29 | override suspend fun fetchMetaByHash(hash: String): AnimationMetadata { 30 | return AnimationDataCollection.entries.first { 31 | it.metadata.hash == hash 32 | }.metadata 33 | } 34 | 35 | override suspend fun fetchRelatedAnimations( 36 | animationMetadata: AnimationMetadata, 37 | count: Int 38 | ): List { 39 | delay(networkSimulateDelay) 40 | return AnimationDataCollection.metadataList 41 | .sortedByDescending { 42 | if (it.hash == animationMetadata.hash) { 43 | 0 44 | } else { 45 | it.tags.intersect(animationMetadata.tags).size 46 | } 47 | }.take(count) 48 | } 49 | 50 | override fun animationStatsFlow(hash: String): Flow = FakeRepositoryState.statsState.map { 51 | it[hash] ?: AnimationStats() 52 | } 53 | 54 | override suspend fun fetchBy( 55 | queryType: GuestQueryType, 56 | limit: Int 57 | ): List { 58 | delay(networkSimulateDelay) 59 | return when(queryType){ 60 | is FilterQueryType -> { 61 | AnimationDataCollection.entries 62 | .map { it.metadata } 63 | .filterSortByText(queryType) 64 | } 65 | is SelectedQueryType.ExploreCategory.Explore ->{ 66 | AnimationDataCollection.metadataList 67 | } 68 | 69 | SelectedQueryType.ExploreCategory.Trending -> { 70 | val trendingIds = fetchTradingAnimationIds() 71 | return trendingIds.map { 72 | AnimationDataCollection.findByHash(it).metadata 73 | } 74 | } 75 | } 76 | 77 | } 78 | 79 | override suspend fun fetchTags(): List { 80 | return AnimationDataCollection.entries.map { it.metadata }.extractSortedTags() 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/FakeAnimationContentLoader.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.ui.di.domain.AnimationContentLoader 4 | import kotlinx.coroutines.delay 5 | import kotlinx.coroutines.flow.MutableStateFlow 6 | import openanimationapp.composeapp.generated.resources.Res 7 | import org.koin.core.annotation.Factory 8 | import kotlin.time.Duration 9 | import kotlin.time.Duration.Companion.milliseconds 10 | 11 | 12 | @Factory 13 | class FakeAnimationContentLoader() : AnimationContentLoader { 14 | private val networkSimulateDelay: Duration = 500.milliseconds 15 | override suspend fun fetchAnimationByPath(path: String): String { 16 | delay(networkSimulateDelay) 17 | 18 | return Res.readBytes("files/$path").decodeToString() 19 | } 20 | } 21 | 22 | object FakeAnimationStorage { 23 | private val storage = MutableStateFlow>(emptyMap()) 24 | fun storeAnimation(path: String, data: String) { 25 | storage.value = storage.value + (path to data) 26 | } 27 | 28 | fun deleteAnimation(path: String) { 29 | storage.value = storage.value - path 30 | } 31 | 32 | fun getAnimation(path: String): String? { 33 | return storage.value[path] 34 | } 35 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/FakeAnimationInitialUpload.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.data.upload.ModerationStatus 4 | import com.osg.openanimation.core.data.upload.UploadedAnimationMeta 5 | import com.osg.openanimation.core.ui.di.domain.AnimationUploader 6 | import kotlinx.coroutines.flow.Flow 7 | import kotlinx.coroutines.flow.map 8 | import kotlinx.coroutines.flow.mapNotNull 9 | import kotlinx.coroutines.flow.update 10 | import org.koin.core.annotation.Factory 11 | import kotlin.time.Clock 12 | 13 | @Factory 14 | class FakeAnimationInitialUpload: AnimationUploader { 15 | override suspend fun processUploadAnimation(animationContent: String): String { 16 | val timeStamp = Clock.System.now().toEpochMilliseconds() 17 | val animationId = "uid_$timeStamp" 18 | val derivedMetaData = UploadedAnimationMeta( 19 | hash = animationId, 20 | uploadTimestamp = timeStamp, 21 | name = "My Animation Name", 22 | description = "My Animation Description", 23 | path = "$animationId.json", 24 | tags = emptyList(), 25 | isSubmitted = false, 26 | ) 27 | uploadAnimation(derivedMetaData, animationContent) 28 | 29 | return animationId 30 | } 31 | 32 | override suspend fun uploadAnimation( 33 | uploadedAnimationMeta: UploadedAnimationMeta, 34 | animationContent: String? 35 | ) { 36 | if (animationContent != null) { 37 | FakeAnimationStorage.storeAnimation(uploadedAnimationMeta.path, animationContent) 38 | } 39 | FakeRepositoryState.uploadedAnimationsMeta.update { currentMap -> 40 | currentMap + (uploadedAnimationMeta.hash to uploadedAnimationMeta) 41 | } 42 | 43 | if (uploadedAnimationMeta.isSubmitted) { 44 | FakeRepositoryState.moderationStatusState.update { currentMap -> 45 | currentMap + (uploadedAnimationMeta.hash to ModerationStatus.PENDING) 46 | } 47 | } 48 | } 49 | 50 | override fun moderationStatusFlow(hash: String): Flow { 51 | return FakeRepositoryState.moderationStatusState.map { currentMap -> 52 | currentMap[hash] ?: ModerationStatus.DRAFT 53 | } 54 | } 55 | 56 | override fun uploadedMetaFlow(hash: String): Flow { 57 | return FakeRepositoryState.uploadedAnimationsMeta.mapNotNull { currentMap -> 58 | currentMap[hash] 59 | } 60 | } 61 | 62 | override suspend fun onRemoveAnimation(hash: String) { 63 | val meta = FakeRepositoryState.uploadedAnimationsMeta.value.getValue(hash) 64 | FakeAnimationStorage.deleteAnimation(meta.path) 65 | FakeRepositoryState.uploadedAnimationsMeta.update { currentMap -> 66 | currentMap - hash 67 | } 68 | } 69 | 70 | override suspend fun fetchUserAnimation(path: String): String { 71 | return FakeAnimationStorage.getAnimation(path) ?: error("Animation not found") 72 | } 73 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/FakeReportSubmissionService.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.data.report.ReportSubmission 4 | import com.osg.openanimation.core.ui.di.domain.ReportSubmissionService 5 | import kotlinx.coroutines.delay 6 | import org.koin.core.annotation.Factory 7 | import kotlin.time.Duration.Companion.milliseconds 8 | 9 | @Factory 10 | class FakeReportSubmissionService: ReportSubmissionService { 11 | override suspend fun submit(reportSubmission: ReportSubmission) { 12 | delay(200.milliseconds) 13 | } 14 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/FakeRepositoryState.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.data.stats.AnimationStats 4 | import com.osg.openanimation.core.data.upload.ModerationStatus 5 | import com.osg.openanimation.core.data.upload.UploadedAnimationMeta 6 | import com.osg.openanimation.core.data.user.UserProfile 7 | import com.osg.openanimation.repo.AnimationDataCollection.AIRPLANE 8 | import com.osg.openanimation.repo.AnimationDataCollection.CHECKMARK 9 | import com.osg.openanimation.repo.AnimationDataCollection.DAY_NIGHT_CYCLE 10 | import com.osg.openanimation.repo.AnimationDataCollection.HAPPY_DOG 11 | import com.osg.openanimation.repo.AnimationDataCollection.ORBITING_DOTS 12 | import com.osg.openanimation.repo.AnimationDataCollection.PARTLY_CLOUDY_SUN 13 | import com.osg.openanimation.repo.AnimationDataCollection.SIMPLE_JUMP 14 | import com.osg.openanimation.repo.AnimationDataCollection.SURPRISED_FACE 15 | import com.osg.openanimation.repo.AnimationDataCollection.SYNC_DOTS 16 | import com.osg.openanimation.repo.AnimationDataCollection.WALKING_DOG 17 | import com.osg.openanimation.repo.AnimationDataCollection.entries 18 | import kotlinx.coroutines.flow.MutableStateFlow 19 | 20 | 21 | object FakeRepositoryState{ 22 | 23 | val profileState = MutableStateFlow(null) 24 | val statsState: MutableStateFlow> = MutableStateFlow(entries.associate { 25 | it.metadata.hash to it.initialStats 26 | }) 27 | 28 | val uploadedAnimationsMeta = MutableStateFlow>(emptyMap()) 29 | 30 | val moderationStatusState: MutableStateFlow> = MutableStateFlow(emptyMap()) 31 | 32 | val userLikedAnimationsState: MutableStateFlow> = MutableStateFlow(emptySet()) 33 | } 34 | 35 | 36 | private val AnimationDataCollection.initialStats: AnimationStats 37 | get() = when (this) { 38 | CHECKMARK -> AnimationStats( 39 | downloadCount = 1000, 40 | likeCount = 500 41 | ) 42 | AIRPLANE -> AnimationStats( 43 | downloadCount = 2000, 44 | likeCount = 1500 45 | ) 46 | SIMPLE_JUMP -> AnimationStats( 47 | downloadCount = 750, 48 | likeCount = 320 49 | ) 50 | DAY_NIGHT_CYCLE -> AnimationStats( 51 | downloadCount = 1200, 52 | likeCount = 600 53 | ) 54 | SURPRISED_FACE -> AnimationStats( 55 | downloadCount = 400, 56 | likeCount = 180 57 | ) 58 | HAPPY_DOG -> AnimationStats( 59 | downloadCount = 2100, 60 | likeCount = 1700 61 | ) 62 | ORBITING_DOTS -> AnimationStats( 63 | downloadCount = 950, 64 | likeCount = 410 65 | ) 66 | WALKING_DOG -> AnimationStats( 67 | downloadCount = 1300, 68 | likeCount = 900 69 | ) 70 | PARTLY_CLOUDY_SUN -> AnimationStats( 71 | downloadCount = 500, 72 | likeCount = 250 73 | ) 74 | SYNC_DOTS -> AnimationStats( 75 | downloadCount = 1600, 76 | likeCount = 1200 77 | ) 78 | 79 | AnimationDataCollection.LOADING_EMOJI -> AnimationStats( 80 | downloadCount = 700, 81 | likeCount = 355 82 | ) 83 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/FakeSignInProviderFactory.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.LaunchedEffect 5 | import com.osg.openanimation.core.data.user.UserProfile 6 | import com.osg.openanimation.core.ui.components.signin.SignInIdentifier 7 | import com.osg.openanimation.core.ui.components.signin.SignInProvider 8 | import com.osg.openanimation.core.ui.components.signin.SignInResult 9 | import com.osg.openanimation.core.ui.di.domain.SignInProviderFactory 10 | import org.koin.core.annotation.Factory 11 | 12 | class GoogleSignInSim( 13 | private val result: Result 14 | ) : SignInProvider { 15 | override val identifier: SignInIdentifier = SignInIdentifier.Google 16 | 17 | @Composable 18 | override fun SignInDialog(onComplete: (Result) -> Unit) { 19 | LaunchedEffect(Unit) { 20 | val res = result.getOrThrow() 21 | FakeRepositoryState.profileState.value = UserProfile( 22 | uid = res.uid, 23 | email = "test@test.com", 24 | displayName = "John Snow", 25 | ) 26 | onComplete( 27 | result 28 | ) 29 | } 30 | } 31 | } 32 | 33 | @Factory 34 | class SignInProviderSim() : SignInProviderFactory { 35 | override fun buildSignInProviders(): List { 36 | val result: Result = Result.success(SignInResult(uid = "testUid")) 37 | return listOf( 38 | GoogleSignInSim(result) 39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/com/osg/openanimation/repo/FakeUserRepo.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation.repo 2 | 3 | import com.osg.openanimation.core.data.stats.AnimationStats 4 | import com.osg.openanimation.core.data.upload.UploadedAnimationMeta 5 | import com.osg.openanimation.core.data.user.UserProfile 6 | import com.osg.openanimation.core.ui.components.signin.SignInResult 7 | import com.osg.openanimation.core.ui.di.domain.UserRepository 8 | import com.osg.openanimation.core.ui.di.domain.UserSessionState 9 | import kotlinx.coroutines.ExperimentalCoroutinesApi 10 | import kotlinx.coroutines.delay 11 | import kotlinx.coroutines.flow.Flow 12 | import kotlinx.coroutines.flow.flatMapLatest 13 | import kotlinx.coroutines.flow.map 14 | import kotlinx.coroutines.flow.update 15 | import org.koin.core.annotation.Factory 16 | import kotlin.time.Duration 17 | import kotlin.time.Duration.Companion.milliseconds 18 | 19 | @Factory 20 | class FakeUserRepo(): UserRepository { 21 | private val networkSimulateDelay: Duration = 300.milliseconds 22 | 23 | 24 | @OptIn(ExperimentalCoroutinesApi::class) 25 | override val profileFlow: Flow = FakeRepositoryState.profileState.flatMapLatest { 26 | FakeRepositoryState.userLikedAnimationsState.map { likedSet -> 27 | if (it == null) { 28 | UserSessionState.SignedOut 29 | } else { 30 | UserSessionState.SignedIn( 31 | userProfile = it, 32 | favorites = likedSet 33 | ) 34 | } 35 | } 36 | } 37 | 38 | 39 | override suspend fun onUserDownload(hash: String) { 40 | delay(networkSimulateDelay) 41 | FakeRepositoryState.statsState.update { 42 | it.toMutableMap().apply { 43 | val currentStats = this[hash]?: AnimationStats() 44 | this[hash] = currentStats.copy( 45 | downloadCount = currentStats.downloadCount + 1 46 | ) 47 | } 48 | } 49 | } 50 | 51 | override suspend fun likeAnimation(hash: String) { 52 | delay(networkSimulateDelay) 53 | FakeRepositoryState.userLikedAnimationsState.update { likedSet -> 54 | likedSet + hash 55 | } 56 | 57 | FakeRepositoryState.statsState.update { 58 | it.toMutableMap().apply { 59 | val currentStats = this[hash]?: AnimationStats() 60 | this[hash] = currentStats.copy( 61 | likeCount = currentStats.likeCount + 1 62 | ) 63 | } 64 | } 65 | } 66 | 67 | override suspend fun dislikeAnimation(hash: String) { 68 | delay(networkSimulateDelay) 69 | FakeRepositoryState.userLikedAnimationsState.update { likedSet -> 70 | likedSet - hash 71 | } 72 | 73 | FakeRepositoryState.statsState.update { 74 | it.toMutableMap().apply { 75 | val currentStats = this[hash]?: AnimationStats() 76 | this[hash] = currentStats.copy( 77 | likeCount = currentStats.likeCount - 1 78 | ) 79 | } 80 | } 81 | } 82 | 83 | override fun userAnimationsFlow(uid: String): Flow> { 84 | return FakeRepositoryState.uploadedAnimationsMeta.map { it.values.toList() } 85 | } 86 | 87 | override fun onUserSignOut() { 88 | FakeRepositoryState.profileState.value = null 89 | } 90 | 91 | override fun onRegistered(signInResultState: Result) { 92 | 93 | } 94 | 95 | override suspend fun updateProfile(userProfile: UserProfile) { 96 | FakeRepositoryState.profileState.value = userProfile 97 | } 98 | } -------------------------------------------------------------------------------- /composeApp/src/iosMain/kotlin/com/osg/openanimation/MainViewController.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation 2 | 3 | import androidx.compose.ui.window.ComposeUIViewController 4 | 5 | val app = getBaseApp() 6 | 7 | @Suppress("unused", "FunctionName") 8 | fun MainViewController() = ComposeUIViewController { 9 | app.AppEntry() 10 | } -------------------------------------------------------------------------------- /composeApp/src/jsMain/kotlin/main.kt: -------------------------------------------------------------------------------- 1 | import androidx.compose.ui.ExperimentalComposeUiApi 2 | import androidx.navigation.ExperimentalBrowserHistoryApi 3 | import com.osg.openanimation.core.ui.webApp 4 | import com.osg.openanimation.getBaseApp 5 | 6 | @OptIn(ExperimentalComposeUiApi::class, ExperimentalBrowserHistoryApi::class) 7 | fun main() { 8 | webApp( 9 | baseApp = getBaseApp() 10 | ) 11 | } 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/jsMain/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OpenAnimation 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | OpenAnimation - Lottie animations powered by Kotlin Multiplatform 14 |
15 |
16 |
Loading
17 |
18 |
19 |
20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/jsMain/resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/composeApp/src/jsMain/resources/logo.png -------------------------------------------------------------------------------- /composeApp/src/jsMain/resources/privacy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Privacy Policy – openAnimation 7 | 23 | 24 | 25 |

Privacy Policy

26 | 27 |

Data Collection and Usage

28 |

29 | openAnimation collects and stores basic user information such as your name, email address, and authentication credentials when you sign up or sign in. 30 | We also record metadata related to your downloads, saved animations, and interactions with the platform to personalize your experience and improve the service. 31 |

32 | 33 |

Tracking Technologies

34 |

35 | We use cookies and similar technologies to: 36 |

37 |
    38 |
  • Keep you signed in across sessions
  • 39 |
  • Enhance site performance and usability
  • 40 |
  • Understand user behavior and preferences
  • 41 |
42 | 43 |

Third-Party Services

44 |

45 | We use third-party services such as Google Analytics and Google AdSense for: 46 |

47 |
    48 |
  • Traffic and usage analysis
  • 49 |
  • Personalized content and advertising
  • 50 |
  • General statistical insights
  • 51 |
52 |

53 | These services may collect anonymized usage data including your IP address, browser type, device information, and visited pages. 54 |

55 | 56 |

Cookie Consent

57 |

58 | By using openAnimation, you agree to our use of cookies and related technologies as described in this policy. You may control cookie preferences in your browser settings. 59 |

60 |

61 | You can also manage ad personalization via your Google account settings. 62 |

63 | 64 |

User Control and Transparency

65 |

66 | Users can view and update their account information at any time from their profile page. You may request deletion of your account or associated data by contacting us directly. 67 |

68 |

69 | For transparency, we provide a summary of the data collected and its usage. For more information, please refer to Google's Privacy & Terms. 70 |

71 | 72 |

Changes to This Policy

73 |

74 | We may update this Privacy Policy from time to time. Material changes will be communicated through the website. We encourage you to review this page regularly. 75 |

76 | 77 |

Last Updated: December 2024

78 | 79 | -------------------------------------------------------------------------------- /composeApp/src/jsMain/resources/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --color-bg-dark: #19120c; 3 | --color-bg-medium: #322720; 4 | --color-white: #fff; 5 | --color-white-70: rgba(255, 255, 255, 0.7); 6 | --color-white-40: rgba(255, 255, 255, 0.4); 7 | --color-white-20: rgba(255, 255, 255, 0.2); 8 | --color-white-18: rgba(255, 255, 255, 0.18); 9 | --color-black-20: rgba(0, 0, 0, 0.2); 10 | --color-black-30: rgba(0, 0, 0, 0.3); 11 | --color-black-50: rgba(0, 0, 0, 0.5); 12 | } 13 | 14 | html, body { 15 | height: 100%; 16 | margin: 0; 17 | padding: 0; 18 | } 19 | 20 | body { 21 | overflow: hidden; 22 | } 23 | 24 | header { 25 | position: absolute; 26 | z-index: -1; 27 | } 28 | 29 | main { 30 | height: 100vh; 31 | width: 100vw; 32 | position: relative; 33 | } 34 | 35 | #splash { 36 | width: 100vw; 37 | height: 100vh; 38 | background: linear-gradient(135deg, var(--color-bg-dark), var(--color-bg-medium)); 39 | display: flex; 40 | justify-content: center; 41 | align-items: center; 42 | position: fixed; 43 | top: 0; 44 | left: 0; 45 | z-index: 1; 46 | flex-direction: column; 47 | transition: opacity 0.25s ease-out; 48 | } 49 | 50 | #ComposeTarget { 51 | position: absolute; 52 | top: 0; 53 | left: 0; 54 | width: 100%; 55 | height: 100%; 56 | z-index: 0; 57 | } 58 | 59 | .gradient-background img { 60 | max-width: 90%; 61 | height: auto; 62 | margin-bottom: 40px; 63 | filter: drop-shadow(0 0 15px var(--color-white-40)); 64 | animation: float 3s ease-in-out infinite; 65 | } 66 | 67 | @keyframes float { 68 | 0% { transform: translateY(0px); } 69 | 50% { transform: translateY(-10px); } 70 | 100% { transform: translateY(0px); } 71 | } 72 | 73 | /* Loading indicator styles */ 74 | .loading-container { 75 | margin-top: 20px; 76 | text-align: center; 77 | display: flex; 78 | flex-direction: column; 79 | align-items: center; 80 | background: rgba(255, 255, 255, 0.1); 81 | padding: 25px; 82 | border-radius: 16px; 83 | backdrop-filter: blur(10px); 84 | -webkit-backdrop-filter: blur(10px); /* Safari support */ 85 | box-shadow: 0 8px 32px var(--color-black-20); 86 | width: 85%; 87 | max-width: 320px; 88 | border: 1px solid var(--color-white-18); 89 | } 90 | 91 | .loading-spinner { 92 | position: relative; 93 | width: 60px; 94 | height: 60px; 95 | } 96 | 97 | .loading-spinner::before, 98 | .loading-spinner::after { 99 | content: ''; 100 | position: absolute; 101 | border-radius: 50%; 102 | top: 0; 103 | left: 0; 104 | width: 100%; 105 | height: 100%; 106 | } 107 | 108 | .loading-spinner::before { 109 | border: 3px solid var(--color-white-20); 110 | } 111 | 112 | .loading-spinner::after { 113 | border: 3px solid transparent; 114 | border-top-color: var(--color-white); 115 | border-left-color: var(--color-white); 116 | animation: spin 1s linear infinite; 117 | box-shadow: 0 0 10px var(--color-white-40); 118 | } 119 | 120 | .loading-text { 121 | position: relative; 122 | color: var(--color-white); 123 | margin-top: 20px; 124 | font-family: 'Segoe UI', Arial, sans-serif; 125 | text-align: center; 126 | letter-spacing: 1.5px; 127 | font-size: 14px; 128 | font-weight: 500; 129 | text-transform: uppercase; 130 | text-shadow: 0 2px 5px var(--color-black-30); 131 | } 132 | 133 | .loading-text::after { 134 | content: ''; 135 | position: absolute; 136 | bottom: -8px; 137 | left: 50%; 138 | transform: translateX(-50%); 139 | width: 40px; 140 | height: 2px; 141 | background: var(--color-white); 142 | border-radius: 2px; 143 | } 144 | 145 | @keyframes spin { 146 | 0% { transform: rotate(0deg); } 147 | 100% { transform: rotate(360deg); } 148 | } 149 | 150 | @keyframes pulse { 151 | 0% { opacity: 0.7; } 152 | 50% { opacity: 1; } 153 | 100% { opacity: 0.7; } 154 | } 155 | 156 | @media (max-width: 480px) { 157 | .loading-container { 158 | padding: 20px; 159 | width: 90%; 160 | } 161 | 162 | .loading-spinner { 163 | width: 50px; 164 | height: 50px; 165 | } 166 | 167 | .gradient-background img { 168 | max-width: 85%; 169 | margin-bottom: 30px; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /composeApp/src/jsMain/resources/term/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Terms of Use – openAnimation 7 | 29 | 30 | 31 |

Terms of Use

32 |

Last updated: May 21, 2025

33 | 34 |

Welcome to openAnimation, a platform for discovering and sharing Lottie animations. By accessing or using this site, you agree to the following Terms of Use:

35 | 36 |

1. Use of Content

37 |

Animations on openAnimation are either:

38 |
    39 |
  • Collected from public sources under open or unknown licenses, or
  • 40 |
  • Uploaded by users who claim they have the rights to share them.
  • 41 |
42 |

Unless explicitly stated, openAnimation does not own or license the animations hosted here.

43 |

You are responsible for ensuring that any animation you use complies with its original license.

44 |

Do not use animations for commercial purposes unless they are clearly marked as verified for such use.

45 | 46 |

2. Uploading Content

47 |

By uploading animations or submitting content:

48 |
    49 |
  • You confirm that you own the rights or have permission to share the files.
  • 50 |
  • You grant openAnimation a non-exclusive, royalty-free license to display and distribute the content on the platform.
  • 51 |
  • You agree not to upload content that violates copyright, trademarks, or any applicable laws.
  • 52 |
53 | 54 |

3. Removal of Content

55 |

If you are a copyright holder and believe your work has been posted on openAnimation without authorization, please contact us at orispok@gmail.com with the following:

56 |
    57 |
  • The URL(s) of the content in question
  • 58 |
  • Proof of ownership
  • 59 |
  • A request to remove the content
  • 60 |
61 |

We will respond promptly and remove infringing content as required by law.

62 | 63 |

4. No Warranty

64 |

The platform and its content are provided "as is" without warranties of any kind. We do not guarantee:

65 |
    66 |
  • The accuracy, completeness, or legality of any animation
  • 67 |
  • That files are virus-free or safe for use
  • 68 |
69 |

Use this platform at your own risk.

70 | 71 |

5. Limitation of Liability

72 |

openAnimation will not be liable for any damages arising out of your use of the site, including but not limited to loss of data, business interruptions, or legal claims arising from content misuse.

73 | 74 |

6. Changes to Terms

75 |

These terms may be updated periodically. Continued use of the site constitutes acceptance of any revised terms.

76 | 77 |

7. Contact

78 |

For questions, copyright issues, or takedown requests, contact us at:
79 | 📧 orispok@gmail.com

80 | 81 | -------------------------------------------------------------------------------- /composeApp/src/jvmMain/kotlin/com/osg/openanimation/main.kt: -------------------------------------------------------------------------------- 1 | package com.osg.openanimation 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import androidx.compose.ui.graphics.toArgb 5 | import androidx.compose.ui.graphics.vector.rememberVectorPainter 6 | import androidx.compose.ui.window.Window 7 | import androidx.compose.ui.window.WindowPlacement 8 | import androidx.compose.ui.window.application 9 | import androidx.compose.ui.window.rememberWindowState 10 | import com.osg.openanimation.core.ui.util.icons.brandingpack.LogoVector 11 | 12 | 13 | fun main() = application { 14 | val basePreviewApp = getBaseApp() 15 | Window( 16 | icon = rememberVectorPainter(image = LogoVector), 17 | state = rememberWindowState( 18 | placement = WindowPlacement.Maximized 19 | ), 20 | onCloseRequest = ::exitApplication, 21 | title = "OpenAnimation", 22 | ) { 23 | 24 | window.background = java.awt.Color(Color.Green.toArgb()) 25 | 26 | basePreviewApp.AppEntry() 27 | } 28 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | 3 | #Gradle 4 | org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx4096m" 5 | 6 | #Android 7 | android.nonTransitiveRClass=true 8 | android.useAndroidX=true 9 | 10 | #MPP 11 | kotlin.mpp.androidSourceSetLayoutVersion=2 12 | kotlin.mpp.enableCInteropCommonization=true 13 | kotlin.js.yarn=false 14 | org.jetbrains.compose.experimental.macos.enabled=true 15 | 16 | # w: The following Kotlin/Native targets cannot be built on this machine and are disabled: iosArm64, iosSimulatorArm64, iosX64 17 | kotlin.native.ignoreDisabledTargets=true 18 | 19 | # WEB 20 | org.jetbrains.compose.experimental.jscanvas.enabled=true 21 | #Ktor 22 | io.ktor.development=true -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | agp = "8.11.1" 3 | kotlin = "2.2.21" 4 | android-minSdk = "34" 5 | android-targetSdk = "36" 6 | compose-multiplatform = "1.10.0-beta01" 7 | androidx-lifecycle = "2.10.0-alpha04" 8 | adaptive = "1.2.0" 9 | ksp = "2.3.0" 10 | 11 | 12 | kotlinxSerializationCore = "1.9.0" 13 | androidx-activityCompose = "1.11.0" 14 | androidx-navigation = "2.9.1" 15 | composeHotReload = "1.0.0-rc02" 16 | kotlinx-datetime = "0.7.1" 17 | coroutines = "1.10.2" 18 | koinBom = "4.1.1" 19 | materialIconsCore = "1.7.3" 20 | koinAnnotationsVersion = "2.3.0" 21 | material3 = "1.10.0-alpha03" 22 | okio = "3.16.2" 23 | atomicfu="0.29.0" 24 | keight = "0.0.04" 25 | collection="1.5.0" 26 | 27 | [libraries] 28 | material3-adaptive = { module = "org.jetbrains.compose.material3.adaptive:adaptive", version.ref = "adaptive" } 29 | material-icons-core = { module = "org.jetbrains.compose.material:material-icons-core", version.ref = "materialIconsCore" } 30 | material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "material3" } 31 | material3-navigation-suite = { module = "org.jetbrains.compose.material3:material3-adaptive-navigation-suite", version.ref = "material3" } 32 | 33 | 34 | 35 | androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } 36 | androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" } 37 | androidx-lifecycle-viewmodel-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } 38 | 39 | androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } 40 | androidx-navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "androidx-navigation" } 41 | kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationCore" } 42 | kotlinx-serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlinxSerializationCore" } 43 | kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" } 44 | 45 | kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } 46 | 47 | koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koinBom" } 48 | koin-core = { module = "io.insert-koin:koin-core" } 49 | koin-compose = { module = "io.insert-koin:koin-compose" } 50 | koin-compose-viewmodel = {group = "io.insert-koin", name = "koin-compose-viewmodel"} 51 | 52 | koin-annotations = { module = "io.insert-koin:koin-annotations", version.ref = "koinAnnotationsVersion" } 53 | koin-ksp-compiler = { module = "io.insert-koin:koin-ksp-compiler", version.ref = "koinAnnotationsVersion" } 54 | 55 | kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } 56 | kotlinx-coroutines-swing = {group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "coroutines" } 57 | 58 | okio = { module = "com.squareup.okio:okio", version.ref = "okio" } 59 | okio-fakefilesystem = { module = "com.squareup.okio:okio-fakefilesystem", version.ref = "okio" } 60 | atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicfu" } 61 | 62 | keight = { module = "io.github.alexzhirkevich:keight", version.ref = "keight" } 63 | keight-core = { module = "io.github.alexzhirkevich:keight-core", version.ref = "keight" } 64 | androidx-collection = { module = "androidx.collection:collection", version.ref = "collection" } 65 | 66 | components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "compose-multiplatform" } 67 | ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose-multiplatform" } 68 | runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-multiplatform" } 69 | foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose-multiplatform" } 70 | ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "compose-multiplatform" } 71 | ui-tooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "compose-multiplatform" } 72 | 73 | 74 | [plugins] 75 | androidApplication = { id = "com.android.application", version.ref = "agp" } 76 | androidLibrary = { id = "com.android.library", version.ref = "agp" } 77 | composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } 78 | composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } 79 | kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } 80 | kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } 81 | kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 82 | ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } 83 | composeHotReload = { id = "org.jetbrains.compose.hot-reload", version.ref = "composeHotReload"} -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Apr 21 21:01:12 IDT 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s 90 | ' "$PWD" ) || exit 91 | 92 | # Use the maximum available, or set MAX_FD != -1 to use that value. 93 | MAX_FD=maximum 94 | 95 | warn () { 96 | echo "$*" 97 | } >&2 98 | 99 | die () { 100 | echo 101 | echo "$*" 102 | echo 103 | exit 1 104 | } >&2 105 | 106 | # OS specific support (must be 'true' or 'false'). 107 | cygwin=false 108 | msys=false 109 | darwin=false 110 | nonstop=false 111 | case "$( uname )" in #( 112 | CYGWIN* ) cygwin=true ;; #( 113 | Darwin* ) darwin=true ;; #( 114 | MSYS* | MINGW* ) msys=true ;; #( 115 | NONSTOP* ) nonstop=true ;; 116 | esac 117 | 118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 119 | 120 | 121 | # Determine the Java command to use to start the JVM. 122 | if [ -n "$JAVA_HOME" ] ; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD=$JAVA_HOME/jre/sh/java 126 | else 127 | JAVACMD=$JAVA_HOME/bin/java 128 | fi 129 | if [ ! -x "$JAVACMD" ] ; then 130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 131 | 132 | Please set the JAVA_HOME variable in your environment to match the 133 | location of your Java installation." 134 | fi 135 | else 136 | JAVACMD=java 137 | if ! command -v java >/dev/null 2>&1 138 | then 139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 140 | 141 | Please set the JAVA_HOME variable in your environment to match the 142 | location of your Java installation." 143 | fi 144 | fi 145 | 146 | # Increase the maximum file descriptors if we can. 147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 148 | case $MAX_FD in #( 149 | max*) 150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 151 | # shellcheck disable=SC2039,SC3045 152 | MAX_FD=$( ulimit -H -n ) || 153 | warn "Could not query maximum file descriptor limit" 154 | esac 155 | case $MAX_FD in #( 156 | '' | soft) :;; #( 157 | *) 158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 159 | # shellcheck disable=SC2039,SC3045 160 | ulimit -n "$MAX_FD" || 161 | warn "Could not set maximum file descriptor limit to $MAX_FD" 162 | esac 163 | fi 164 | 165 | # Collect all arguments for the java command, stacking in reverse order: 166 | # * args from the command line 167 | # * the main class name 168 | # * -classpath 169 | # * -D...appname settings 170 | # * --module-path (only if needed) 171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 172 | 173 | # For Cygwin or MSYS, switch paths to Windows format before running java 174 | if "$cygwin" || "$msys" ; then 175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 177 | 178 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 179 | 180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 181 | for arg do 182 | if 183 | case $arg in #( 184 | -*) false ;; # don't mess with options #( 185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 186 | [ -e "$t" ] ;; #( 187 | *) false ;; 188 | esac 189 | then 190 | arg=$( cygpath --path --ignore --mixed "$arg" ) 191 | fi 192 | # Roll the args list around exactly as many times as the number of 193 | # args, so each arg winds up back in the position where it started, but 194 | # possibly modified. 195 | # 196 | # NB: a `for` loop captures its iteration list before it begins, so 197 | # changing the positional parameters here affects neither the number of 198 | # iterations, nor the values presented in `arg`. 199 | shift # remove old arg 200 | set -- "$@" "$arg" # push replacement arg 201 | done 202 | fi 203 | 204 | 205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 207 | 208 | # Collect all arguments for the java command: 209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 210 | # and any embedded shellness will be escaped. 211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 212 | # treated as '${Hostname}' itself on the command line. 213 | 214 | set -- \ 215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 216 | -classpath "$CLASSPATH" \ 217 | org.gradle.wrapper.GradleWrapperMain \ 218 | "$@" 219 | 220 | # Stop when "xargs" is not available. 221 | if ! command -v xargs >/dev/null 2>&1 222 | then 223 | die "xargs is not available" 224 | fi 225 | 226 | # Use "xargs" to parse quoted args. 227 | # 228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 229 | # 230 | # In Bash we could simply go: 231 | # 232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 233 | # set -- "${ARGS[@]}" "$@" 234 | # 235 | # but POSIX shell has neither arrays nor command substitution, so instead we 236 | # post-process each arg (as a line of input to sed) to backslash-escape any 237 | # character that might be a shell metacharacter, then use eval to reverse 238 | # that process (while maintaining the separation between arguments), and wrap 239 | # the whole thing up as a single "set" statement. 240 | # 241 | # This will of course break if any of these variables contains a newline or 242 | # an unmatched quote. 243 | # 244 | 245 | eval "set -- $( 246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 247 | xargs -n1 | 248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 249 | tr '\n' ' ' 250 | )" '"$@"' 251 | 252 | exec "$JAVACMD" "$@" 253 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /iosApp/Configuration/Config.xcconfig: -------------------------------------------------------------------------------- 1 | TEAM_ID= 2 | 3 | PRODUCT_NAME=openAnimation 4 | PRODUCT_BUNDLE_IDENTIFIER=com.osg.openanimation.openanimation$(TEAM_ID) 5 | 6 | CURRENT_PROJECT_VERSION=1 7 | MARKETING_VERSION=1.0 -------------------------------------------------------------------------------- /iosApp/StLaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-1024.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/background.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background.jpg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/background.imageset/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/iosApp/iosApp/Assets.xcassets/background.imageset/background.jpg -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/sit_new_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sit_full.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iosApp/iosApp/Assets.xcassets/sit_new_logo.imageset/sit_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/iosApp/iosApp/Assets.xcassets/sit_new_logo.imageset/sit_full.png -------------------------------------------------------------------------------- /iosApp/iosApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import SwiftUI 3 | import ComposeApp 4 | 5 | struct ComposeView: UIViewControllerRepresentable { 6 | func makeUIViewController(context: Context) -> UIViewController { 7 | MainViewControllerKt.MainViewController() 8 | } 9 | 10 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} 11 | } 12 | 13 | struct ContentView: View { 14 | var body: some View { 15 | ComposeView() 16 | .ignoresSafeArea(.keyboard) // Compose has own keyboard handler 17 | } 18 | } 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /iosApp/iosApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSApplicationCategoryType 24 | "public.app-category.social-networking" 25 | LSRequiresIPhoneOS 26 | 27 | UIApplicationSceneManifest 28 | 29 | UIApplicationSupportsMultipleScenes 30 | 31 | 32 | UILaunchScreen 33 | 34 | UILaunchStoryboardName 35 | StLaunchScreen.storyboard 36 | UIRequiredDeviceCapabilities 37 | 38 | armv7 39 | 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UISupportedInterfaceOrientations~ipad 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationPortraitUpsideDown 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct iOSApp: App { 5 | var body: some Scene { 6 | WindowGroup { 7 | ContentView() 8 | .ignoresSafeArea(edges: .all) 9 | .ignoresSafeArea(.keyboard) 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /iosApp/openAnimationApp.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 77; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6BD518882DEC5BFE005B3BFA /* StLaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6BD518872DEC5BFE005B3BFA /* StLaunchScreen.storyboard */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXFileReference section */ 14 | 6BD518872DEC5BFE005B3BFA /* StLaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = StLaunchScreen.storyboard; sourceTree = ""; }; 15 | B9DA97B12DC1472C00A4DA20 /* openAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = openAnimation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | /* End PBXFileReference section */ 17 | 18 | /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ 19 | B99700CA2DC9B8D800C7335B /* Exceptions for "iosApp" folder in "openAnimationApp" target */ = { 20 | isa = PBXFileSystemSynchronizedBuildFileExceptionSet; 21 | membershipExceptions = ( 22 | Info.plist, 23 | ); 24 | target = B9DA97B02DC1472C00A4DA20 /* openAnimationApp */; 25 | }; 26 | /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ 27 | 28 | /* Begin PBXFileSystemSynchronizedRootGroup section */ 29 | B9DA97B32DC1472C00A4DA20 /* iosApp */ = { 30 | isa = PBXFileSystemSynchronizedRootGroup; 31 | exceptions = ( 32 | B99700CA2DC9B8D800C7335B /* Exceptions for "iosApp" folder in "openAnimationApp" target */, 33 | ); 34 | path = iosApp; 35 | sourceTree = ""; 36 | }; 37 | B9DA98002DC14AA900A4DA20 /* Configuration */ = { 38 | isa = PBXFileSystemSynchronizedRootGroup; 39 | path = Configuration; 40 | sourceTree = ""; 41 | }; 42 | /* End PBXFileSystemSynchronizedRootGroup section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | B9DA97AE2DC1472C00A4DA20 /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | B9DA97A82DC1472C00A4DA20 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 6BD518872DEC5BFE005B3BFA /* StLaunchScreen.storyboard */, 59 | B9DA98002DC14AA900A4DA20 /* Configuration */, 60 | B9DA97B32DC1472C00A4DA20 /* iosApp */, 61 | B9DA97B22DC1472C00A4DA20 /* Products */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | B9DA97B22DC1472C00A4DA20 /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | B9DA97B12DC1472C00A4DA20 /* openAnimation.app */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | /* End PBXGroup section */ 74 | 75 | /* Begin PBXNativeTarget section */ 76 | B9DA97B02DC1472C00A4DA20 /* openAnimationApp */ = { 77 | isa = PBXNativeTarget; 78 | buildConfigurationList = B9DA97BF2DC1472D00A4DA20 /* Build configuration list for PBXNativeTarget "openAnimationApp" */; 79 | buildPhases = ( 80 | B9DA97F42DC1497100A4DA20 /* Compile Kotlin Framework */, 81 | B9DA97AD2DC1472C00A4DA20 /* Sources */, 82 | B9DA97AE2DC1472C00A4DA20 /* Frameworks */, 83 | B9DA97AF2DC1472C00A4DA20 /* Resources */, 84 | ); 85 | buildRules = ( 86 | ); 87 | dependencies = ( 88 | ); 89 | fileSystemSynchronizedGroups = ( 90 | B9DA97B32DC1472C00A4DA20 /* iosApp */, 91 | ); 92 | name = openAnimationApp; 93 | packageProductDependencies = ( 94 | ); 95 | productName = iosApp; 96 | productReference = B9DA97B12DC1472C00A4DA20 /* openAnimation.app */; 97 | productType = "com.apple.product-type.application"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | B9DA97A92DC1472C00A4DA20 /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | BuildIndependentTargetsInParallel = 1; 106 | LastSwiftUpdateCheck = 1620; 107 | LastUpgradeCheck = 1620; 108 | TargetAttributes = { 109 | B9DA97B02DC1472C00A4DA20 = { 110 | CreatedOnToolsVersion = 16.2; 111 | }; 112 | }; 113 | }; 114 | buildConfigurationList = B9DA97AC2DC1472C00A4DA20 /* Build configuration list for PBXProject "openAnimationApp" */; 115 | developmentRegion = en; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | Base, 120 | ); 121 | mainGroup = B9DA97A82DC1472C00A4DA20; 122 | minimizedProjectReferenceProxies = 1; 123 | preferredProjectObjectVersion = 77; 124 | productRefGroup = B9DA97B22DC1472C00A4DA20 /* Products */; 125 | projectDirPath = ""; 126 | projectRoot = ""; 127 | targets = ( 128 | B9DA97B02DC1472C00A4DA20 /* openAnimationApp */, 129 | ); 130 | }; 131 | /* End PBXProject section */ 132 | 133 | /* Begin PBXResourcesBuildPhase section */ 134 | B9DA97AF2DC1472C00A4DA20 /* Resources */ = { 135 | isa = PBXResourcesBuildPhase; 136 | buildActionMask = 2147483647; 137 | files = ( 138 | 6BD518882DEC5BFE005B3BFA /* StLaunchScreen.storyboard in Resources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXResourcesBuildPhase section */ 143 | 144 | /* Begin PBXShellScriptBuildPhase section */ 145 | B9DA97F42DC1497100A4DA20 /* Compile Kotlin Framework */ = { 146 | isa = PBXShellScriptBuildPhase; 147 | alwaysOutOfDate = 1; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | ); 151 | inputFileListPaths = ( 152 | ); 153 | inputPaths = ( 154 | ); 155 | name = "Compile Kotlin Framework"; 156 | outputFileListPaths = ( 157 | ); 158 | outputPaths = ( 159 | ); 160 | runOnlyForDeploymentPostprocessing = 0; 161 | shellPath = /bin/sh; 162 | shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n"; 163 | }; 164 | /* End PBXShellScriptBuildPhase section */ 165 | 166 | /* Begin PBXSourcesBuildPhase section */ 167 | B9DA97AD2DC1472C00A4DA20 /* Sources */ = { 168 | isa = PBXSourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | ); 172 | runOnlyForDeploymentPostprocessing = 0; 173 | }; 174 | /* End PBXSourcesBuildPhase section */ 175 | 176 | /* Begin XCBuildConfiguration section */ 177 | B9DA97BD2DC1472D00A4DA20 /* Debug */ = { 178 | isa = XCBuildConfiguration; 179 | buildSettings = { 180 | ALWAYS_SEARCH_USER_PATHS = NO; 181 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 182 | CLANG_ANALYZER_NONNULL = YES; 183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 185 | CLANG_ENABLE_MODULES = YES; 186 | CLANG_ENABLE_OBJC_ARC = YES; 187 | CLANG_ENABLE_OBJC_WEAK = YES; 188 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 189 | CLANG_WARN_BOOL_CONVERSION = YES; 190 | CLANG_WARN_COMMA = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 193 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 194 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 195 | CLANG_WARN_EMPTY_BODY = YES; 196 | CLANG_WARN_ENUM_CONVERSION = YES; 197 | CLANG_WARN_INFINITE_RECURSION = YES; 198 | CLANG_WARN_INT_CONVERSION = YES; 199 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 200 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 201 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 202 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 203 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 204 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 205 | CLANG_WARN_STRICT_PROTOTYPES = YES; 206 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 207 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 208 | CLANG_WARN_UNREACHABLE_CODE = YES; 209 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 210 | COPY_PHASE_STRIP = NO; 211 | DEBUG_INFORMATION_FORMAT = dwarf; 212 | ENABLE_STRICT_OBJC_MSGSEND = YES; 213 | ENABLE_TESTABILITY = YES; 214 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 215 | GCC_C_LANGUAGE_STANDARD = gnu17; 216 | GCC_DYNAMIC_NO_PIC = NO; 217 | GCC_NO_COMMON_BLOCKS = YES; 218 | GCC_OPTIMIZATION_LEVEL = 0; 219 | GCC_PREPROCESSOR_DEFINITIONS = ( 220 | "DEBUG=1", 221 | "$(inherited)", 222 | ); 223 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 224 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 225 | GCC_WARN_UNDECLARED_SELECTOR = YES; 226 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 227 | GCC_WARN_UNUSED_FUNCTION = YES; 228 | GCC_WARN_UNUSED_VARIABLE = YES; 229 | IPHONEOS_DEPLOYMENT_TARGET = 18.2; 230 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 231 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 232 | MTL_FAST_MATH = YES; 233 | ONLY_ACTIVE_ARCH = YES; 234 | SDKROOT = iphoneos; 235 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 236 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 237 | }; 238 | name = Debug; 239 | }; 240 | B9DA97BE2DC1472D00A4DA20 /* Release */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 245 | CLANG_ANALYZER_NONNULL = YES; 246 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 248 | CLANG_ENABLE_MODULES = YES; 249 | CLANG_ENABLE_OBJC_ARC = YES; 250 | CLANG_ENABLE_OBJC_WEAK = YES; 251 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 252 | CLANG_WARN_BOOL_CONVERSION = YES; 253 | CLANG_WARN_COMMA = YES; 254 | CLANG_WARN_CONSTANT_CONVERSION = YES; 255 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 256 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 257 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 258 | CLANG_WARN_EMPTY_BODY = YES; 259 | CLANG_WARN_ENUM_CONVERSION = YES; 260 | CLANG_WARN_INFINITE_RECURSION = YES; 261 | CLANG_WARN_INT_CONVERSION = YES; 262 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 263 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 264 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 265 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 266 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 267 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 268 | CLANG_WARN_STRICT_PROTOTYPES = YES; 269 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 270 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 271 | CLANG_WARN_UNREACHABLE_CODE = YES; 272 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 273 | COPY_PHASE_STRIP = NO; 274 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 275 | ENABLE_NS_ASSERTIONS = NO; 276 | ENABLE_STRICT_OBJC_MSGSEND = YES; 277 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 278 | GCC_C_LANGUAGE_STANDARD = gnu17; 279 | GCC_NO_COMMON_BLOCKS = YES; 280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 282 | GCC_WARN_UNDECLARED_SELECTOR = YES; 283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 284 | GCC_WARN_UNUSED_FUNCTION = YES; 285 | GCC_WARN_UNUSED_VARIABLE = YES; 286 | IPHONEOS_DEPLOYMENT_TARGET = 18.2; 287 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 288 | MTL_ENABLE_DEBUG_INFO = NO; 289 | MTL_FAST_MATH = YES; 290 | SDKROOT = iphoneos; 291 | SWIFT_COMPILATION_MODE = wholemodule; 292 | VALIDATE_PRODUCT = YES; 293 | }; 294 | name = Release; 295 | }; 296 | B9DA97C02DC1472D00A4DA20 /* Debug */ = { 297 | isa = XCBuildConfiguration; 298 | baseConfigurationReferenceAnchor = B9DA98002DC14AA900A4DA20 /* Configuration */; 299 | baseConfigurationReferenceRelativePath = Config.xcconfig; 300 | buildSettings = { 301 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 302 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 303 | CODE_SIGN_IDENTITY = "Apple Development"; 304 | CODE_SIGN_STYLE = Automatic; 305 | DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; 306 | DEVELOPMENT_TEAM = 2PVNM7P424; 307 | ENABLE_PREVIEWS = YES; 308 | FRAMEWORK_SEARCH_PATHS = ( 309 | "$(inherited)", 310 | "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", 311 | ); 312 | GENERATE_INFOPLIST_FILE = YES; 313 | INFOPLIST_FILE = iosApp/Info.plist; 314 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 315 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 316 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 317 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 318 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 319 | LD_RUNPATH_SEARCH_PATHS = ( 320 | "$(inherited)", 321 | "@executable_path/Frameworks", 322 | ); 323 | SWIFT_EMIT_LOC_STRINGS = YES; 324 | SWIFT_VERSION = 5.0; 325 | TARGETED_DEVICE_FAMILY = "1,2"; 326 | }; 327 | name = Debug; 328 | }; 329 | B9DA97C12DC1472D00A4DA20 /* Release */ = { 330 | isa = XCBuildConfiguration; 331 | baseConfigurationReferenceAnchor = B9DA98002DC14AA900A4DA20 /* Configuration */; 332 | baseConfigurationReferenceRelativePath = Config.xcconfig; 333 | buildSettings = { 334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 335 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 336 | CODE_SIGN_IDENTITY = "Apple Development"; 337 | CODE_SIGN_STYLE = Automatic; 338 | DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; 339 | DEVELOPMENT_TEAM = 2PVNM7P424; 340 | ENABLE_PREVIEWS = YES; 341 | FRAMEWORK_SEARCH_PATHS = ( 342 | "$(inherited)", 343 | "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", 344 | ); 345 | GENERATE_INFOPLIST_FILE = YES; 346 | INFOPLIST_FILE = iosApp/Info.plist; 347 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 348 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 349 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 350 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 351 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 352 | LD_RUNPATH_SEARCH_PATHS = ( 353 | "$(inherited)", 354 | "@executable_path/Frameworks", 355 | ); 356 | SWIFT_EMIT_LOC_STRINGS = YES; 357 | SWIFT_VERSION = 5.0; 358 | TARGETED_DEVICE_FAMILY = "1,2"; 359 | }; 360 | name = Release; 361 | }; 362 | /* End XCBuildConfiguration section */ 363 | 364 | /* Begin XCConfigurationList section */ 365 | B9DA97AC2DC1472C00A4DA20 /* Build configuration list for PBXProject "openAnimationApp" */ = { 366 | isa = XCConfigurationList; 367 | buildConfigurations = ( 368 | B9DA97BD2DC1472D00A4DA20 /* Debug */, 369 | B9DA97BE2DC1472D00A4DA20 /* Release */, 370 | ); 371 | defaultConfigurationIsVisible = 0; 372 | defaultConfigurationName = Release; 373 | }; 374 | B9DA97BF2DC1472D00A4DA20 /* Build configuration list for PBXNativeTarget "openAnimationApp" */ = { 375 | isa = XCConfigurationList; 376 | buildConfigurations = ( 377 | B9DA97C02DC1472D00A4DA20 /* Debug */, 378 | B9DA97C12DC1472D00A4DA20 /* Release */, 379 | ); 380 | defaultConfigurationIsVisible = 0; 381 | defaultConfigurationName = Release; 382 | }; 383 | /* End XCConfigurationList section */ 384 | }; 385 | rootObject = B9DA97A92DC1472C00A4DA20 /* Project object */; 386 | } 387 | -------------------------------------------------------------------------------- /iosApp/openAnimationApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /readme_images/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/readme_images/app-icon.png -------------------------------------------------------------------------------- /readme_images/drop_edit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/readme_images/drop_edit.gif -------------------------------------------------------------------------------- /readme_images/multiplatform_open-animation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/readme_images/multiplatform_open-animation.png -------------------------------------------------------------------------------- /readme_images/openanimation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orispok/OpenAnimationApp/HEAD/readme_images/openanimation.gif -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "OpenAnimationApp" 2 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 3 | 4 | pluginManagement { 5 | repositories { 6 | google { 7 | mavenContent { 8 | includeGroupAndSubgroups("androidx") 9 | includeGroupAndSubgroups("com.android") 10 | includeGroupAndSubgroups("com.google") 11 | } 12 | } 13 | mavenCentral() 14 | gradlePluginPortal() 15 | } 16 | } 17 | 18 | dependencyResolutionManagement { 19 | repositories { 20 | google { 21 | mavenContent { 22 | includeGroupAndSubgroups("androidx") 23 | includeGroupAndSubgroups("com.android") 24 | includeGroupAndSubgroups("com.google") 25 | } 26 | } 27 | mavenCentral() 28 | } 29 | } 30 | 31 | include("core:data") 32 | include("core:ui") 33 | include(":compottie:compottie") 34 | include(":compottie:compottie-core") 35 | include(":compottie:compottie-lite") 36 | include(":composeApp") --------------------------------------------------------------------------------