diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..7643783a
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..79ee123c
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/icon.png b/.idea/icon.png
new file mode 100644
index 00000000..08421fcc
Binary files /dev/null and b/.idea/icon.png differ
diff --git a/RULES.md b/RULES.md
index c3246728..58bf572b 100644
--- a/RULES.md
+++ b/RULES.md
@@ -2,8 +2,8 @@
1. Do not import-on-demand (star-import).
2. All composable functions should be restartable and skippable.
-3. Do not use List/Map/Set as parameters for composable functions. Instead, consider using lambdas
- like `() -> List/Map/Set` or immutable data structures.
+3. Do not use List/Map/Set as parameters for composable functions. Instead, consider using stable wrapper
+or immutable data structures.
4. If you want to change the visibility of the system bars, you can do so by calling
`Helper#statusBarsVisibility` or `Helper#navigationBarsVisibility`.
5. If you want to create a new string resource, you can do so by creating it in the i18n module and
diff --git a/arch.txt b/arch.txt
deleted file mode 100644
index fbcebf4c..00000000
--- a/arch.txt
+++ /dev/null
@@ -1,404 +0,0 @@
-.
-├── androidApp
-│ ├── build.gradle.kts
-│ ├── debug
-│ │ ├── androidApp-debug.apk
-│ │ └── output-metadata.json
-│ ├── proguard-rules.pro
-│ ├── release
-│ │ ├── androidApp-release.apk
-│ │ └── output-metadata.json
-│ └── src
-│ ├── main
-│ │ ├── AndroidManifest.xml
-│ └── java/com/m3u/androidApp
-│ ├── AppPublisher.kt
-│ ├── M3UApplication.kt
-│ ├── MainActivity.kt
-│ ├── components
-│ │ ├── AppBottomSheet.kt
-│ │ └── AppSnackHost.kt
-│ ├── di
-│ │ └── AppModule.kt
-│ ├── navigation
-│ │ ├── M3UNavHost.kt
-│ │ └── RootGraph.kt
-│ └── ui
-│ ├── App.kt
-│ ├── AppDefaults.kt
-│ ├── AppScaffold.kt
-│ ├── AppState.kt
-│ └── AppViewModel.kt
-├── benchmark
-│ ├── build.gradle.kts
-│ └── src/main/com/m3u/benchmark
-│ ├── ExampleStartupBenchmark.kt
-├── build.gradle.kts
-├── config
-│ └── detekt.yml
-├── core
-│ ├── README.md
-│ ├── build.gradle.kts
-│ ├── consumer-rules.pro
-│ ├── proguard-rules.pro
-│ └── src/main/com/m3u/core
-│ ├── annotation
-│ │ ├── ClipMode.kt
-│ │ ├── ConnectTimeout.kt
-│ │ └── FeedStrategy.kt
-│ ├── architecture
-│ │ ├── Logger.kt
-│ │ ├── Publisher.kt
-│ │ ├── Reader.kt
-│ │ ├── configuration
-│ │ │ ├── Configuration.kt
-│ │ │ ├── ExperimentalConfiguration.kt
-│ │ │ ├── SharedConfiguration.kt
-│ │ │ └── di
-│ │ │ └── ConfigurationModule.kt
-│ │ └── viewmodel
-│ │ └── BaseViewModel.kt
-│ ├── unspecified
-│ │ └── UBoolean.kt
-│ ├── util
-│ │ ├── Collections.kt
-│ │ ├── Files.kt
-│ │ ├── Likable.kt
-│ │ ├── Properties.kt
-│ │ ├── basic
-│ │ │ ├── Graphics.kt
-│ │ │ └── Strings.kt
-│ │ ├── collections
-│ │ │ ├── Contains.kt
-│ │ │ ├── ForEachNotNull.kt
-│ │ │ ├── IndexOf.kt
-│ │ │ ├── LoopIn.kt
-│ │ │ ├── Map.kt
-│ │ │ ├── ReplaceIf.kt
-│ │ │ ├── UnsuitableRangeForIterable.kt
-│ │ │ └── WithEach.kt
-│ │ ├── compose
-│ │ │ └── ObservableState.kt
-│ │ ├── context
-│ │ │ ├── Configuration.kt
-│ │ │ ├── ResourceDecoder.kt
-│ │ │ ├── SharedPreferences.kt
-│ │ │ └── Toasts.kt
-│ │ ├── coroutine
-│ │ │ └── Element.kt
-│ │ ├── serialization
-│ │ │ ├── DeserializationStrategyConverter.kt
-│ │ │ ├── Factory.kt
-│ │ │ ├── SerializationStrategyConverter.kt
-│ │ │ └── Serializer.kt
-│ │ └── transform
-│ │ ├── IntIterativeTransferable.kt
-│ │ ├── IterativeTransferable.kt
-│ │ └── Transferable.kt
-│ └── wrapper
-│ ├── Event.kt
-│ ├── Resource.kt
-│ └── Stored.kt
-├── data
-│ ├── build.gradle.kts
-│ ├── consumer-rules.pro
-│ ├── proguard-rules.pro
-│ └── src/main/com/m3u/data
-│ ├── api
-│ │ ├── DropboxApi.kt
-│ │ ├── GithubApi.kt
-│ │ └── dto
-│ │ └── github
-│ │ ├── Asset.kt
-│ │ ├── File.kt
-│ │ ├── Leaf.kt
-│ │ ├── Links.kt
-│ │ ├── Release.kt
-│ │ ├── Tree.kt
-│ │ └── User.kt
-│ ├── contract
-│ │ ├── Apis.kt
-│ │ ├── Certs.kt
-│ │ └── SSL.kt
-│ ├── database
-│ │ ├── M3UDatabase.kt
-│ │ ├── dao
-│ │ │ ├── FeedDao.kt
-│ │ │ └── LiveDao.kt
-│ │ └── entity
-│ │ ├── Feed.kt
-│ │ └── Live.kt
-│ ├── di
-│ │ ├── ApiModule.kt
-│ │ ├── BindServicesModule.kt
-│ │ ├── DatabaseModule.kt
-│ │ ├── LoggerModule.kt
-│ │ ├── ParserModule.kt
-│ │ ├── ReaderModule.kt
-│ │ └── RepositoryModule.kt
-│ ├── logger
-│ │ ├── CommonLogger.kt
-│ │ ├── FileLogger.kt
-│ │ └── UiLogger.kt
-│ ├── parser
-│ │ ├── Parser.kt
-│ │ ├── PlaylistParser.kt
-│ │ └── impl
-│ │ ├── DefaultPlaylistParser.kt
-│ │ ├── ExperimentalPlaylistParser.kt
-│ │ └── M3UData.kt
-│ ├── reader
-│ │ └── LogFileReader.kt
-│ ├── repository
-│ │ ├── CloudRepository.kt
-│ │ ├── FeedRepository.kt
-│ │ ├── LiveRepository.kt
-│ │ ├── MediaRepository.kt
-│ │ ├── ReadOnlyRepository.kt
-│ │ └── impl
-│ │ ├── DropboxCloudRepository.kt
-│ │ ├── FeedRepositoryImpl.kt
-│ │ ├── LiveRepositoryImpl.kt
-│ │ └── MediaRepositoryImpl.kt
-│ ├── service
-│ │ ├── PlayerManager.kt
-│ │ ├── UiService.kt
-│ │ └── impl
-│ │ ├── PlayerManagerImpl.kt
-│ │ └── UiServiceImpl.kt
-│ └── worker
-│ ├── SubscriptionInBackgroundWorker.kt
-├── detekt-twitter-compose-0.0.26-all.jar
-├── docs
-│ └── img
-│ ├── feat_live_1.png
-│ ├── feat_live_2.png
-│ └── feat_live_3.png
-├── features
-│ ├── about
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── libs
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/about
-│ │ ├── AboutScreen.kt
-│ │ ├── AboutViewModel.kt
-│ │ ├── components
-│ │ │ └── ContributorItem.kt
-│ │ ├── model
-│ │ │ └── Contributor.kt
-│ │ └── navigation
-│ │ └── AboutNavigation.kt
-│ ├── console
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/console
-│ │ ├── ConsoleEvent.kt
-│ │ ├── ConsoleScreen.kt
-│ │ ├── ConsoleState.kt
-│ │ ├── ConsoleViewModel.kt
-│ │ ├── MonoStyle.kt
-│ │ ├── command
-│ │ │ ├── CommandHandler.kt
-│ │ │ ├── CommandResource.kt
-│ │ │ ├── CommandScope.kt
-│ │ │ └── impl
-│ │ │ ├── EmptyCommandHandler.kt
-│ │ │ ├── LoggerCommandHandler.kt
-│ │ │ └── UpnpCommandHandler.kt
-│ │ └── navigation
-│ │ └── ConsoleNavigation.kt
-│ ├── crash
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/crash
-│ │ ├── CrashActivity.kt
-│ │ ├── CrashApp.kt
-│ │ ├── CrashHandler.kt
-│ │ ├── components
-│ │ │ └── FileItem.kt
-│ │ ├── navigation
-│ │ └── Destination.kt
-│ │ ├── screen
-│ │ ├── detail
-│ │ │ ├── DetailEvent.kt
-│ │ │ ├── DetailScreen.kt
-│ │ │ ├── DetailState.kt
-│ │ │ └── DetailViewModel.kt
-│ │ └── list
-│ │ ├── ListEvent.kt
-│ │ ├── ListScreen.kt
-│ │ ├── ListState.kt
-│ │ ├── ListViewModel.kt
-│ │ └── navigation
-│ │ └── ListNavigation.kt
-│ ├── favorite
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/favorite
-│ │ ├── FavoriteEvent.kt
-│ │ ├── FavoriteScreen.kt
-│ │ ├── FavoriteState.kt
-│ │ ├── FavouriteViewModel.kt
-│ │ ├── components
-│ │ │ └── FavoriteLiveItem.kt
-│ ├── feed
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/feed
-│ │ ├── FeedEvent.kt
-│ │ ├── FeedScreen.kt
-│ │ ├── FeedState.kt
-│ │ ├── FeedViewModel.kt
-│ │ ├── components
-│ │ │ ├── FeedDialog.kt
-│ │ │ └── LiveItem.kt
-│ │ └── navigation
-│ │ └── FeedNavigation.kt
-│ ├── live
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/live
-│ │ ├── LiveEvent.kt
-│ │ ├── LiveScreen.kt
-│ │ ├── LiveState.kt
-│ │ ├── LiveViewModel.kt
-│ │ ├── components
-│ │ │ ├── CoverPlaceholder.kt
-│ │ │ ├── DlnaDeviceItem.kt
-│ │ │ ├── DlnaDevicesBottomSheet.kt
-│ │ │ └── LiveMask.kt
-│ │ ├── fragments
-│ │ │ └── LiveFragment.kt
-│ │ └── navigation
-│ │ └── LiveNavigation.kt
-│ ├── main
-│ │ ├── build.gradle.kts
-│ │ ├── consumer-rules.pro
-│ │ ├── proguard-rules.pro
-│ │ └── src/main/com/m3u/features/main
-│ │ ├── MainEvent.kt
-│ │ ├── MainScreen.kt
-│ │ ├── MainState.kt
-│ │ ├── MainViewModel.kt
-│ │ ├── components
-│ │ │ ├── FeedItem.kt
-│ │ │ ├── Loading.kt
-│ │ │ └── MainDialog.kt
-│ │ └── model
-│ │ └── FeedDetail.kt
-│ └── setting
-│ ├── build.gradle.kts
-│ ├── consumer-rules.pro
-│ ├── proguard-rules.pro
-│ └── src/main/com/m3u/features/setting
-│ ├── SettingEvent.kt
-│ ├── SettingFragments.kt
-│ ├── SettingScreen.kt
-│ ├── SettingState.kt
-│ ├── SettingViewModel.kt
-│ ├── components
-│ │ └── MutedLiveItem.kt
-│ └── fragments
-│ ├── PreferencesFragment.kt
-│ ├── ScriptsFragment.kt
-│ └── SubscriptionsFragment.kt
-├── gradle
-│ ├── libs.versions.toml
-│ └── wrapper
-│ ├── gradle-wrapper.jar
-│ └── gradle-wrapper.properties
-├── gradle.properties
-├── gradlew
-├── gradlew.bat
-├── i18n
-│ ├── build.gradle.kts
-│ ├── consumer-rules.pro
-│ ├── proguard-rules.pro
-│ └── src/main
-│ └── AndroidManifest.xml
-├── lint
-│ ├── build.gradle.kts
-│ ├── consumer-rules.pro
-│ ├── libs
-│ ├── proguard-rules.pro
-│ └── src/main/java/com/m3u/lint
-│ ├── M3UIssueRegistry.kt
-│ ├── detectors
-│ │ ├── HelperDetector.kt
-│ │ └── StaredImportsDetector.kt
-│ └── resources
-│ └── META-INF
-│ └── services
-│ └── com.android.tools.lint.client.api.IssueRegistry
-├── lint.xml
-├── local.properties
-├── material
-│ ├── build.gradle.kts
-│ ├── consumer-rules.pro
-│ ├── proguard-rules.pro
-│ └── src
-│ └── main
-│ ├── AndroidManifest.xml
-│ └── java/com/m3u/material
-│ ├── components
-│ │ ├── AppBars.kt
-│ │ ├── Backgrounds.kt
-│ │ ├── Badges.kt
-│ │ ├── Brushes.kt
-│ │ ├── Buttons.kt
-│ │ ├── Dialogs.kt
-│ │ ├── Images.kt
-│ │ ├── Indicators.kt
-│ │ ├── Layouts.kt
-│ │ ├── Lotties.kt
-│ │ ├── Mask.kt
-│ │ ├── NavigationSheet.kt
-│ │ ├── Preferences.kt
-│ │ ├── Selection.kt
-│ │ ├── TextFields.kt
-│ │ └── ThemeSelection.kt
-│ ├── ktx
-│ │ ├── Animations.kt
-│ │ ├── Blurs.kt
-│ │ ├── Effects.kt
-│ │ ├── Interaction.kt
-│ │ ├── InterceptEvent.kt
-│ │ ├── LifecycleEffect.kt
-│ │ ├── ScrollableState.kt
-│ │ └── Specified.kt
-│ └── model
-│ ├── Duration.kt
-│ ├── GradientColors.kt
-│ ├── Scalable.kt
-│ ├── Spacing.kt
-│ ├── StepColor.kt
-│ ├── SugarColors.kt
-│ └── Theme.kt
-├── play_store_512.png
-├── release.jks
-├── settings.gradle.kts
-└── ui
- ├── build.gradle.kts
- ├── consumer-rules.pro
- ├── libs
- ├── proguard-rules.pro
- └── src
- ├── androidTest
- └── main
- ├── AndroidManifest.xml
- └── java/com/m3u/ui
- ├── AppFont.kt
- ├── Destination.kt
- ├── EventHandler.kt
- ├── M3ULocalProvider.kt
- ├── MonoText.kt
- ├── OnUserLeaveHint.kt
- ├── Player.kt
- ├── ResumeEvent.kt
- └── ScrollableState.kt