diff --git a/.gitignore b/.gitignore index 5788c62..c2ed1ac 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,15 @@ .idea .gradle/ app/build/ +.gradle +**/build/ # Local configuration file (sdk path, etc) local.properties # Log/OS Files *.log +.DS_Store # Android Studio generated files and folders captures/ @@ -33,14 +36,55 @@ google-services.json # Android Profiling *.hprof +# Diagram backups *.drawio.bkp -.DS_Store - -server/ -ktor-server/build/ +/docs/*.drawio.bkp +build/ -app/src/main/res/values/developer-config.xml +# Android +**/developer-config.xml +# Internal /TODO.md -/docs/.$design.drawio.bkp + + +# Xcode +## Obj-C/Swift specific +*.hmap +## App packaging +*.ipa +*.dSYM.zip +*.dSYM +# Swift Package Manager +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +Packages/ +Package.pins +Package.resolved + +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +.swiftpm +# CocoaPods - Only use to conserve bandwidth / Save time on Pushing +# - Also handy if you have a large number of dependant pods +# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE +Pods/ +.build/ +/compose-ios-app/Podfile.lock + +## Xcode 8 and earlier + +### Xcode Patch ### +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcodeproj/project.xcworkspace/ +!*.xcworkspace/contents.xcworkspacedata +/*.gcno +**/xcshareddata/WorkspaceSettings.xcsettings + +xcuserdata +!src/**/build/ +captures +.externalNativeBuild +.cxx diff --git a/.run/Desktop app.run.xml b/.run/Desktop app.run.xml new file mode 100644 index 0000000..2cbe819 --- /dev/null +++ b/.run/Desktop app.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/IOS app.run.xml b/.run/IOS app.run.xml new file mode 100644 index 0000000..cd363b1 --- /dev/null +++ b/.run/IOS app.run.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.nettyServer/Netty server.run.xml b/.run/Netty server.run.xml similarity index 100% rename from .nettyServer/Netty server.run.xml rename to .run/Netty server.run.xml diff --git a/.run/Web app (Wasm + JS).run.xml b/.run/Web app (Wasm + JS).run.xml new file mode 100644 index 0000000..5682a14 --- /dev/null +++ b/.run/Web app (Wasm + JS).run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/Web app (Wasm).run.xml b/.run/Web app (Wasm).run.xml new file mode 100644 index 0000000..dada8d3 --- /dev/null +++ b/.run/Web app (Wasm).run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/README.md b/README.md index be167b7..d005d5c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # PoC of design implementation for processing large GPS node trace data effectively +> [!WARNING] +> This branch in development. Project setup guide will be later. This has XCode projects, CocoaPods tool, different AndroidStudio plugins and run configuration that should be guided with instructions. + [![.github/workflows/main.yml](https://github.com/vitaliystoyanov/trace-node-tracking-playground/actions/workflows/main.yml/badge.svg?branch=gitworkflow)](https://github.com/vitaliystoyanov/trace-node-tracking-playground/actions/workflows/main.yml) ![API](https://img.shields.io/badge/API-23%2B-brightgreen.svg?style=flat) diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts new file mode 100644 index 0000000..4ec189e --- /dev/null +++ b/build-logic/convention/build.gradle.kts @@ -0,0 +1,47 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` +} + +group = "io.architecture.plugin.convention" + +// Configure the build-logic plugins to target JDK 17 +// This matches the JDK used to build the project, and is not related to what is running on device. +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } +} + +dependencies { + compileOnly(libs.android.gradlePlugin) + compileOnly(libs.android.tools.common) + compileOnly(libs.kotlin.gradlePlugin) +} + +tasks { + validatePlugins { + enableStricterValidation = true + failOnWarning = true + } +} + +gradlePlugin { + plugins { + register("androidLibrary") { + id = "io.architecture.android.library" + implementationClass = "AndroidLibraryConventionPlugin" + } + } + plugins { + register("multiplatformDefaultTargetPreset") { + id = "io.architecture.multiplatform.target.preset.default" + implementationClass = "MultiplatformTargetPresetConventionPlugin" + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt new file mode 100644 index 0000000..9f624e3 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -0,0 +1,26 @@ +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.android.build.gradle.LibraryExtension +import io.architecture.build.logic.configureKotlinAndroid +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.kotlin + +class AndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.library") + } + extensions.configure { + configureKotlinAndroid(this) + } + extensions.configure { + } + dependencies { + add("testImplementation", kotlin("test")) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/MultiplatformTargetPresetConventionPlugin.kt b/build-logic/convention/src/main/kotlin/MultiplatformTargetPresetConventionPlugin.kt new file mode 100644 index 0000000..7e9d314 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/MultiplatformTargetPresetConventionPlugin.kt @@ -0,0 +1,26 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl + +class MultiplatformTargetPresetConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.multiplatform") + } + extensions.configure { + applyDefaultHierarchyTemplate() + @OptIn(ExperimentalWasmDsl::class) + wasmJs { browser() } + js(IR) { browser() } + androidTarget() + iosX64() +// iosArm64() +// iosSimulatorArm64() + jvm() + } + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/io/architecture/build/logic/Android.kt b/build-logic/convention/src/main/kotlin/io/architecture/build/logic/Android.kt new file mode 100644 index 0000000..80fb5e7 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/io/architecture/build/logic/Android.kt @@ -0,0 +1,39 @@ +package io.architecture.build.logic + +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +internal fun Project.configureKotlinAndroid( + commonExtension: CommonExtension<*, *, *, *, *>, +) { + commonExtension.apply { + namespace = "io.architecture.playground" + path.replace(":", ".") + compileSdk = libs.findVersion("compileSdk").get().requiredVersion.toInt() + + defaultConfig { + minSdk = libs.findVersion("minSdk").get().requiredVersion.toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + } + + configureKotlin() + + dependencies { + } +} + +private fun Project.configureKotlin() { + tasks.withType().configureEach { + kotlinOptions { + jvmTarget = libs.findVersion("jvmTarget").get().requiredVersion + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/io/architecture/build/logic/ProjectExtensions.kt b/build-logic/convention/src/main/kotlin/io/architecture/build/logic/ProjectExtensions.kt new file mode 100644 index 0000000..e300635 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/io/architecture/build/logic/ProjectExtensions.kt @@ -0,0 +1,12 @@ +package io.architecture.build.logic + +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType + + +val Project.libs + get(): VersionCatalog = extensions + .getByType() + .named("libs") \ No newline at end of file diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 0000000..6225785 --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,14 @@ +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "build-logic" +include(":convention") \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 49bbfcb..a25b2a9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,10 +6,12 @@ import dev.iurysouza.modulegraph.Theme plugins { alias(libs.plugins.androidApplication) apply false alias(libs.plugins.androidLibrary) apply false + alias(libs.plugins.kotlinCocoapods) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.androidx.benchmark) apply false alias(libs.plugins.kotlinJvm) apply false alias(libs.plugins.kotlinMultiplatform) apply false + alias(libs.plugins.jetbrainsCompose) apply false alias(libs.plugins.modulegraph) alias(libs.plugins.ksp) } diff --git a/compose-android-app/build.gradle.kts b/compose-android-app/build.gradle.kts new file mode 100644 index 0000000..3c5ee36 --- /dev/null +++ b/compose-android-app/build.gradle.kts @@ -0,0 +1,111 @@ +import java.net.Inet4Address +import java.net.NetworkInterface + +plugins { + alias(libs.plugins.androidApplication) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.jetbrainsCompose) +} + +kotlin { + androidTarget() + sourceSets { + commonMain.dependencies { + + + + } + androidMain.dependencies { + implementation(libs.koin.core.coroutine) + implementation(projects.core.designsystem) + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) + implementation(compose.components.resources) + + implementation(projects.core.database.imp.room) + implementation(projects.core.di) + implementation(projects.core.domain) + implementation(projects.feature.map) + + implementation(libs.koin.android) + implementation(libs.koin.compose) + implementation(libs.kotlinx.coroutine.android) + + implementation(libs.scarlet.lifecycle.android) + implementation(libs.androidx.multidex) + implementation(libs.googleMaterialDesign) + + // Lifecycles + implementation(libs.androidx.lifecycle) + implementation(libs.androidx.lifecycleKtx) + implementation(libs.androidx.lifecycle.service) + implementation(libs.androidx.activityCompose) + implementation(libs.androidx.appCompat) + implementation(libs.androidx.coreKtx) + } + } +} + +android { + namespace = "io.architecture.playground" + compileSdk = libs.versions.compileSdk.get().toInt() + + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + sourceSets["main"].res.srcDirs("src/commonMain/resources", "src/androidMain/res") // TODO + sourceSets["main"].resources.srcDirs("src/commonMain/resources") + + buildFeatures { + compose = true + buildConfig = true + } + + defaultConfig { + applicationId = "io.architecture.playground" + minSdk = libs.versions.minSdk.get().toInt() + targetSdk = libs.versions.tragetSdk.get().toInt() + versionCode = 1 + versionName = "1.0" + multiDexEnabled = true + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + debug { + buildConfigField("String", "DEV_MACHINE_IP", "\"" + getLocalIPv4[0] + "\"") + } + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + packaging { + resources { + excludes.add("/META-INF/{AL2.0,LGPL2.1}") + } + } + composeOptions { + kotlinCompilerExtensionVersion = libs.versions.kotlinCompilerExtensionVersion.get() + } +} + +val getLocalIPv4: List + get() { + val ip4s = mutableListOf() + NetworkInterface.getNetworkInterfaces().toList() + .filter { it.isUp && !it.isLoopback && !it.isVirtual } + .forEach { networkInterface -> + networkInterface.inetAddresses.toList() + .filter { !it.isLoopbackAddress && it is Inet4Address } + .forEach { inetAddress -> ip4s.add(inetAddress.hostAddress) } + } + return ip4s + } diff --git a/compose-app/proguard-rules.pro b/compose-android-app/proguard-rules.pro similarity index 100% rename from compose-app/proguard-rules.pro rename to compose-android-app/proguard-rules.pro diff --git a/compose-app/src/main/AndroidManifest.xml b/compose-android-app/src/androidMain/AndroidManifest.xml similarity index 100% rename from compose-app/src/main/AndroidManifest.xml rename to compose-android-app/src/androidMain/AndroidManifest.xml diff --git a/compose-app/src/main/java/io/architecture/playground/EndlessForegroundService.kt b/compose-android-app/src/androidMain/kotlin/io/architecture/playground/EndlessForegroundService.kt similarity index 100% rename from compose-app/src/main/java/io/architecture/playground/EndlessForegroundService.kt rename to compose-android-app/src/androidMain/kotlin/io/architecture/playground/EndlessForegroundService.kt diff --git a/compose-app/src/main/java/io/architecture/playground/MapActivity.kt b/compose-android-app/src/androidMain/kotlin/io/architecture/playground/MapActivity.kt similarity index 85% rename from compose-app/src/main/java/io/architecture/playground/MapActivity.kt rename to compose-android-app/src/androidMain/kotlin/io/architecture/playground/MapActivity.kt index faf6c4e..cfdcb1b 100644 --- a/compose-app/src/main/java/io/architecture/playground/MapActivity.kt +++ b/compose-android-app/src/androidMain/kotlin/io/architecture/playground/MapActivity.kt @@ -5,8 +5,8 @@ import android.os.Build import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import io.architecture.map.MapScreen -import org.koin.compose.KoinContext +import io.architecture.core.design.system.theme.UAVTheme +import io.architecture.feature.common.map.MapScreen class MapActivity : ComponentActivity() { @@ -14,7 +14,7 @@ class MapActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { - KoinContext { + UAVTheme { MapScreen() } } diff --git a/compose-app/src/main/java/io/architecture/playground/PlaygroundApplication.kt b/compose-android-app/src/androidMain/kotlin/io/architecture/playground/PlaygroundApplication.kt similarity index 78% rename from compose-app/src/main/java/io/architecture/playground/PlaygroundApplication.kt rename to compose-android-app/src/androidMain/kotlin/io/architecture/playground/PlaygroundApplication.kt index 97ffc37..e781c30 100644 --- a/compose-app/src/main/java/io/architecture/playground/PlaygroundApplication.kt +++ b/compose-android-app/src/androidMain/kotlin/io/architecture/playground/PlaygroundApplication.kt @@ -1,13 +1,11 @@ package io.architecture.playground import android.app.Application -import android.util.Log +import androidx.multidex.BuildConfig import io.architecture.core.di.coreKoinModules -import io.architecture.core.runtime.configuration.WebsocketRuntimeConfiguration import io.architecture.database.imp.room.di.roomDaoModule import io.architecture.database.imp.room.di.roomDatabaseModule -import io.architecture.map.featureMapModule -import org.koin.android.ext.android.inject +import io.architecture.feature.common.map.di.mapFeatureModule import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger import org.koin.core.annotation.KoinExperimentalAPI @@ -28,7 +26,7 @@ class PlaygroundApplication : Application() { coreKoinModules, roomDaoModule, roomDatabaseModule, - featureMapModule + mapFeatureModule ) } @@ -41,8 +39,6 @@ class PlaygroundApplication : Application() { val koin = KoinPlatform.getKoin() koin.runOnKoinStarted { _ -> - val runtimeConfig: WebsocketRuntimeConfiguration by inject() - Log.d("RUNTIME_CONFIG", "Runtime configuration -> $runtimeConfig") super.onCreate() } } diff --git a/compose-app/src/main/res/drawable/ic_launcher_background.xml b/compose-android-app/src/androidMain/res/drawable/ic_launcher_background.xml similarity index 100% rename from compose-app/src/main/res/drawable/ic_launcher_background.xml rename to compose-android-app/src/androidMain/res/drawable/ic_launcher_background.xml diff --git a/compose-app/src/main/res/drawable/ic_launcher_foreground.xml b/compose-android-app/src/androidMain/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from compose-app/src/main/res/drawable/ic_launcher_foreground.xml rename to compose-android-app/src/androidMain/res/drawable/ic_launcher_foreground.xml diff --git a/compose-android-app/src/androidMain/res/font/uav_font_family.xml b/compose-android-app/src/androidMain/res/font/uav_font_family.xml new file mode 100644 index 0000000..f62e51e --- /dev/null +++ b/compose-android-app/src/androidMain/res/font/uav_font_family.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/compose-android-app/src/androidMain/res/font/uav_osd_mono.ttf b/compose-android-app/src/androidMain/res/font/uav_osd_mono.ttf new file mode 100644 index 0000000..eff34e3 Binary files /dev/null and b/compose-android-app/src/androidMain/res/font/uav_osd_mono.ttf differ diff --git a/compose-android-app/src/androidMain/res/font/uav_osd_sans_mono.ttf b/compose-android-app/src/androidMain/res/font/uav_osd_sans_mono.ttf new file mode 100644 index 0000000..61b7a16 Binary files /dev/null and b/compose-android-app/src/androidMain/res/font/uav_osd_sans_mono.ttf differ diff --git a/compose-android-app/src/androidMain/res/font/vcr_osd_mono.ttf b/compose-android-app/src/androidMain/res/font/vcr_osd_mono.ttf new file mode 100644 index 0000000..9322814 Binary files /dev/null and b/compose-android-app/src/androidMain/res/font/vcr_osd_mono.ttf differ diff --git a/compose-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/compose-android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from compose-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to compose-android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/compose-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/compose-android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from compose-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to compose-android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/compose-app/src/main/res/mipmap-hdpi/ic_launcher.webp b/compose-android-app/src/androidMain/res/mipmap-hdpi/ic_launcher.webp similarity index 100% rename from compose-app/src/main/res/mipmap-hdpi/ic_launcher.webp rename to compose-android-app/src/androidMain/res/mipmap-hdpi/ic_launcher.webp diff --git a/compose-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/compose-android-app/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp similarity index 100% rename from compose-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp rename to compose-android-app/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp diff --git a/compose-app/src/main/res/mipmap-mdpi/ic_launcher.webp b/compose-android-app/src/androidMain/res/mipmap-mdpi/ic_launcher.webp similarity index 100% rename from compose-app/src/main/res/mipmap-mdpi/ic_launcher.webp rename to compose-android-app/src/androidMain/res/mipmap-mdpi/ic_launcher.webp diff --git a/compose-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/compose-android-app/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp similarity index 100% rename from compose-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp rename to compose-android-app/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp diff --git a/compose-app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/compose-android-app/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp similarity index 100% rename from compose-app/src/main/res/mipmap-xhdpi/ic_launcher.webp rename to compose-android-app/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp diff --git a/compose-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/compose-android-app/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp similarity index 100% rename from compose-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp rename to compose-android-app/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp diff --git a/compose-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/compose-android-app/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp similarity index 100% rename from compose-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp rename to compose-android-app/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp diff --git a/compose-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/compose-android-app/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp similarity index 100% rename from compose-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp rename to compose-android-app/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp diff --git a/compose-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/compose-android-app/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp similarity index 100% rename from compose-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp rename to compose-android-app/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp diff --git a/compose-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/compose-android-app/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp similarity index 100% rename from compose-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp rename to compose-android-app/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/compose-app/src/main/res/values-night/themes.xml b/compose-android-app/src/androidMain/res/values-night/themes.xml similarity index 100% rename from compose-app/src/main/res/values-night/themes.xml rename to compose-android-app/src/androidMain/res/values-night/themes.xml diff --git a/compose-app/src/main/res/values/colors.xml b/compose-android-app/src/androidMain/res/values/colors.xml similarity index 100% rename from compose-app/src/main/res/values/colors.xml rename to compose-android-app/src/androidMain/res/values/colors.xml diff --git a/compose-app/src/main/res/values/developer-config.xml b/compose-android-app/src/androidMain/res/values/developer-config.xml similarity index 100% rename from compose-app/src/main/res/values/developer-config.xml rename to compose-android-app/src/androidMain/res/values/developer-config.xml diff --git a/compose-app/src/main/res/values/strings.xml b/compose-android-app/src/androidMain/res/values/strings.xml similarity index 100% rename from compose-app/src/main/res/values/strings.xml rename to compose-android-app/src/androidMain/res/values/strings.xml diff --git a/compose-app/src/main/res/values/themes.xml b/compose-android-app/src/androidMain/res/values/themes.xml similarity index 93% rename from compose-app/src/main/res/values/themes.xml rename to compose-android-app/src/androidMain/res/values/themes.xml index e7f88d8..44ca7e4 100644 --- a/compose-app/src/main/res/values/themes.xml +++ b/compose-android-app/src/androidMain/res/values/themes.xml @@ -13,6 +13,7 @@ @color/black + true \ No newline at end of file diff --git a/compose-app/src/main/res/xml/backup_rules.xml b/compose-android-app/src/androidMain/res/xml/backup_rules.xml similarity index 100% rename from compose-app/src/main/res/xml/backup_rules.xml rename to compose-android-app/src/androidMain/res/xml/backup_rules.xml diff --git a/compose-app/src/main/res/xml/data_extraction_rules.xml b/compose-android-app/src/androidMain/res/xml/data_extraction_rules.xml similarity index 100% rename from compose-app/src/main/res/xml/data_extraction_rules.xml rename to compose-android-app/src/androidMain/res/xml/data_extraction_rules.xml diff --git a/compose-app/src/main/res/xml/network_security.xml b/compose-android-app/src/androidMain/res/xml/network_security.xml similarity index 72% rename from compose-app/src/main/res/xml/network_security.xml rename to compose-android-app/src/androidMain/res/xml/network_security.xml index fbd4839..550782b 100644 --- a/compose-app/src/main/res/xml/network_security.xml +++ b/compose-android-app/src/androidMain/res/xml/network_security.xml @@ -1,6 +1,6 @@ - 192.168.1.*** + 192.168.1.197 \ No newline at end of file diff --git a/compose-app/build.gradle.kts b/compose-app/build.gradle.kts deleted file mode 100644 index 82320be..0000000 --- a/compose-app/build.gradle.kts +++ /dev/null @@ -1,108 +0,0 @@ -import java.net.Inet4Address -import java.net.NetworkInterface - -plugins { - alias(libs.plugins.androidApplication) - alias(libs.plugins.kotlin.android) - alias(libs.plugins.ksp) -} - -android { - namespace = "io.architecture.playground" - compileSdk = libs.versions.compileSdk.get().toInt() - - buildFeatures { - compose = true - buildConfig = true - } - - defaultConfig { - applicationId = "io.architecture.playground" - minSdk = libs.versions.minSdk.get().toInt() - targetSdk = libs.versions.tragetSdk.get().toInt() - versionCode = 1 - versionName = "1.0" - multiDexEnabled = true - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - - applicationVariants.all { - val variantName = name - sourceSets { - getByName("main") { - java.srcDir(File("build/generated/ksp/$variantName/kotlin")) - } - } - } - - buildTypes { - debug { - buildConfigField("String", "DEV_MACHINE_IP", "\"" + getLocalIPv4[0] + "\"") - } - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - packaging { - resources { - excludes.add("/META-INF/{AL2.0,LGPL2.1}") - } - } - kotlinOptions { - jvmTarget = libs.versions.jvmTarget.get() - } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.kotlinCompilerExtensionVersion.get() - } -} - -dependencies { - implementation(projects.core.di) - implementation(projects.core.domain) - implementation(projects.core.runtime.configuration) - implementation(projects.core.database.imp.room) - - implementation(projects.feature.map) - - implementation(libs.lifecycle.android) - implementation(libs.androidx.multidex) - implementation(libs.googleMaterialDesign) - - // Lifecycles - implementation(libs.androidx.lifecycle) - implementation(libs.androidx.lifecycleKtx) - implementation(libs.androidx.lifecycle.viewmodel.ktx) - implementation(libs.androidx.lifecycle.viewModelCompose) - implementation(libs.androidx.lifecycle.runtimeCompose) - implementation(libs.androidx.lifecycle.service) - implementation(libs.androidx.activityCompose) - implementation(libs.androidx.appCompat) - implementation(libs.androidx.coreKtx) - - // Koin - implementation(libs.koin.core.coroutine) - implementation(libs.koin.android) - implementation(libs.koin.compose) - ksp(libs.koin.ksp.compiler) -} - -val getLocalIPv4: List - get() { - val ip4s = mutableListOf() - NetworkInterface.getNetworkInterfaces().toList() - .filter { it.isUp && !it.isLoopback && !it.isVirtual } - .forEach { networkInterface -> - networkInterface.inetAddresses.toList() - .filter { !it.isLoopbackAddress && it is Inet4Address } - .forEach { inetAddress -> ip4s.add(inetAddress.hostAddress) } - } - return ip4s - } diff --git a/compose-desktop-app/build.gradle.kts b/compose-desktop-app/build.gradle.kts new file mode 100644 index 0000000..c0c42b2 --- /dev/null +++ b/compose-desktop-app/build.gradle.kts @@ -0,0 +1,44 @@ +import org.jetbrains.compose.desktop.application.dsl.TargetFormat + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.jetbrainsCompose) +} + +kotlin { + + jvm("desktop") + + sourceSets { + commonMain.dependencies { implementation(compose.desktop.common) } + + val desktopMain by getting { + dependencies { + implementation(projects.core.di) + implementation(projects.core.datasource.api) + implementation(projects.core.designsystem) + implementation(projects.feature.map) + // from Composite Gradle Build. See root setting.gradle.kts + //noinspection UseTomlInstead + implementation("ca.derekellis.mapbox:compose-mapbox-library") // TODO For testing + implementation(libs.koin.core) + implementation(libs.koin.mp.compose) + implementation(compose.desktop.currentOs) + + implementation("org.jetbrains.skiko:skiko-awt-runtime-macos-arm64:0.7.96") + } + } + } +} + +compose.desktop { + application { + mainClass = "MainKt" + + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageName = "io.architecture.playground" + packageVersion = "1.0.0" + } + } +} \ No newline at end of file diff --git a/compose-desktop-app/src/desktopMain/kotlin/main.kt b/compose-desktop-app/src/desktopMain/kotlin/main.kt new file mode 100644 index 0000000..9b5b572 --- /dev/null +++ b/compose-desktop-app/src/desktopMain/kotlin/main.kt @@ -0,0 +1,24 @@ +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import androidx.compose.ui.window.rememberWindowState +import io.architecture.core.design.system.theme.UAVTheme +import io.architecture.core.di.coreKoinModules +import io.architecture.datasource.api.di.inMemoryLocalDatasourceModule +import io.architecture.feature.common.map.MapScreen +import io.architecture.feature.common.map.di.mapFeatureModule +import org.koin.compose.KoinApplication + +fun main() = application { + val state = rememberWindowState(size = DpSize(1680.dp, 840.dp)) + Window(onCloseRequest = ::exitApplication, state, title = "Node trace tracking") { + KoinApplication(application = { + modules(coreKoinModules, mapFeatureModule, inMemoryLocalDatasourceModule) + }) { + UAVTheme { + MapScreen() + } + } + } +} \ No newline at end of file diff --git a/compose-ios-app/Podfile b/compose-ios-app/Podfile new file mode 100644 index 0000000..87ec6e7 --- /dev/null +++ b/compose-ios-app/Podfile @@ -0,0 +1,5 @@ +target 'compose-ios-app' do + use_frameworks! + platform :ios, '16.0' + pod 'shared', :path => 'shared' +end \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app.xcodeproj/project.pbxproj b/compose-ios-app/compose-ios-app.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5f25cf7 --- /dev/null +++ b/compose-ios-app/compose-ios-app.xcodeproj/project.pbxproj @@ -0,0 +1,406 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; + 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; + 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; + 6FCA0914780CD0B48097859F /* Pods_compose_ios_app.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1F1758DC454C58104421AEF /* Pods_compose_ios_app.framework */; }; + 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; + 7555FF7B242A565900829871 /* compose-ios-app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "compose-ios-app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C1F1758DC454C58104421AEF /* Pods_compose_ios_app.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_compose_ios_app.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EDF1612A3465E1C5CE8A0793 /* Pods-compose-ios-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-compose-ios-app.debug.xcconfig"; path = "Target Support Files/Pods-compose-ios-app/Pods-compose-ios-app.debug.xcconfig"; sourceTree = ""; }; + EEB086D4CD2A44CE72B722BF /* Pods-compose-ios-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-compose-ios-app.release.xcconfig"; path = "Target Support Files/Pods-compose-ios-app/Pods-compose-ios-app.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3D6DF6B4041B3D25A024A8F1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6FCA0914780CD0B48097859F /* Pods_compose_ios_app.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 058557D7273AAEEB004C7B11 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 4ED2C3F4C9096682DB1360A2 /* Pods */ = { + isa = PBXGroup; + children = ( + EDF1612A3465E1C5CE8A0793 /* Pods-compose-ios-app.debug.xcconfig */, + EEB086D4CD2A44CE72B722BF /* Pods-compose-ios-app.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 7555FF72242A565900829871 = { + isa = PBXGroup; + children = ( + 7555FF7D242A565900829871 /* compose-ios-app */, + 7555FF7C242A565900829871 /* Products */, + 4ED2C3F4C9096682DB1360A2 /* Pods */, + C6418FC90C34BCF33E861EEB /* Frameworks */, + ); + sourceTree = ""; + }; + 7555FF7C242A565900829871 /* Products */ = { + isa = PBXGroup; + children = ( + 7555FF7B242A565900829871 /* compose-ios-app.app */, + ); + name = Products; + sourceTree = ""; + }; + 7555FF7D242A565900829871 /* compose-ios-app */ = { + isa = PBXGroup; + children = ( + 058557BA273AAA24004C7B11 /* Assets.xcassets */, + 7555FF82242A565900829871 /* ContentView.swift */, + 7555FF8C242A565B00829871 /* Info.plist */, + 2152FB032600AC8F00CF470E /* iOSApp.swift */, + 058557D7273AAEEB004C7B11 /* Preview Content */, + ); + path = "compose-ios-app"; + sourceTree = ""; + }; + C6418FC90C34BCF33E861EEB /* Frameworks */ = { + isa = PBXGroup; + children = ( + C1F1758DC454C58104421AEF /* Pods_compose_ios_app.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7555FF7A242A565900829871 /* compose-ios-app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "compose-ios-app" */; + buildPhases = ( + E2040E433012C2128CCB577C /* [CP] Check Pods Manifest.lock */, + 7555FF77242A565900829871 /* Sources */, + 7555FF79242A565900829871 /* Resources */, + 3D6DF6B4041B3D25A024A8F1 /* Frameworks */, + AE792BCB12731B47A035F967 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "compose-ios-app"; + productName = "compose-ios-app"; + productReference = 7555FF7B242A565900829871 /* compose-ios-app.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7555FF73242A565900829871 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1130; + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = orgName; + TargetAttributes = { + 7555FF7A242A565900829871 = { + CreatedOnToolsVersion = 11.3.1; + }; + }; + }; + buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "compose-ios-app" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7555FF72242A565900829871; + productRefGroup = 7555FF7C242A565900829871 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7555FF7A242A565900829871 /* compose-ios-app */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7555FF79242A565900829871 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, + 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + AE792BCB12731B47A035F967 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-compose-ios-app/Pods-compose-ios-app-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-compose-ios-app/Pods-compose-ios-app-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-compose-ios-app/Pods-compose-ios-app-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + E2040E433012C2128CCB577C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-compose-ios-app-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7555FF77242A565900829871 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, + 7555FF83242A565900829871 /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7555FFA3242A565B00829871 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7555FFA4242A565B00829871 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7555FFA6242A565B00829871 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EDF1612A3465E1C5CE8A0793 /* Pods-compose-ios-app.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"compose-ios-app/Preview Content\""; + DEVELOPMENT_TEAM = F4479B46B2; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "compose-ios-app/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Nod; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.arhitecture.compose.ios.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7555FFA7242A565B00829871 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EEB086D4CD2A44CE72B722BF /* Pods-compose-ios-app.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"compose-ios-app/Preview Content\""; + DEVELOPMENT_TEAM = F4479B46B2; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "compose-ios-app/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Nod; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.arhitecture.compose.ios.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7555FF76242A565900829871 /* Build configuration list for PBXProject "compose-ios-app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7555FFA3242A565B00829871 /* Debug */, + 7555FFA4242A565B00829871 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "compose-ios-app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7555FFA6242A565B00829871 /* Debug */, + 7555FFA7242A565B00829871 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7555FF73242A565900829871 /* Project object */; +} diff --git a/compose-ios-app/compose-ios-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/compose-ios-app/compose-ios-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/compose-ios-app/compose-ios-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/compose-ios-app/compose-ios-app.xcworkspace/contents.xcworkspacedata b/compose-ios-app/compose-ios-app.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d9914ac --- /dev/null +++ b/compose-ios-app/compose-ios-app.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app/Assets.xcassets/AccentColor.colorset/Contents.json b/compose-ios-app/compose-ios-app/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..ee7e3ca --- /dev/null +++ b/compose-ios-app/compose-ios-app/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app/Assets.xcassets/AppIcon.appiconset/Contents.json b/compose-ios-app/compose-ios-app/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fb88a39 --- /dev/null +++ b/compose-ios-app/compose-ios-app/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app/Assets.xcassets/Contents.json b/compose-ios-app/compose-ios-app/Assets.xcassets/Contents.json new file mode 100644 index 0000000..4aa7c53 --- /dev/null +++ b/compose-ios-app/compose-ios-app/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app/ContentView.swift b/compose-ios-app/compose-ios-app/ContentView.swift new file mode 100644 index 0000000..a9d2673 --- /dev/null +++ b/compose-ios-app/compose-ios-app/ContentView.swift @@ -0,0 +1,17 @@ +import SwiftUI +import shared + +struct ComposeView: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> UIViewController { + return ComposeUIControllerKt.controller() + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} +} + +struct ContentView: View { + var body: some View { + ComposeView() + .ignoresSafeArea(.all, edges: .bottom) // Compose has own keyboard handler + } +} diff --git a/compose-ios-app/compose-ios-app/Info.plist b/compose-ios-app/compose-ios-app/Info.plist new file mode 100644 index 0000000..eaf75e1 --- /dev/null +++ b/compose-ios-app/compose-ios-app/Info.plist @@ -0,0 +1,48 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UILaunchScreen + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app/Preview Content/Preview Assets.xcassets/Contents.json b/compose-ios-app/compose-ios-app/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..4aa7c53 --- /dev/null +++ b/compose-ios-app/compose-ios-app/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/compose-ios-app/compose-ios-app/iOSApp.swift b/compose-ios-app/compose-ios-app/iOSApp.swift new file mode 100644 index 0000000..568d1e0 --- /dev/null +++ b/compose-ios-app/compose-ios-app/iOSApp.swift @@ -0,0 +1,14 @@ +import SwiftUI + +@main +struct iOSApp: App { + + var body: some Scene { + WindowGroup { + ZStack { + Color.white.ignoresSafeArea(.all) // status bar color + ContentView() + }.preferredColorScheme(.light) + } + } +} diff --git a/compose-ios-app/shared/build.gradle.kts b/compose-ios-app/shared/build.gradle.kts new file mode 100644 index 0000000..562818e --- /dev/null +++ b/compose-ios-app/shared/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.kotlinCocoapods) + alias(libs.plugins.jetbrainsCompose) +} + +kotlin { + iosX64() +// iosArm64() +// iosSimulatorArm64() + + cocoapods { + summary = "Some description for the Shared Module" + homepage = "Link to the Shared Module homepage" + version = "1.0" + ios.deploymentTarget = "16.0" + podfile = project.file("../Podfile") + framework { + baseName = "shared" + isStatic = true + } +// pod("MapboxMaps") { +// version = "11.1.0" +// packageName = "MapBox" +// // https://kotlinlang.org/docs/native-cocoapods-libraries.html#support-for-objective-c-headers-with-import-directives +// extraOpts += listOf("-compiler-option", "-fmodules") // TODO look up in docs what it's +// } + } + + sourceSets { + iosMain.dependencies { + implementation("ca.derekellis.mapbox:compose-mapbox-library") + implementation(projects.core.di) + implementation(projects.core.datasource.api) + implementation(projects.feature.map) + + implementation(libs.koin.core) + implementation(libs.koin.mp.compose) + } + } +} \ No newline at end of file diff --git a/compose-ios-app/shared/shared.podspec b/compose-ios-app/shared/shared.podspec new file mode 100644 index 0000000..0fa5b1d --- /dev/null +++ b/compose-ios-app/shared/shared.podspec @@ -0,0 +1,50 @@ +Pod::Spec.new do |spec| + spec.name = 'shared' + spec.version = '1.0' + spec.homepage = 'Link to the Shared Module homepage' + spec.source = { :http=> ''} + spec.authors = '' + spec.license = '' + spec.summary = 'Some description for the Shared Module' + spec.vendored_frameworks = 'build/cocoapods/framework/shared.framework' + spec.libraries = 'c++' + spec.ios.deployment_target = '16.0' + + + if !Dir.exist?('build/cocoapods/framework/shared.framework') || Dir.empty?('build/cocoapods/framework/shared.framework') + raise " + + Kotlin framework 'shared' doesn't exist yet, so a proper Xcode project can't be generated. + 'pod install' should be executed after running ':generateDummyFramework' Gradle task: + + ./gradlew :compose-ios-app:shared:generateDummyFramework + + Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)" + end + + spec.pod_target_xcconfig = { + 'KOTLIN_PROJECT_PATH' => ':compose-ios-app:shared', + 'PRODUCT_MODULE_NAME' => 'shared', + } + + spec.script_phases = [ + { + :name => 'Build shared', + :execution_position => :before_compile, + :shell_path => '/bin/sh', + :script => <<-SCRIPT + if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then + echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" + exit 0 + fi + set -ev + REPO_ROOT="$PODS_TARGET_SRCROOT" + "$REPO_ROOT/../../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ + -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ + -Pkotlin.native.cocoapods.archs="$ARCHS" \ + -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" + SCRIPT + } + ] + spec.resources = ['build/compose/ios/shared/compose-resources'] +end \ No newline at end of file diff --git a/compose-ios-app/shared/src/iosMain/composeResources/font/uav_osd_mono.ttf b/compose-ios-app/shared/src/iosMain/composeResources/font/uav_osd_mono.ttf new file mode 100644 index 0000000..eff34e3 Binary files /dev/null and b/compose-ios-app/shared/src/iosMain/composeResources/font/uav_osd_mono.ttf differ diff --git a/compose-ios-app/shared/src/iosMain/composeResources/font/uav_osd_sans_mono.ttf b/compose-ios-app/shared/src/iosMain/composeResources/font/uav_osd_sans_mono.ttf new file mode 100644 index 0000000..61b7a16 Binary files /dev/null and b/compose-ios-app/shared/src/iosMain/composeResources/font/uav_osd_sans_mono.ttf differ diff --git a/compose-ios-app/shared/src/iosMain/composeResources/font/vcr_osd_mono.ttf b/compose-ios-app/shared/src/iosMain/composeResources/font/vcr_osd_mono.ttf new file mode 100644 index 0000000..9322814 Binary files /dev/null and b/compose-ios-app/shared/src/iosMain/composeResources/font/vcr_osd_mono.ttf differ diff --git a/compose-ios-app/shared/src/iosMain/kotlin/io/architecture/shared/ComposeUIController.kt b/compose-ios-app/shared/src/iosMain/kotlin/io/architecture/shared/ComposeUIController.kt new file mode 100644 index 0000000..5911ca9 --- /dev/null +++ b/compose-ios-app/shared/src/iosMain/kotlin/io/architecture/shared/ComposeUIController.kt @@ -0,0 +1,20 @@ +package io.architecture.shared + +import androidx.compose.ui.window.ComposeUIViewController +import io.architecture.core.design.system.theme.UAVTheme +import io.architecture.core.di.coreKoinModules +import io.architecture.datasource.api.di.inMemoryLocalDatasourceModule +import io.architecture.feature.common.map.MapScreen +import io.architecture.feature.common.map.di.mapFeatureModule +import org.koin.compose.KoinApplication +import platform.UIKit.UIViewController + +fun controller(): UIViewController = ComposeUIViewController { + KoinApplication(application = { + modules(coreKoinModules, mapFeatureModule, inMemoryLocalDatasourceModule) + }) { + UAVTheme { + MapScreen() + } + } +} \ No newline at end of file diff --git a/compose-mapbox-library/LICENSE b/compose-mapbox-library/LICENSE new file mode 100644 index 0000000..0580d44 --- /dev/null +++ b/compose-mapbox-library/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Derek Ellis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/compose-mapbox-library/README.md b/compose-mapbox-library/README.md new file mode 100644 index 0000000..225a91c --- /dev/null +++ b/compose-mapbox-library/README.md @@ -0,0 +1,76 @@ +# compose-mapbox-library (based on https://github.com/dellisd/compose-web-mapbox) + +A Compose for Web wrapper of Mapbox. + +## Usage + +To create a map, call `rememberMapboxState()` to obtain a map state object that you can use to +programmatically interact with the map. Then call the `MapboxMap()` composable and pass it your +Mapbox access token and a map style URL at a minimum. + +```kotlin +val mapState = rememberMapboxState() + +MapboxMap( + accessToken = MAPBOX_ACCESS_TOKEN, + style = "mapbox://styles/mapbox/dark-v10", + state = mapState, +) { + // Place your sources and layers here +} +``` + +### Adding Sources + +Data sources are added using Composable methods in the `sources` block of the `MapboxMap` function. +Currently, only GeoJSON sources are implemented. + +```kotlin +import geojson.GeoJsonObject + +MapboxMap(/* ... */) { + GeoJsonSource(id = "test", data = data.unsafeCast()) { + // Layers for this data source go here + } +} +``` + +### Adding Layers + +Layers are added within the scope of a data source. The layer is automatically set up to pull data +from that source. +Paint and layout properties can be applied to the layer. + +```kotlin +MapboxMap(/* ... */) { + GeoJsonSource(/* ... */) { + CircleLayer(id = "circles") { + circleColor("#FF0000") + circleRadius(10) + } + } +} +``` + +All the source, layer, and paint/layout property functions are composable functions meaning that +their properties +can be updated like any other composable function. + +```kotlin +var size by remember { mutableStateOf(1) } + +MapboxMap(/* ... */) { + GeoJsonSource(/* ... */) { + CircleLayer(id = "circles") { + circleColor("#FF0000") + // The circle radius will automatically update on the map + circleRadius(size) + } + } +} +Button(attrs = { + onClick = { size++ } +}) { + Text("Increase Size") +} +``` \ No newline at end of file diff --git a/compose-mapbox-library/build.gradle.kts b/compose-mapbox-library/build.gradle.kts new file mode 100644 index 0000000..243fa83 --- /dev/null +++ b/compose-mapbox-library/build.gradle.kts @@ -0,0 +1,92 @@ +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl + +plugins { + alias(libs.plugins.androidLibrary) + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.kotlinCocoapods) + alias(libs.plugins.compose) +} + +group = "ca.derekellis.mapbox" +version = "11.1.0-SNAPSHOT" // corresponding to MapBox SDK version + +kotlin { + applyDefaultHierarchyTemplate() + @OptIn(ExperimentalWasmDsl::class) + wasmJs { browser() } + androidTarget() + iosX64() + iosArm64() + iosSimulatorArm64() + jvm() + js(IR) { + browser { + commonWebpackConfig { + cssSupport { + enabled.set(true) + } + } + } + } + + cocoapods { + summary = "Compose MapBox Library" + homepage = "TBR" + version = "11.1.0" + ios.deploymentTarget = "16.0" + pod("MapboxMaps") { + version = "11.1.0" + packageName = "MapBox" + // https://kotlinlang.org/docs/native-cocoapods-libraries.html#support-for-objective-c-headers-with-import-directives + extraOpts += listOf("-compiler-option", "-fmodules") // TODO look up in docs what it's + } + } + + sourceSets { + val commonMain by getting { + dependencies { + api(compose.runtime) + api(compose.foundation) + api(compose.material) + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + } + } + val jvmMain by getting { + dependencies { + implementation(compose.desktop.currentOs) + } + } + val jsMain by getting { + dependencies { + implementation(compose.html.core) + implementation(compose.runtime) + implementation(libs.kotlinx.coroutine.core) + implementation(npm("mapbox-gl", libs.versions.mapbox.get())) + } + } + val jsTest by getting + } +} + +android { + namespace = "io.architecture.mapbox.compose.library" + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} + +compose { + // https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html#use-a-developer-version-of-compose-multiplatform-compiler + kotlinCompilerPlugin.set("1.5.4") +} \ No newline at end of file diff --git a/compose-mapbox-library/compose_mapbox_library.podspec b/compose-mapbox-library/compose_mapbox_library.podspec new file mode 100644 index 0000000..13eb5d6 --- /dev/null +++ b/compose-mapbox-library/compose_mapbox_library.podspec @@ -0,0 +1,50 @@ +Pod::Spec.new do |spec| + spec.name = 'compose_mapbox_library' + spec.version = '11.1.0' + spec.homepage = 'TBR' + spec.source = { :http=> ''} + spec.authors = '' + spec.license = '' + spec.summary = 'Compose MapBox Library' + spec.vendored_frameworks = 'build/cocoapods/framework/compose_mapbox_library.framework' + spec.libraries = 'c++' + spec.ios.deployment_target = '16.0' + spec.dependency 'MapboxMaps', '11.1.0' + + if !Dir.exist?('build/cocoapods/framework/compose_mapbox_library.framework') || Dir.empty?('build/cocoapods/framework/compose_mapbox_library.framework') + raise " + + Kotlin framework 'compose_mapbox_library' doesn't exist yet, so a proper Xcode project can't be generated. + 'pod install' should be executed after running ':generateDummyFramework' Gradle task: + + ./gradlew :generateDummyFramework + + Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)" + end + + spec.pod_target_xcconfig = { + 'KOTLIN_PROJECT_PATH' => '', + 'PRODUCT_MODULE_NAME' => 'compose_mapbox_library', + } + + spec.script_phases = [ + { + :name => 'Build compose_mapbox_library', + :execution_position => :before_compile, + :shell_path => '/bin/sh', + :script => <<-SCRIPT + if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then + echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" + exit 0 + fi + set -ev + REPO_ROOT="$PODS_TARGET_SRCROOT" + "$REPO_ROOT/gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ + -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ + -Pkotlin.native.cocoapods.archs="$ARCHS" \ + -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" + SCRIPT + } + ] + spec.resources = ['build/compose/ios/compose_mapbox_library/compose-resources'] +end \ No newline at end of file diff --git a/compose-mapbox-library/gradle.properties b/compose-mapbox-library/gradle.properties new file mode 100644 index 0000000..ef19a36 --- /dev/null +++ b/compose-mapbox-library/gradle.properties @@ -0,0 +1,14 @@ +org.jetbrains.compose.experimental.jscanvas.enabled=true +org.jetbrains.compose.experimental.wasm.enabled=true + +android.useAndroidX=true + +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +org.gradle.parallel=true \ No newline at end of file diff --git a/compose-mapbox-library/gradle/libs.mapbox-library.versions.toml b/compose-mapbox-library/gradle/libs.mapbox-library.versions.toml new file mode 100644 index 0000000..bb2ecf4 --- /dev/null +++ b/compose-mapbox-library/gradle/libs.mapbox-library.versions.toml @@ -0,0 +1,23 @@ +[versions] +kotlin = "1.9.21" +mapbox = "2.15.0" +kotlinxCoroutineCore = "1.8.0" +# 1.5.X version throws kotlin.native.internal.IrLinkageError: +# "No function found for symbol..: using rememberCoroutineScope +compose = "1.6.0-beta02" +kotlinCompilerExtensionVersion = "1.5.4" +# Android +agp = "8.2.2" +minSdk = "23" +tragetSdk = "34" +compileSdk = "34" + +[libraries] +kotlinx-coroutine-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutineCore" } + +[plugins] +androidLibrary = { id = "com.android.library", version.ref = "agp" } +compose = { id = "org.jetbrains.compose", version.ref = "compose" } +kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +kotlinCocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" } + diff --git a/compose-mapbox-library/gradle/wrapper/gradle-wrapper.jar b/compose-mapbox-library/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/compose-mapbox-library/gradle/wrapper/gradle-wrapper.jar differ diff --git a/compose-mapbox-library/gradle/wrapper/gradle-wrapper.properties b/compose-mapbox-library/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..6cdac55 --- /dev/null +++ b/compose-mapbox-library/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Jan 29 17:45:57 EET 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/compose-mapbox-library/gradlew b/compose-mapbox-library/gradlew new file mode 100755 index 0000000..4f906e0 --- /dev/null +++ b/compose-mapbox-library/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/compose-mapbox-library/gradlew.bat b/compose-mapbox-library/gradlew.bat new file mode 100644 index 0000000..ac1b06f --- /dev/null +++ b/compose-mapbox-library/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/compose-mapbox-library/kotlin-js-store/yarn.lock b/compose-mapbox-library/kotlin-js-store/yarn.lock new file mode 100644 index 0000000..ca14aaa --- /dev/null +++ b/compose-mapbox-library/kotlin-js-store/yarn.lock @@ -0,0 +1,2236 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17": + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@mapbox/geojson-rewind@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz#591a5d71a9cd1da1a0bf3420b3bea31b0fc7946a" + integrity sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA== + dependencies: + get-stream "^6.0.1" + minimist "^1.2.6" + +"@mapbox/jsonlint-lines-primitives@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234" + integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ== + +"@mapbox/mapbox-gl-supported@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz#c15367178d8bfe4765e6b47b542fe821ce259c7b" + integrity sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ== + +"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" + integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ== + +"@mapbox/tiny-sdf@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz#9a1d33e5018093e88f6a4df2343e886056287282" + integrity sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA== + +"@mapbox/unitbezier@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz#d32deb66c7177e9e9dfc3bbd697083e2e657ff01" + integrity sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw== + +"@mapbox/vector-tile@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666" + integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw== + dependencies: + "@mapbox/point-geometry" "~0.1.0" + +"@mapbox/whoots-js@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" + integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== + +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.13" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" + integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" + integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + +"@types/json-schema@*", "@types/json-schema@^7.0.8": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/node@*", "@types/node@>=10.0.0": + version "18.11.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" + integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== + +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" + integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== + +"@webpack-cli/info@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" + integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== + +"@webpack-cli/serve@^2.0.3": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" + integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +accepts@~1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.7.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@^1.19.0: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + dependencies: + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001449: + version "1.0.30001449" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001449.tgz#a8d11f6a814c75c9ce9d851dc53eb1d1dfbcd657" + integrity sha512-CPB+UL9XMT/Av+pJxCKGhdx+yg1hzplvFJQlJ2n68PyQGMz9L/E2zCyLdOL8uasbouTUgnPl+y0tccI/se+BEw== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3, chokidar@^3.5.1: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.14: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.3.tgz#1e8799f3ccc5874fdd55461af51137fcc5befbcd" + integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.19" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +csscolorparser@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" + integrity sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + +date-format@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" + integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +earcut@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" + integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.284: + version "1.4.284" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +engine.io-parser@~5.0.3: + version "5.0.6" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.6.tgz#7811244af173e157295dec9b2718dfe42a64ef45" + integrity sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw== + +engine.io@~6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.1.tgz#e3f7826ebc4140db9bbaa9021ad6b1efb175878f" + integrity sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + +enhanced-resolve@^5.13.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +es-module-lexer@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" + integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +follow-redirects@^1.0.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +format-util@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +geojson-vt@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.2.1.tgz#f8adb614d2c1d3f6ee7c4265cad4bbf3ad60c8b7" + integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +gl-matrix@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" + integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +graceful-fs@^4.2.10: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +grid-index@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7" + integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.12: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz#eb9c95024f2d6dfbb3748d3415ac9b381906b9a9" + integrity sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q== + dependencies: + which "^1.2.1" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +karma-sourcemap-loader@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== + dependencies: + graceful-fs "^4.2.10" + +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.2.tgz#a983f874cee6f35990c4b2dcc3d274653714de8e" + integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kdbush@^4.0.1, kdbush@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39" + integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA== + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.4.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.7.1.tgz#06e12b1ac915dd1067146ffad8215f666f7d2c51" + integrity sha512-lzbd0Eq1HRdWM2abSD7mk6YIVY0AogGJzb/z+lqzRk+8+XJP+M6L1MS5FUSc3jjGru4dbKjEMJmqlsoYYpuivQ== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + flatted "^3.2.7" + rfdc "^1.3.0" + streamroller "^3.1.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +mapbox-gl@2.15.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-2.15.0.tgz#9439828d0bae1e7b464ae08b30cb2e65a7e2256d" + integrity sha512-fjv+aYrd5TIHiL7wRa+W7KjtUqKWziJMZUkK5hm8TvJ3OLeNPx4NmW/DgfYhd/jHej8wWL+QJBDbdMMAKvNC0A== + dependencies: + "@mapbox/geojson-rewind" "^0.5.2" + "@mapbox/jsonlint-lines-primitives" "^2.0.2" + "@mapbox/mapbox-gl-supported" "^2.0.1" + "@mapbox/point-geometry" "^0.1.0" + "@mapbox/tiny-sdf" "^2.0.6" + "@mapbox/unitbezier" "^0.0.1" + "@mapbox/vector-tile" "^1.3.1" + "@mapbox/whoots-js" "^3.1.0" + csscolorparser "~1.0.3" + earcut "^2.2.4" + geojson-vt "^3.2.1" + gl-matrix "^3.4.3" + grid-index "^1.1.0" + kdbush "^4.0.1" + murmurhash-js "^1.0.0" + pbf "^3.2.1" + potpack "^2.0.0" + quickselect "^2.0.0" + rw "^1.3.3" + supercluster "^8.0.0" + tinyqueue "^2.0.3" + vt-pbf "^3.1.3" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.3, minimist@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + +mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +murmurhash-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" + integrity sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-releases@^2.0.8: + version "2.0.9" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.9.tgz#fe66405285382b0c4ac6bcfbfbe7e8a510650b4d" + integrity sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +pbf@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.2.1.tgz#b4c1b9e72af966cd82c6531691115cc0409ffe2a" + integrity sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ== + dependencies: + ieee754 "^1.1.12" + resolve-protobuf-schema "^2.1.0" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.11" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" + integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.19: + version "8.4.29" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" + integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +potpack@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/potpack/-/potpack-2.0.0.tgz#61f4dd2dc4b3d5e996e3698c0ec9426d0e169104" + integrity sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw== + +protocol-buffers-schema@^3.3.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03" + integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +quickselect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-protobuf-schema@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758" + integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ== + dependencies: + protocol-buffers-schema "^3.3.1" + +resolve@^1.20.0: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rw@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +semver@^7.3.8: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +socket.io-adapter@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" + integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== + +socket.io-parser@~4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.2.tgz#1dd384019e25b7a3d374877f492ab34f2ad0d206" + integrity sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@^4.4.1: + version "4.5.4" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.4.tgz#a4513f06e87451c17013b8d13fdfaf8da5a86a90" + integrity sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.2.1" + socket.io-adapter "~2.4.0" + socket.io-parser "~4.2.1" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.1.tgz#72f00d05f5d1f90f80974eda781cbd7107c125f2" + integrity sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA== + dependencies: + abab "^2.0.6" + iconv-lite "^0.6.3" + source-map-js "^1.0.2" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +streamroller@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.4.tgz#844a18e795d39c1089a8216e66a1cf1151271df0" + integrity sha512-Ha1Ccw2/N5C/IF8Do6zgNe8F3jQo8MPBnMBGvX0QjNv/I97BcNRzK6/mzOpZHHK7DjMLTI3c7Xw7Y1KvdChkvw== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + fs-extra "^8.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.2.tgz#eaebca714d9e462c19aa1e3599057bc363924899" + integrity sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw== + +supercluster@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-8.0.1.tgz#9946ba123538e9e9ab15de472531f604e7372df5" + integrity sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ== + dependencies: + kdbush "^4.0.2" + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + +terser@^5.16.8: + version "5.19.4" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.4.tgz#941426fa482bf9b40a0308ab2b3cd0cf7c775ebd" + integrity sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +tinyqueue@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08" + integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA== + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + +ua-parser-js@^0.7.30: + version "0.7.33" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532" + integrity sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@^1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + +vt-pbf@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" + integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== + dependencies: + "@mapbox/point-geometry" "0.1.0" + "@mapbox/vector-tile" "^1.3.1" + pbf "^3.2.1" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webpack-cli@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.0.tgz#abc4b1f44b50250f2632d8b8b536cfe2f6257891" + integrity sha512-a7KRJnCxejFoDpYTOwzm5o21ZXMaNqtRlvS183XzGDUPRdVEzJNImcQokqYZ8BNTnk9DkKiuWxw75+DCCoZ26w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^2.1.0" + "@webpack-cli/info" "^2.0.1" + "@webpack-cli/serve" "^2.0.3" + colorette "^2.0.14" + commander "^10.0.1" + cross-spawn "^7.0.3" + envinfo "^7.7.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^3.1.1" + rechoir "^0.8.0" + webpack-merge "^5.7.3" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@5.82.0: + version "5.82.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.82.0.tgz#3c0d074dec79401db026b4ba0fb23d6333f88e7d" + integrity sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.13.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/compose-mapbox-library/settings.gradle.kts b/compose-mapbox-library/settings.gradle.kts new file mode 100644 index 0000000..0368577 --- /dev/null +++ b/compose-mapbox-library/settings.gradle.kts @@ -0,0 +1,23 @@ +rootProject.name = "compose-mapbox-library" + +pluginManagement { + repositories { + google() + gradlePluginPortal() + mavenCentral() + } +} + +dependencyResolutionManagement { + repositories { + mavenCentral() + google() + maven("https://androidx.dev/storage/compose-compiler/repository/") + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } + versionCatalogs { + create("libs") { + from(files("gradle/libs.mapbox-library.versions.toml")) + } + } +} diff --git a/compose-mapbox-library/src/androidMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.android.kt b/compose-mapbox-library/src/androidMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.android.kt new file mode 100644 index 0000000..8ffba04 --- /dev/null +++ b/compose-mapbox-library/src/androidMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.android.kt @@ -0,0 +1,15 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.architecture.mapbox.compose.library.state.MapboxState + +@Composable +actual fun MapBoxMap( + modifier: Modifier, + accessToken: String, + state: MapboxState, + style: String, + content: @MapboxMapComposableMarker @Composable (MapboxMapScope.() -> Unit)?, +) { +} \ No newline at end of file diff --git a/compose-mapbox-library/src/appleMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.apple.kt b/compose-mapbox-library/src/appleMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.apple.kt new file mode 100644 index 0000000..8ffba04 --- /dev/null +++ b/compose-mapbox-library/src/appleMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.apple.kt @@ -0,0 +1,15 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.architecture.mapbox.compose.library.state.MapboxState + +@Composable +actual fun MapBoxMap( + modifier: Modifier, + accessToken: String, + state: MapboxState, + style: String, + content: @MapboxMapComposableMarker @Composable (MapboxMapScope.() -> Unit)?, +) { +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/LngLat.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/LngLat.kt new file mode 100644 index 0000000..d625d63 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/LngLat.kt @@ -0,0 +1,8 @@ +package io.architecture.mapbox.compose.library + +class LngLat constructor(val array: Array) { + constructor(longitude: Double, latitude: Double) : this(arrayOf(longitude, latitude)) + + inline val longitude: Double get() = array[0] + inline val latitude: Double get() = array[1] +} diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/LngLatBounds.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/LngLatBounds.kt new file mode 100644 index 0000000..3414cf9 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/LngLatBounds.kt @@ -0,0 +1,19 @@ +package io.architecture.mapbox.compose.library + +class LngLatBounds private constructor(val array: Array) { + constructor(southwest: LngLat, northeast: LngLat) : this( + arrayOf( + southwest.longitude, + southwest.latitude, + northeast.longitude, + northeast.latitude, + ), + ) + + constructor(west: Double, south: Double, east: Double, north: Double) : this( + arrayOf(west, south, east, north), + ) + + inline val southwest: LngLat get() = LngLat(array[0], array[1]) + inline val northeast: LngLat get() = LngLat(array[2], array[3]) +} diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapBoxComposable.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapBoxComposable.kt new file mode 100644 index 0000000..0028057 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapBoxComposable.kt @@ -0,0 +1,14 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.ComposableTargetMarker + +@Retention(AnnotationRetention.BINARY) +@ComposableTargetMarker(description = "MapBox Composable") +@Target( + AnnotationTarget.FILE, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.TYPE, + AnnotationTarget.TYPE_PARAMETER, +) +public annotation class MapboxMapComposableMarker diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.kt new file mode 100644 index 0000000..e5416c1 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.kt @@ -0,0 +1,26 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import io.architecture.mapbox.compose.library.state.MapboxState + +@Composable +expect fun MapBoxMap( + modifier: Modifier = Modifier, + accessToken: String, + state: MapboxState, + style: String, +// onMapClickListener: OnMapClickListener, + content: (@Composable @MapboxMapComposableMarker MapboxMapScope.() -> Unit)? = null, +) + +@Composable +fun rememberMapboxState( + center: LngLat = LngLat(0.0, 0.0), + zoom: Double = 0.0, + bearing: Double = 0.0, + pitch: Double = 0.0, +): MapboxState { + return remember { MapboxState(center, zoom, bearing, pitch) } +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapScope.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapScope.kt new file mode 100644 index 0000000..890e2e5 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapScope.kt @@ -0,0 +1,19 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import kotlinx.coroutines.CoroutineScope + +open class MapScope() { + + @Composable + fun GeoJsonSource( + id: String, + geojson: String, + ) { + + } +} + +fun CoroutineScope.applySources(content: @Composable MapScope.() -> Unit) { + +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapboxMapScope.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapboxMapScope.kt new file mode 100644 index 0000000..e18ad19 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/MapboxMapScope.kt @@ -0,0 +1,8 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.foundation.layout.LayoutScopeMarker +import androidx.compose.runtime.Immutable + +@LayoutScopeMarker +@Immutable +object MapboxMapScope \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/MapboxState.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/MapboxState.kt new file mode 100644 index 0000000..1677bc1 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/MapboxState.kt @@ -0,0 +1,128 @@ +package io.architecture.mapbox.compose.library.state + +import io.architecture.mapbox.compose.library.LngLat +import io.architecture.mapbox.compose.library.LngLatBounds +import io.architecture.mapbox.compose.library.state.options.AnimationOptions +import io.architecture.mapbox.compose.library.state.options.CameraOptions +import io.architecture.mapbox.compose.library.state.options.FitBoundsOptions +import io.architecture.mapbox.compose.library.state.options.PaddingOptions +import kotlinx.coroutines.suspendCancellableCoroutine + +class MapboxState( + internal val initialCenter: LngLat = LngLat(0.0, 0.0), + internal val initialZoom: Double = 0.0, + internal val initialBearing: Double = 0.0, + internal val initialPitch: Double = 0.0, +) { + + var center: LngLat = LngLat(0.0, 0.0) + + var zoom: Double = 0.0 + + var bearing: Double = 0.0 + + var padding: PaddingOptions = object : PaddingOptions { + override var top: Number + get() = 0 + set(value) {} // tODO + override var bottom: Number + get() = 0 + set(value) {} + override var left: Number + get() = 0 + set(value) {} + override var right: Number + get() = 0 + set(value) {} + + } + + var pitch: Double = 0.0 + + suspend fun panBy(x: Double, y: Double, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + + } + + suspend fun panTo(location: LngLat, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + + } + + suspend fun zoomTo(zoom: Double, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + + } + + suspend fun zoomIn(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + + } + + suspend fun zoomOut(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + + } + + suspend fun rotateTo(bearing: Double, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + + } + + suspend fun resetNorth(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + + } + + suspend fun resetNorthPitch(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + + } + + suspend fun snapToNorth(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + + } + + fun cameraForBounds( + bounds: LngLatBounds, + options: (CameraOptions.() -> Unit)? = null, + ): CameraOptions? { + return null + } + + suspend fun fitBounds(bounds: LngLatBounds, options: (FitBoundsOptions.() -> Unit)? = null) = + doMoveAnimation { + + } + + suspend fun easeTo( + center: LngLat = this.center, + zoom: Double = this.zoom, + bearing: Double = this.bearing, + pitch: Double = this.pitch, + padding: PaddingOptions = this.padding, + options: (AnimationOptions.() -> Unit)? = null, + ) = doMoveAnimation { + + } + + suspend fun flyTo( + center: LngLat = this.center, + zoom: Double = this.zoom, + bearing: Double = this.bearing, + pitch: Double = this.pitch, + padding: PaddingOptions = this.padding, + options: (AnimationOptions.() -> Unit)? = null, + ) = doMoveAnimation { + + } + + /** + * Runs the given [block], assuming that the [block] triggers a move animation on the [map]. + * Suspends until the move animation has ended. + */ + private suspend fun doMoveAnimation(block: () -> Unit) { + var listener: (Any) -> Unit + var resumed = false + suspendCancellableCoroutine { continuation -> + block() + + } + } +} diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/AnimationOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/AnimationOptions.kt new file mode 100644 index 0000000..37d542f --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/AnimationOptions.kt @@ -0,0 +1,9 @@ +package io.architecture.mapbox.compose.library.state.options + +interface AnimationOptions { + var duration: Number? + var easing: ((time: Number) -> Number)? +// TODO var offset: dynamic /* Point? | JsTuple */ + var animate: Boolean? + var essential: Boolean? +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/CameraForBoundsOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/CameraForBoundsOptions.kt new file mode 100644 index 0000000..95bd96a --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/CameraForBoundsOptions.kt @@ -0,0 +1,6 @@ +package io.architecture.mapbox.compose.library.state.options + +interface CameraForBoundsOptions : CameraOptions { + // TODO var offset: Point /* Point? | JsTuple */ + var maxZoom: Number? +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/CameraOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/CameraOptions.kt new file mode 100644 index 0000000..e7fe028 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/CameraOptions.kt @@ -0,0 +1,12 @@ +package io.architecture.mapbox.compose.library.state.options + +import io.architecture.mapbox.compose.library.LngLat + +interface CameraOptions { + var center: LngLat? /* JsTuple | LngLat? | `T$1`? | `T$2`? */ + var zoom: Number? + var bearing: Number? + var pitch: Number? + var around: LngLat? /* JsTuple | LngLat? | `T$1`? | `T$2`? */ + var padding: PaddingOptions? /* Number? | PaddingOptions? */ +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/EaseToOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/EaseToOptions.kt new file mode 100644 index 0000000..66f5f6d --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/EaseToOptions.kt @@ -0,0 +1,5 @@ +package io.architecture.mapbox.compose.library.state.options + +interface EaseToOptions : AnimationOptions, CameraOptions { + var delayEndEvents: Number? +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/FitBoundsOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/FitBoundsOptions.kt new file mode 100644 index 0000000..1843f8f --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/FitBoundsOptions.kt @@ -0,0 +1,8 @@ +package io.architecture.mapbox.compose.library.state.options + +interface FitBoundsOptions : FlyToOptions { + var linear: Boolean? +// TODO override var offset: dynamic /* Point? | JsTuple */ + var maxZoom: Number? + override var maxDuration: Number? +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/FlyToOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/FlyToOptions.kt new file mode 100644 index 0000000..914e4a6 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/FlyToOptions.kt @@ -0,0 +1,9 @@ +package io.architecture.mapbox.compose.library.state.options + +interface FlyToOptions : AnimationOptions, CameraOptions { + var curve: Number? + var minZoom: Number? + var speed: Number? + var screenSpeed: Number? + var maxDuration: Number? +} \ No newline at end of file diff --git a/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/PaddingOptions.kt b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/PaddingOptions.kt new file mode 100644 index 0000000..f82f290 --- /dev/null +++ b/compose-mapbox-library/src/commonMain/kotlin/io/architecture/mapbox/compose/library/state/options/PaddingOptions.kt @@ -0,0 +1,8 @@ +package io.architecture.mapbox.compose.library.state.options + +interface PaddingOptions { + var top: Number + var bottom: Number + var left: Number + var right: Number +} \ No newline at end of file diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/EventsScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/EventsScope.kt new file mode 100644 index 0000000..8b77780 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/EventsScope.kt @@ -0,0 +1,80 @@ +package ca.derekellis.mapbox + +class EventsScope(private val mapRef: mapbox.Map) { + @Suppress("NOTHING_TO_INLINE") + private inline fun registerEvent( + event: String, + layers: List? = null, + noinline callback: (E) -> Unit, + ) { + if (layers == null) { + mapRef.on(event, callback.unsafeCast<(Any) -> Unit>()) + } else { + mapRef.on(event, layers.toTypedArray(), callback.unsafeCast<(Any) -> Unit>()) + } + } + + fun onMouseDown(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mousedown", layers, callback) + } + + fun onMouseUp(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mouseup", layers, callback) + } + + fun onMouseOver(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mouseover", layers, callback) + } + + fun onMouseMove(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mousemove", layers, callback) + } + + fun onPreClick(callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("preclick", null, callback) + } + + fun onClick(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("click", layers, callback) + } + + fun onDblClick(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("dblclick", layers, callback) + } + + fun onMouseEnter(layers: List, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mouseenter", layers, callback) + } + + fun onMouseLeave(layers: List, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mouseleave", layers, callback) + } + + fun onMouseOut(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("mouseout", layers, callback) + } + + fun onContextMenu(layers: List? = null, callback: (mapbox.MapMouseEvent) -> Unit) { + registerEvent("contextmenu", layers, callback) + } + + fun onWheel(callback: (mapbox.MapWheelEvent) -> Unit) { + registerEvent("wheel", null, callback) + } + + fun onTouchStart(layers: List? = null, callback: (mapbox.MapTouchEvent) -> Unit) { + registerEvent("touchstart", layers, callback) + } + + fun onTouchEnd(layers: List? = null, callback: (mapbox.MapTouchEvent) -> Unit) { + registerEvent("touchend", layers, callback) + } + + fun onTouchMove(callback: (mapbox.MapTouchEvent) -> Unit) { + registerEvent("touchmove", null, callback) + } + + fun onTouchCancel(layers: List? = null, callback: (mapbox.MapTouchEvent) -> Unit) { + registerEvent("touchcancel", layers, callback) + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapScope.kt new file mode 100644 index 0000000..52361a7 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapScope.kt @@ -0,0 +1,77 @@ +package ca.derekellis.mapbox + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ComposeNode +import androidx.compose.runtime.Composition +import androidx.compose.runtime.DefaultMonotonicFrameClock +import androidx.compose.runtime.Recomposer +import ca.derekellis.mapbox.compose.MapNodeApplier +import ca.derekellis.mapbox.compose.SourceNode +import ca.derekellis.mapbox.sources.SourceScope +import geojson.GeoJsonObject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import mapbox.GeoJSONSource +import mapbox.GeoJSONSourceRaw + +@Suppress("FunctionName") +class MapScope(private val mapRef: mapbox.Map) { + /** + * TODO: Add other GeoJSONSource parameters + */ + @Composable + fun GeoJsonSource( + id: String, + geojson: GeoJsonObject, + layers: @Composable SourceScope.() -> Unit, + ) { + GeoJsonSource(id, data = geojson, layers) + } + + @Composable + fun GeoJsonSource(id: String, url: String, layers: @Composable SourceScope.() -> Unit) { + GeoJsonSource(id, data = url, layers) + } + + @Composable + private fun GeoJsonSource(id: String, data: Any?, layers: @Composable SourceScope.() -> Unit) { + val layerScope = SourceScope(id, mapRef) + + ComposeNode( + factory = { + SourceNode( + id, + jsObject { + type = "geojson" + this.data = data + }, + ) + }, + update = { + set(id) { this.id = id } + set(data) { + (this.source.unsafeCast()).data = data + mapRef.getSource(id)?.setData(data) + + return@set + } + }, + content = { layerScope.layers() }, + ) + } +} + +fun CoroutineScope.applySources(mapRef: mapbox.Map, content: @Composable MapScope.() -> Unit) { + val recomposer = Recomposer(coroutineContext) + val composition = Composition(MapNodeApplier(mapRef), recomposer) + + launch(DefaultMonotonicFrameClock) { + recomposer.runRecomposeAndApplyChanges() + } + + val sourceScope = MapScope(mapRef) + + composition.setContent { + sourceScope.content() + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapboxMap.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapboxMap.kt new file mode 100644 index 0000000..086972a --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapboxMap.kt @@ -0,0 +1,99 @@ +package ca.derekellis.mapbox + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import io.architecture.mapbox.compose.library.LngLat +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import mapbox.Map +import org.jetbrains.compose.web.attributes.AttrsScope +import org.jetbrains.compose.web.css.height +import org.jetbrains.compose.web.css.vh +import org.jetbrains.compose.web.css.vw +import org.jetbrains.compose.web.css.width +import org.jetbrains.compose.web.dom.Div +import org.w3c.dom.HTMLDivElement + +@Composable +fun MapboxMapInternal( + accessToken: String, + style: String, + state: MapboxStateInternal = rememberMapboxStateInternal(), + hash: Boolean = false, + projection: String = "mercator", + containerAttrs: AttrsScope.() -> Unit = { + style { + height(100.vh) + width(100.vw) + } + }, + events: EventsScope.() -> Unit = {}, + sources: @Composable MapScope.() -> Unit, +) { + var map: mapbox.Map? by remember { mutableStateOf(null) } + val scope = rememberCoroutineScope() + Div(attrs = { + this.containerAttrs() + + ref { + map = Map( + jsObject { + this.accessToken = accessToken + container = it + this.style = style + this.projection = projection + this.hash = hash + + this.center = state.initialCenter.array + this.zoom = state.initialZoom + this.bearing = state.initialBearing + this.pitch = state.initialPitch + }, + ) + map?.resize() + + state.map = map + + var sourceScopeJob: Job? = null + map?.on("style.load") { + sourceScopeJob?.cancel() + sourceScopeJob = scope.launch { + // https://github.com/mapbox/mapbox-gl-js/issues/2268#issuecomment-401979967 + while (map?.isStyleLoaded() == false) { + delay(100) + } + applySources(map!!, sources) + EventsScope(map!!).events() + } + } + + onDispose { } + } + }) + + DisposableEffect(style) { + map?.setStyle(style) + onDispose { } + } + + DisposableEffect(projection) { + map?.setProjection(projection) + onDispose { } + } +} + +@Composable +fun rememberMapboxStateInternal( + center: LngLat = LngLat(0.0, 0.0), + zoom: Double = 0.0, + bearing: Double = 0.0, + pitch: Double = 0.0, +): MapboxStateInternal { + return remember { MapboxStateInternal(center, zoom, bearing, pitch) } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapboxStateInternal.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapboxStateInternal.kt new file mode 100644 index 0000000..6da1494 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/MapboxStateInternal.kt @@ -0,0 +1,185 @@ +package ca.derekellis.mapbox + +import io.architecture.mapbox.compose.library.LngLat +import io.architecture.mapbox.compose.library.LngLatBounds +import kotlinx.coroutines.suspendCancellableCoroutine +import mapbox.AnimationOptions +import mapbox.CameraOptions +import mapbox.FitBoundsOptions +import mapbox.PaddingOptions +import kotlin.coroutines.resume + +class MapboxStateInternal( + internal val initialCenter: LngLat = LngLat(0.0, 0.0), + internal val initialZoom: Double = 0.0, + internal val initialBearing: Double = 0.0, + internal val initialPitch: Double = 0.0, +) { + internal var map: mapbox.Map? = null + set(value) { + if (value != null) initMap() + field = value + } + + /** + * Performs deferred initialization of the map with the initial state + */ + private fun initMap() { + center = initialCenter + zoom = initialZoom + bearing = initialBearing + pitch = initialPitch + } + + var center: LngLat + get() = map!!.getCenter().let { LngLat(it.lng.toDouble(), it.lat.toDouble()) } + set(value) { + map?.setCenter(value.array) + } + + var zoom: Double + get() = map!!.getZoom().toDouble() + set(value) { + map?.setZoom(value) + } + + var bearing: Double + get() = map!!.getBearing().toDouble() + set(value) { + map?.setBearing(bearing) + } + + var padding: PaddingOptions + get() = map!!.getPadding() + set(value) { + map?.setPadding(value) + } + + var pitch: Double + get() = map!!.getPitch().toDouble() + set(value) { + map?.setPitch(value) + } + + suspend fun panBy(x: Double, y: Double, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + map?.panBy(arrayOf(x, y), options?.let(::jsObject)) + } + + suspend fun panTo(location: LngLat, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + map?.panTo(location.array, options?.let(::jsObject)) + } + + suspend fun zoomTo(zoom: Double, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + map?.zoomTo(zoom, options?.let(::jsObject)) + } + + suspend fun zoomIn(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + map?.zoomIn(options?.let(::jsObject)) + } + + suspend fun zoomOut(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + map?.zoomOut(options?.let(::jsObject)) + } + + suspend fun rotateTo(bearing: Double, options: (AnimationOptions.() -> Unit)? = null) = + doMoveAnimation { + map?.rotateTo(bearing, options?.let(::jsObject)) + } + + suspend fun resetNorth(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + map?.resetNorth(options?.let(::jsObject)) + } + + suspend fun resetNorthPitch(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + map?.resetNorthPitch(options?.let(::jsObject)) + } + + suspend fun snapToNorth(options: (AnimationOptions.() -> Unit)? = null) = doMoveAnimation { + map?.snapToNorth(options?.let(::jsObject)) + } + + fun cameraForBounds( + bounds: LngLatBounds, + options: (CameraOptions.() -> Unit)? = null, + ): CameraOptions? { + return map?.cameraForBounds(bounds.array, options?.let(::jsObject)) + .unsafeCast() + } + + suspend fun fitBounds(bounds: LngLatBounds, options: (FitBoundsOptions.() -> Unit)? = null) = + doMoveAnimation { + map?.fitBounds(bounds, options?.let(::jsObject)) + } + + suspend fun easeTo( + center: LngLat = this.center, + zoom: Double = this.zoom, + bearing: Double = this.bearing, + pitch: Double = this.pitch, + padding: PaddingOptions = this.padding, + options: (AnimationOptions.() -> Unit)? = null, + ) = doMoveAnimation { + map?.easeTo( + jsObject { + this.center = center.array + this.zoom = zoom + this.bearing = bearing + this.pitch = pitch + this.padding = padding + + options?.invoke(this) + }, + ) + } + + suspend fun flyTo( + center: LngLat = this.center, + zoom: Double = this.zoom, + bearing: Double = this.bearing, + pitch: Double = this.pitch, + padding: PaddingOptions = this.padding, + options: (AnimationOptions.() -> Unit)? = null, + ) = doMoveAnimation { + map?.flyTo( + jsObject { + this.center = center.array + this.zoom = zoom + this.bearing = bearing + this.pitch = pitch + this.padding = padding + + options?.invoke(this) + }, + ) + } + + // TODO: fitScreenCoordinates, jumpTo, easeTo, flyTo + + /** + * Runs the given [block], assuming that the [block] triggers a move animation on the [map]. + * Suspends until the move animation has ended. + */ + private suspend fun doMoveAnimation(block: () -> Unit) { + var listener: (Any) -> Unit + var resumed = false + suspendCancellableCoroutine { continuation -> + block() + listener = { _ -> + // If the animation is interrupted, the "moveend" listener may fire a second time before the cancellation is complete + if (!resumed) { + continuation.resume(Unit) + } + resumed = true + } + map?.on("moveend", listener) + + continuation.invokeOnCancellation { + map?.stop() + map?.off("moveend", listener) + } + } + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/Utils.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/Utils.kt new file mode 100644 index 0000000..abb3462 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/Utils.kt @@ -0,0 +1,3 @@ +package ca.derekellis.mapbox + +internal inline fun jsObject(block: T.() -> Unit): T = js("{}").unsafeCast().apply(block) \ No newline at end of file diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/compose/MapNode.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/compose/MapNode.kt new file mode 100644 index 0000000..891dfb1 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/compose/MapNode.kt @@ -0,0 +1,49 @@ +package ca.derekellis.mapbox.compose + +import ca.derekellis.mapbox.jsObject +import mapbox.Layer +import mapbox.Source + +internal sealed class MapNode + +internal class RootNode : MapNode() { + val children = mutableListOf() +} + +internal class SourceNode(var id: String, var source: Source) : MapNode() { + val layers: MutableList = mutableListOf() +} + +internal class LayerNode(var id: String, var layer: Layer) : MapNode() { + val props: MutableList = mutableListOf() + + val styleProps: Pair + get() { + val groups = props.groupBy { it.type } + val paintProps = groups[ExpressionType.PAINT]?.let { + val obj = jsObject { } + it.forEach { prop -> + obj[prop.name] = prop.expression + } + obj + } ?: jsObject { } + + val layoutProps = groups[ExpressionType.LAYOUT]?.let { + val obj = jsObject { } + it.forEach { prop -> + obj[prop.name] = prop.expression + } + obj + } ?: jsObject { } + + return Pair(paintProps, layoutProps) + } +} + +internal class ExpressionNode(var name: String, var expression: dynamic, val type: ExpressionType) : + MapNode() + +internal enum class ExpressionType { + LAYOUT, + PAINT, +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/compose/MapNodeApplier.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/compose/MapNodeApplier.kt new file mode 100644 index 0000000..ddac41e --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/compose/MapNodeApplier.kt @@ -0,0 +1,103 @@ +package ca.derekellis.mapbox.compose + +import androidx.compose.runtime.AbstractApplier +import mapbox.FillLayer +import mapbox.FillLayout +import mapbox.FillPaint +import mapbox.GeoJSONSource + +internal class MapNodeApplier(private val mapRef: mapbox.Map) : + AbstractApplier(RootNode()) { + override fun onClear() { + (root as? RootNode)?.run { + children.forEach { sourceNode -> + sourceNode.layers.forEach { + mapRef.removeLayer(it.layer.id) + } + mapRef.removeSource(sourceNode.id) + } + children.clear() + } + } + + override fun insertBottomUp(index: Int, instance: MapNode) { + when (val node = current) { + is SourceNode -> { + if (instance !is LayerNode) throw IllegalStateException("Node must be a LayerNode") + + if (mapRef.getLayer(instance.id) == null) { + val (paintProps, layoutProps) = instance.styleProps + + mapRef.addLayer( + instance.layer.unsafeCast().apply { + paint = paintProps.unsafeCast() + layout = layoutProps.unsafeCast() + }, + ) + node.layers.add(index, instance) + } else { + console.warn("Layer ${instance.id} already exists") + } + } + + is LayerNode -> { + if (instance !is ExpressionNode) throw IllegalStateException("Node must be an ExpressionNode") + node.props.add(index, instance) + } + + else -> {} + } + } + + override fun insertTopDown(index: Int, instance: MapNode) { + when (val node = current) { + is RootNode -> { + if (instance !is SourceNode) throw IllegalStateException("Node must be a SourceNode") + + if (mapRef.getSource(instance.id) == null) { + mapRef.addSource(instance.id, instance.source.unsafeCast()) + node.children.add(index, instance) + } else { + console.warn("Source ${instance.id} already exists") + } + } + + else -> {} + } + } + + override fun move(from: Int, to: Int, count: Int) {} + + override fun remove(index: Int, count: Int) { + when (val node = current) { + is SourceNode -> { + mapRef.removeLayer(node.layers[index].id) + node.layers.removeAt(index) + } + + is LayerNode -> { + val prop = node.props[index] + + if (mapRef.getLayer(node.id) == null) { + console.warn("Layer ${node.id} does not exist, cannot update style") + } else { + if (prop.type == ExpressionType.PAINT) { + mapRef.setPaintProperty(node.id, prop.name, null) + } else { + mapRef.setLayoutProperty(node.id, prop.name, null) + } + } + } + + is RootNode -> { + val source = node.children[index] + source.layers.forEach { mapRef.removeLayer(it.id) } + mapRef.removeSource(source.id) + + node.children.removeAt(index) + } + + else -> {} + } + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/BackgroundLayerScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/BackgroundLayerScope.kt new file mode 100644 index 0000000..cae7db9 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/BackgroundLayerScope.kt @@ -0,0 +1,42 @@ +package ca.derekellis.mapbox.layers + +import androidx.compose.runtime.Composable +import ca.derekellis.mapbox.style.Expression +import org.jetbrains.compose.web.css.CSSColorValue + +class BackgroundLayerScope(layerId: String, mapRef: mapbox.Map) : LayerScope(layerId, mapRef) { + @Composable + fun backgroundColor(color: String) { + paint("background-color", color) + } + + @Composable + fun backgroundColor(color: CSSColorValue) { + paint("background-color", color.toString()) + } + + @Composable + fun backgroundColor(expression: Expression) { + paint("background-color", expression) + } + + @Composable + fun backgroundOpacity(opacity: Double) { + paint("background-opacity", opacity) + } + + @Composable + fun backgroundOpacity(expression: Expression) { + paint("background-color", expression) + } + + @Composable + fun backgroundPattern(image: String) { + paint("background-color", image) + } + + @Composable + fun backgroundPattern(expression: Expression) { + paint("background-color", expression) + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/CircleLayerScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/CircleLayerScope.kt new file mode 100644 index 0000000..fbb2152 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/CircleLayerScope.kt @@ -0,0 +1,138 @@ +package ca.derekellis.mapbox.layers + +import androidx.compose.runtime.Composable +import ca.derekellis.mapbox.style.Anchor +import ca.derekellis.mapbox.style.Expression +import org.jetbrains.compose.web.css.CSSColorValue + +class CircleLayerScope(layerId: String, mapRef: mapbox.Map) : LayerScope(layerId, mapRef) { + @Composable + fun circleBlur(blur: Number) { + paint("circle-blur", blur) + } + + @Composable + fun circleBlur(expression: Expression) { + paint("circle-blur", expression) + } + + @Composable + fun circleColor(color: String) { + paint("circle-color", color) + } + + @Composable + fun circleColor(color: CSSColorValue) { + paint("circle-color", color.toString()) + } + + @Composable + fun circleColor(expression: Expression) { + paint("circle-color", expression) + } + + @Composable + fun circleOpacity(opacity: Number) { + paint("circle-opacity", opacity) + } + + @Composable + fun circleOpacity(expression: Expression) { + paint("circle-opacity", expression) + } + + @Composable + fun circlePitchAlignment(alignment: Anchor) { + paint("circle-pitch-alignment", alignment) + } + + @Composable + fun circlePitchAlignment(expression: Expression) { + paint("circle-pitch-alignment", expression) + } + + @Composable + fun circlePitchScale(scale: Anchor) { + paint("circle-pitch-scale", scale) + } + + @Composable + fun circlePitchScale(expression: Expression) { + paint("circle-pitch-scale", expression) + } + + @Composable + fun circleRadius(radius: Number) { + paint("circle-radius", radius) + } + + @Composable + fun circleRadius(expression: Expression) { + paint("circle-radius", expression) + } + + @Composable + fun circleSortKey(key: Number) { + layout("circle-sort-key", key) + } + + @Composable + fun circleSortKey(expression: Expression) { + layout("circle-sort-key", expression) + } + + @Composable + fun circleStrokeColor(color: String) { + paint("circle-stroke-color", color) + } + + @Composable + fun circleStrokeColor(color: CSSColorValue) { + paint("circle-stroke-color", color.toString()) + } + + @Composable + fun circleStrokeColor(expression: Expression) { + paint("circle-stroke-color", expression) + } + + @Composable + fun circleStrokeOpacity(opacity: Number) { + paint("circle-stroke-opacity", opacity) + } + + @Composable + fun circleStrokeOpacity(expression: Expression) { + paint("circle-stroke-opacity", expression) + } + + @Composable + fun circleStrokeWidth(width: Number) { + paint("circle-stroke-width", width) + } + + @Composable + fun circleStrokeWidth(expression: Expression) { + paint("circle-stroke-width", expression) + } + + @Composable + fun circleTranslate(x: Number, y: Number) { + paint("circle-translate", arrayOf(x, y)) + } + + @Composable + fun circleTranslate(expression: Expression) { + paint("circle-translate", expression) + } + + @Composable + fun circleTranslateAnchor(anchor: Anchor) { + paint("circle-translate-anchor", anchor) + } + + @Composable + fun circleTranslateAnchor(expression: Expression) { + paint("circle-translate-anchor", expression) + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/FillLayerScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/FillLayerScope.kt new file mode 100644 index 0000000..04ddc49 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/FillLayerScope.kt @@ -0,0 +1,98 @@ +package ca.derekellis.mapbox.layers + +import androidx.compose.runtime.Composable +import ca.derekellis.mapbox.style.Anchor +import ca.derekellis.mapbox.style.Expression +import org.jetbrains.compose.web.css.CSSColorValue + +class FillLayerScope(layerId: String, mapRef: mapbox.Map) : LayerScope(layerId, mapRef) { + @Composable + fun fillAntialias(value: Boolean) { + paint("fill-antialias", value) + } + + @Composable + fun fillAntialias(expression: Expression) { + paint("fill-antialias", expression) + } + + @Composable + fun fillColor(color: String) { + paint("fill-color", color) + } + + @Composable + fun fillColor(color: CSSColorValue) { + paint("fill-color", color.toString()) + } + + @Composable + fun fillColor(expression: Expression) { + paint("fill-color", expression) + } + + @Composable + fun fillOpacity(opacity: Double) { + paint("fill-opacity", opacity) + } + + @Composable + fun fillOpacity(expression: Expression) { + paint("fill-opacity", expression) + } + + @Composable + fun fillOutlineColor(color: String) { + paint("fill-outline-color", color) + } + + @Composable + fun fillOutlineColor(color: CSSColorValue) { + paint("fill-outline-color", color.toString()) + } + + @Composable + fun fillOutlineColor(expression: Expression) { + paint("fill-outline-color", expression) + } + + @Composable + fun fillPattern(image: String) { + paint("fill-pattern", image) + } + + @Composable + fun fillPattern(expression: Expression) { + paint("fill-pattern", expression) + } + + @Composable + fun fillSortKey(key: Double) { + layout("fill-sort-key", key) + } + + @Composable + fun fillSortKey(expression: Expression) { + layout("fill-sort-key", expression) + } + + @Composable + fun fillTranslate(x: Double, y: Double) { + paint("fill-translate", arrayOf(x, y)) + } + + @Composable + fun fillTranslate(expression: Expression) { + paint("fill-translate", expression) + } + + @Composable + fun fillTranslateAnchor(anchor: Anchor) { + paint("fill-translate-anchor", anchor) + } + + @Composable + fun fillTranslateAnchor(expression: Expression) { + paint("fill-translate-anchor", expression) + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/LayerScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/LayerScope.kt new file mode 100644 index 0000000..5f84db1 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/LayerScope.kt @@ -0,0 +1,62 @@ +package ca.derekellis.mapbox.layers + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ComposeNode +import ca.derekellis.mapbox.compose.ExpressionNode +import ca.derekellis.mapbox.compose.ExpressionType +import ca.derekellis.mapbox.compose.MapNodeApplier +import ca.derekellis.mapbox.style.Expression +import ca.derekellis.mapbox.style.Visibility + +abstract class LayerScope(protected val layerId: String, private val mapRef: mapbox.Map) { + @Composable + protected fun paint(name: String, value: Any?) { + ComposeNode( + factory = { + ExpressionNode(name, value, ExpressionType.PAINT) + }, + update = { + set(value) { + this.expression = value + if (mapRef.getLayer(layerId) != null) { + mapRef.setPaintProperty(layerId, this.name, value) + } + } + }, + ) + } + + @Composable + @Suppress("NOTHING_TO_INLINE") + protected inline fun paint(name: String, value: Expression) { + paint(name, value.parts) + } + + @Composable + protected fun layout(name: String, value: Any?) { + ComposeNode( + factory = { + ExpressionNode(name, value, ExpressionType.LAYOUT) + }, + update = { + set(value) { + this.expression = value + if (mapRef.getLayer(layerId) != null) { + mapRef.setLayoutProperty(layerId, this.name, value) + } + } + }, + ) + } + + @Composable + @Suppress("NOTHING_TO_INLINE") + protected inline fun layout(name: String, value: Expression) { + layout(name, value.parts) + } + + @Composable + public fun visibility(visibility: Visibility) { + layout("visibility", visibility) + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/LineLayerScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/LineLayerScope.kt new file mode 100644 index 0000000..c716a38 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/LineLayerScope.kt @@ -0,0 +1,155 @@ +package ca.derekellis.mapbox.layers + +import androidx.compose.runtime.Composable +import ca.derekellis.mapbox.style.Anchor +import ca.derekellis.mapbox.style.Expression +import ca.derekellis.mapbox.style.LineCap +import ca.derekellis.mapbox.style.LineJoin +import org.jetbrains.compose.web.css.CSSColorValue + +class LineLayerScope(layerId: String, mapRef: mapbox.Map) : LayerScope(layerId, mapRef) { + @Composable + fun lineBlur(blur: Double) { + paint("line-blur", blur) + } + + @Composable + fun lineBlur(expression: Expression) { + paint("line-blur", expression) + } + + @Composable + fun lineCap(cap: LineCap) { + layout("line-cap", cap) + } + + @Composable + fun lineCap(expression: Expression) { + layout("line-cap", expression) + } + + @Composable + fun lineColor(color: String) { + paint("line-color", color) + } + + @Composable + fun lineColor(color: CSSColorValue) { + paint("line-color", color.toString()) + } + + @Composable + fun lineColor(expression: Expression) { + paint("line-color", expression) + } + + @Composable + fun lineDasharray(vararg values: Double) { + paint("line-dasharray", values) + } + + @Composable + fun lineDasharray(expression: Expression) { + paint("line-dasharray", expression) + } + + @Composable + fun lineGapWidth(width: Double) { + paint("line-gap-width", width) + } + + @Composable + fun lineGapWidth(expression: Expression) { + paint("line-gap-width", expression) + } + + @Composable + fun lineGradient(expression: Expression) { + paint("line-gradient", expression) + } + + @Composable + fun lineJoin(join: LineJoin) { + layout("line-join", join) + } + + @Composable + fun lineJoin(expression: Expression) { + layout("line-join", expression) + } + + @Composable + fun lineMiterLimit(limit: Double) { + layout("line-miter-limit", limit) + } + + @Composable + fun lineMiterLimit(expression: Expression) { + layout("line-miter-limit", expression) + } + + @Composable + fun lineOffset(offset: Double) { + paint("line-offset", offset) + } + + @Composable + fun lineOffset(expression: Expression) { + paint("line-offset", expression) + } + + @Composable + fun linePattern(pattern: String) { + paint("line-pattern", pattern) + } + + @Composable + fun linePattern(expression: Expression) { + paint("line-pattern", expression) + } + + @Composable + fun lineRoundLimit(limit: Double) { + layout("line-round-limit", limit) + } + + @Composable + fun lineRoundLimit(expression: Expression) { + layout("line-round-limit", expression) + } + + @Composable + fun lineSortKey(key: Double) { + layout("line-sort-key", key) + } + + @Composable + fun lineSortKey(expression: Expression) { + layout("line-sort-key", expression) + } + + @Composable + fun lineTranslate(expression: Expression) { + paint("line-translate", expression) + } + + @Composable + fun lineTranslateAnchor(anchor: Anchor) { + paint("line-translate-anchor", anchor) + } + + @Composable + fun lineTranslateAnchor(expression: Expression) { + paint("line-translate-anchor", expression) + } + + @Composable + fun lineWidth(width: Double) { + paint("line-width", width) + } + + @Composable + fun lineWidth(expression: Expression) { + paint("line-width", expression) + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/SymbolLayerScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/SymbolLayerScope.kt new file mode 100644 index 0000000..95c21d6 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/layers/SymbolLayerScope.kt @@ -0,0 +1,591 @@ +package ca.derekellis.mapbox.layers + +import androidx.compose.runtime.Composable +import ca.derekellis.mapbox.style.Alignment +import ca.derekellis.mapbox.style.Anchor +import ca.derekellis.mapbox.style.Expression +import ca.derekellis.mapbox.style.Justify +import ca.derekellis.mapbox.style.PositionAnchor +import ca.derekellis.mapbox.style.SymbolPlacement +import ca.derekellis.mapbox.style.SymbolZOrder +import ca.derekellis.mapbox.style.TextFit +import ca.derekellis.mapbox.style.TextTransform +import ca.derekellis.mapbox.style.WritingMode +import org.jetbrains.compose.web.css.CSSColorValue + +class SymbolLayerScope(layerId: String, mapRef: mapbox.Map) : LayerScope(layerId, mapRef) { + @Composable + fun iconAllowOverlap(allow: Boolean) { + layout("icon-allow-overlap", allow) + } + + @Composable + fun iconAllowOverlap(expression: Expression) { + layout("icon-allow-overlap", expression) + } + + @Composable + fun iconAnchor(anchor: PositionAnchor) { + layout("icon-anchor", anchor) + } + + @Composable + fun iconAnchor(expression: Expression) { + layout("icon-anchor", expression) + } + + @Composable + fun iconColor(color: String) { + paint("icon-color", color) + } + + @Composable + fun iconColor(color: CSSColorValue) { + paint("icon-color", color.toString()) + } + + @Composable + fun iconColor(expression: Expression) { + paint("icon-color", expression) + } + + @Composable + fun iconHaloBlur(blur: Double) { + paint("icon-halo-blur", blur) + } + + @Composable + fun iconHaloBlur(expression: Expression) { + paint("icon-halo-blur", expression) + } + + @Composable + fun iconHaloColor(color: String) { + paint("icon-halo-color", color) + } + + @Composable + fun iconHaloColor(color: CSSColorValue) { + paint("icon-halo-color", color.toString()) + } + + @Composable + fun iconHaloColor(expression: Expression) { + paint("icon-halo-color", expression) + } + + @Composable + fun iconHaloWidth(width: Double) { + paint("icon-halo-width", width) + } + + @Composable + fun iconHaloWidth(expression: Expression) { + paint("icon-halo-width", expression) + } + + @Composable + fun iconIgnorePlacement(ignore: Boolean) { + layout("icon-ignore-placement", ignore) + } + + @Composable + fun iconIgnorePlacement(expression: Expression) { + layout("icon-ignore-placement", expression) + } + + @Composable + fun iconImage(image: String) { + layout("icon-image", image) + } + + @Composable + fun iconImage(expression: Expression) { + layout("icon-image", expression) + } + + @Composable + fun iconKeepUpright(keep: Boolean) { + layout("icon-keep-upright", keep) + } + + @Composable + fun iconKeepUpright(expression: Expression) { + layout("icon-keep-upright", expression) + } + + @Composable + fun iconOffset(x: Double, y: Double) { + layout("icon-offset", arrayOf(x, y)) + } + + @Composable + fun iconOffset(expression: Expression) { + layout("icon-offset", expression) + } + + @Composable + fun iconOpacity(opacity: Double) { + paint("icon-opacity", opacity) + } + + @Composable + fun iconOpacity(expression: Expression) { + paint("icon-opacity", expression) + } + + @Composable + fun iconOptional(optional: Boolean) { + layout("icon-optional", optional) + } + + @Composable + fun iconOptional(expression: Expression) { + layout("icon-optional", expression) + } + + @Composable + fun iconPadding(padding: Double) { + layout("icon-padding", padding) + } + + @Composable + fun iconPadding(expression: Expression) { + layout("icon-padding", expression) + } + + @Composable + fun iconPitchAlignment(alignment: Alignment) { + layout("icon-pitch-alignment", alignment) + } + + @Composable + fun iconPitchAlignment(expression: Expression) { + layout("icon-pitch-alignment", expression) + } + + @Composable + fun iconRotate(rotation: Double) { + layout("icon-rotation", rotation) + } + + @Composable + fun iconRotate(expression: Expression) { + layout("icon-rotation", expression) + } + + @Composable + fun iconRotationAlignment(alignment: Alignment) { + layout("icon-rotation-alignment", alignment) + } + + @Composable + fun iconRotationAlignment(expression: Expression) { + layout("icon-rotation-alignment", expression) + } + + @Composable + fun iconSize(size: Double) { + layout("icon-size", size) + } + + @Composable + fun iconSize(expression: Expression) { + layout("icon-size", expression) + } + + @Composable + fun iconTextFit(fit: TextFit) { + layout("icon-text-fit", fit) + } + + @Composable + fun iconTextFit(expression: Expression) { + layout("icon-text-fit", expression) + } + + @Composable + fun iconTextFitPadding( + top: Double = 0.0, + right: Double = 0.0, + bottom: Double = 0.0, + left: Double = 0.0, + ) { + layout("icon-text-fit-padding", arrayOf(top, right, bottom, left)) + } + + @Composable + fun iconTextFitPadding(expression: Expression) { + layout("icon-text-fit-padding", expression) + } + + @Composable + fun iconTranslate(x: Double, y: Double) { + paint("icon-translate", arrayOf(x, y)) + } + + @Composable + fun iconTranslate(expression: Expression) { + paint("icon-translate", expression) + } + + @Composable + fun iconTranslateAnchor(anchor: Anchor) { + paint("icon-translate-anchor", anchor) + } + + @Composable + fun iconTranslateAnchor(expression: Expression) { + paint("icon-translate-anchor", expression) + } + + @Composable + fun symbolAvoidEdges(avoid: Boolean) { + layout("symbol-avoid-edges", avoid) + } + + @Composable + fun symbolAvoidEdges(expression: Expression) { + layout("symbol-avoid-edges", expression) + } + + @Composable + fun symbolPlacement(placement: SymbolPlacement) { + layout("symbol-placement", placement) + } + + @Composable + fun symbolPlacement(expression: Expression) { + layout("symbol-placement", expression) + } + + @Composable + fun symbolSortKey(key: Double) { + layout("symbol-sort-key", key) + } + + @Composable + fun symbolSortKey(expression: Expression) { + layout("symbol-sort-key", expression) + } + + @Composable + fun symbolSpacing(spacing: Double) { + layout("symbol-spacing", spacing) + } + + @Composable + fun symbolSpacing(expression: Expression) { + layout("symbol-spacing", expression) + } + + @Composable + fun symbolZOrder(order: SymbolZOrder) { + layout("symbol-z-order", order) + } + + @Composable + fun symbolZOrder(expression: Expression) { + layout("symbol-z-order", expression) + } + + @Composable + fun textAllowOverlap(overlap: Boolean) { + layout("text-allow-overlap", overlap) + } + + @Composable + fun textAllowOverlap(expression: Expression) { + layout("text-allow-overlap", expression) + } + + @Composable + fun textAnchor(anchor: PositionAnchor) { + layout("text-anchor", anchor) + } + + @Composable + fun textAnchor(expression: Expression) { + layout("text-anchor", expression) + } + + @Composable + fun textColor(color: String) { + paint("text-color", color) + } + + @Composable + fun textColor(color: CSSColorValue) { + paint("text-color", color.toString()) + } + + @Composable + fun textColor(expression: Expression) { + paint("text-color", expression) + } + + @Composable + fun textField(field: String) { + layout("text-field", field) + } + + @Composable + fun textField(expression: Expression) { + layout("text-field", expression) + } + + @Composable + fun textFont(vararg stack: String) { + layout("text-font", stack) + } + + @Composable + fun textFont(expression: Expression) { + layout("text-font", expression) + } + + @Composable + fun textHaloBlur(blur: Double) { + paint("text-halo-blur", blur) + } + + @Composable + fun textHaloBlur(expression: Expression) { + paint("text-halo-blur", expression) + } + + @Composable + fun textHaloColor(color: String) { + paint("text-halo-color", color) + } + + @Composable + fun textHaloColor(color: CSSColorValue) { + paint("text-halo-color", color.toString()) + } + + @Composable + fun textHaloColor(expression: Expression) { + paint("text-halo-color", expression) + } + + @Composable + fun textHaloWidth(width: Double) { + paint("text-halo-width", width) + } + + @Composable + fun textHaloWidth(expression: Expression) { + paint("text-halo-width", expression) + } + + @Composable + fun textIgnorePlacement(ignore: Boolean) { + layout("text-ignore-placement", ignore) + } + + @Composable + fun textIgnorePlacement(expression: Expression) { + layout("text-ignore-placement", expression) + } + + @Composable + fun textJustify(justify: Justify) { + layout("text-justify", justify) + } + + @Composable + fun textJustify(expression: Expression) { + layout("text-justify", expression) + } + + @Composable + fun textKeepUpright(keep: Boolean) { + layout("text-keep-upright", keep) + } + + @Composable + fun textKeepUpright(expression: Expression) { + layout("text-keep-upright", expression) + } + + @Composable + fun textLetterSpacing(spacing: Double) { + layout("text-letter-spacing", spacing) + } + + @Composable + fun textLetterSpacing(expression: Expression) { + layout("text-letter-spacing", expression) + } + + @Composable + fun textLineHeight(height: Double) { + layout("text-line-height", height) + } + + @Composable + fun textLineHeight(expression: Expression) { + layout("text-line-height", expression) + } + + @Composable + fun textMaxAngle(max: Double) { + layout("text-max-angle", max) + } + + @Composable + fun textMaxAngle(expression: Expression) { + layout("text-max-angle", expression) + } + + @Composable + fun textMaxWidth(max: Double) { + layout("text-max-width", max) + } + + @Composable + fun textMaxWidth(expression: Expression) { + layout("text-max-width", expression) + } + + @Composable + fun textOffset(x: Double, y: Double) { + layout("text-offset", arrayOf(x, y)) + } + + @Composable + fun textOffset(expression: Expression) { + layout("text-offset", expression) + } + + @Composable + fun textOpacity(opacity: Double) { + paint("text-opacity", opacity) + } + + @Composable + fun textOpacity(expression: Expression) { + paint("text-opacity", expression) + } + + @Composable + fun textOptional(optional: Boolean) { + layout("text-optional", optional) + } + + @Composable + fun textOptional(expression: Expression) { + layout("text-optional", expression) + } + + @Composable + fun textPadding(padding: Double) { + layout("text-padding", padding) + } + + @Composable + fun textPadding(expression: Expression) { + layout("text-padding", expression) + } + + @Composable + fun textPitchAlignment(alignment: Alignment) { + layout("text-pitch-alignment", alignment) + } + + @Composable + fun textPitchAlignment(expression: Expression) { + layout("text-pitch-alignment", expression) + } + + @Composable + fun textRadialOffset(offset: Double) { + layout("text-radial-offset", offset) + } + + @Composable + fun textRadialOffset(expression: Expression) { + layout("text-radial-offset", expression) + } + + @Composable + fun textRotate(degrees: Double) { + layout("text-rotate", degrees) + } + + @Composable + fun textRotate(expression: Expression) { + layout("text-rotate", expression) + } + + @Composable + fun textRotationAlignment(alignment: Alignment) { + layout("text-rotation-alignment", alignment) + } + + @Composable + fun textRotationAlignment(expression: Expression) { + layout("text-rotation-alignment", expression) + } + + @Composable + fun textSize(size: Double) { + layout("text-size", size) + } + + @Composable + fun textSize(expression: Expression) { + layout("text-size", expression) + } + + @Composable + fun textTransform(transform: TextTransform) { + layout("text-transform", transform) + } + + @Composable + fun textTransform(expression: Expression) { + layout("text-transform", expression) + } + + @Composable + fun textTranslate(x: Double, y: Double) { + paint("text-translate", arrayOf(x, y)) + } + + @Composable + fun textTranslate(expression: Expression) { + paint("text-translate", expression) + } + + @Composable + fun textTranslateAnchor(anchor: Anchor) { + paint("text-translate-anchor", anchor) + } + + @Composable + fun textTranslateAnchor(expression: Expression) { + paint("text-translate-anchor", expression) + } + + @Composable + fun textVariableAnchor(anchor: PositionAnchor) { + layout("text-variable-anchor", anchor) + } + + @Composable + fun textVariableAnchor(expression: Expression) { + layout("text-variable-anchor", expression) + } + + @Composable + fun textWritingMode(mode: WritingMode) { + layout("text-writing-mode", mode) + } + + @Composable + fun textWritingMode(expression: Expression) { + layout("text-writing-mode", expression) + } +} \ No newline at end of file diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/sources/SourceScope.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/sources/SourceScope.kt new file mode 100644 index 0000000..ddbbe99 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/sources/SourceScope.kt @@ -0,0 +1,103 @@ +package ca.derekellis.mapbox.sources + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ComposeNode +import ca.derekellis.mapbox.compose.LayerNode +import ca.derekellis.mapbox.compose.MapNodeApplier +import ca.derekellis.mapbox.jsObject +import ca.derekellis.mapbox.layers.BackgroundLayerScope +import ca.derekellis.mapbox.layers.CircleLayerScope +import ca.derekellis.mapbox.layers.FillLayerScope +import ca.derekellis.mapbox.layers.LayerScope +import ca.derekellis.mapbox.layers.LineLayerScope +import ca.derekellis.mapbox.layers.SymbolLayerScope +import ca.derekellis.mapbox.style.Expression +import mapbox.FillLayer + +private typealias GenericLayer = FillLayer + +class SourceScope(private val sourceId: String, private val mapRef: mapbox.Map) { + @Composable + private fun Layer( + id: String, + type: String, + filter: Expression?, + scope: T, + style: @Composable T.() -> Unit, + ) { + ComposeNode( + factory = { + LayerNode( + id, + jsObject { + this.type = type + this.source = sourceId + this.id = id + if (filter != null) { + this.filter = filter.parts.unsafeCast>() + } + }, + ) + }, + update = { + set(id) { this.id = id } + set(filter) { + if (mapRef.getLayer(id) != null) { + mapRef.setFilter(id, filter?.parts.unsafeCast?>()) + } + } + }, + content = { scope.style() }, + ) + } + + @Composable + fun BackgroundLayer( + id: String, + filter: Expression? = null, + style: @Composable BackgroundLayerScope.() -> Unit = {}, + ) { + val styleScope = BackgroundLayerScope(id, mapRef) + Layer(id, "background", filter, styleScope, style) + } + + @Composable + fun FillLayer( + id: String, + filter: Expression? = null, + style: @Composable FillLayerScope.() -> Unit = {}, + ) { + val styleScope = FillLayerScope(id, mapRef) + Layer(id, "fill", filter, styleScope, style) + } + + @Composable + fun LineLayer( + id: String, + filter: Expression? = null, + style: @Composable LineLayerScope.() -> Unit = {}, + ) { + val styleScope = LineLayerScope(id, mapRef) + Layer(id, "line", filter, styleScope, style) + } + + @Composable + fun SymbolLayer( + id: String, + filter: Expression? = null, + style: @Composable SymbolLayerScope.() -> Unit = {}, + ) { + val styleScope = SymbolLayerScope(id, mapRef) + Layer(id, "symbol", filter, styleScope, style) + } + + @Composable + fun CircleLayer( + id: String, + filter: Expression? = null, + style: @Composable CircleLayerScope.() -> Unit = {}, + ) { + val styleScope = CircleLayerScope(id, mapRef) + Layer(id, "circle", filter, styleScope, style) + } +} \ No newline at end of file diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/Expression.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/Expression.kt new file mode 100644 index 0000000..f567ef4 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/Expression.kt @@ -0,0 +1,61 @@ +@file:Suppress("NOTHING_TO_INLINE") + +package ca.derekellis.mapbox.style + +value class Expression(val parts: Array) + +inline fun expression(vararg parts: Any): Expression = Expression(parts) + +inline fun at(index: Int, array: dynamic): Expression = expression("at", index, array) + +inline fun get(prop: String): Expression = expression("get", prop) + +inline fun get(prop: String, obj: dynamic): Expression = expression("get", prop, obj) + +inline fun has(prop: String): Expression = expression("has", prop) + +inline fun has(prop: String, obj: dynamic): Expression = expression("has", prop, obj) + +inline fun `in`(keyword: dynamic, input: dynamic): Expression = expression("in", keyword, input) + +inline fun not(value: dynamic): Expression = expression("!", value) + +inline fun neq(a: dynamic, b: dynamic): Expression = expression("!=", a, b) + +inline fun neq(a: dynamic, b: dynamic, collator: dynamic): Expression = + expression("!=", a, b, collator) + +inline fun lt(a: dynamic, b: dynamic): Expression = expression("<", a, b) + +inline fun lt(a: dynamic, b: dynamic, collator: dynamic): Expression = + expression("<", a, b, collator) + +inline fun lte(a: dynamic, b: dynamic): Expression = expression("<=", a, b) + +inline fun lte(a: dynamic, b: dynamic, collator: dynamic): Expression = + expression("<=", a, b, collator) + +inline fun eq(a: dynamic, b: dynamic): Expression = expression("==", a, b) + +inline fun eq(a: dynamic, b: dynamic, collator: dynamic): Expression = + expression("==", a, b, collator) + +inline fun gt(a: dynamic, b: dynamic): Expression = expression(">", a, b) + +inline fun gt(a: dynamic, b: dynamic, collator: dynamic): Expression = + expression(">", a, b, collator) + +inline fun gte(a: dynamic, b: dynamic): Expression = expression(">=", a, b) + +inline fun gte(a: dynamic, b: dynamic, collator: dynamic): Expression = + expression(">=", a, b, collator) + +inline fun all(a: dynamic, b: dynamic): Expression = expression("all", a, b) + +inline fun all(a: dynamic, b: dynamic, vararg rest: dynamic): Expression = + expression("all", a, b, *rest) + +inline fun any(a: dynamic, b: dynamic): Expression = expression("any", a, b) + +inline fun any(a: dynamic, b: dynamic, vararg rest: dynamic): Expression = + expression("any", a, b, *rest) diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/FeatureDataExpressions.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/FeatureDataExpressions.kt new file mode 100644 index 0000000..a547501 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/FeatureDataExpressions.kt @@ -0,0 +1,13 @@ +@file:Suppress("NOTHING_TO_INLINE") + +package ca.derekellis.mapbox.style + +inline fun accumulated(): Expression = expression("accumulated") + +inline fun featureState(): Expression = expression("feature-state") + +inline fun geometryType(): Expression = expression("geometry-type") + +inline fun id(): Expression = expression("id") + +inline fun lineProgress(): Expression = expression("line-progress") diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/RampExpressions.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/RampExpressions.kt new file mode 100644 index 0000000..32d4821 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/RampExpressions.kt @@ -0,0 +1,48 @@ +@file:Suppress("NOTHING_TO_INLINE") + +package ca.derekellis.mapbox.style + +public sealed interface InterpolationType { + public companion object { + public inline val linear: InterpolationType get() = arrayOf("linear").unsafeCast() + + public inline fun exponential(base: Double) = + arrayOf("exponential", base).unsafeCast() + + public inline fun cubicBezier(x1: Double, y1: Double, x2: Double, y2: Double) = + arrayOf("cubic-bezier", x1, y1, x2, y2).unsafeCast() + } +} + +public inline fun interpolate( + type: InterpolationType, + input: Expression, + vararg stops: Pair, +): Expression = + expression( + "interpolate", + type, + input.parts, + *Array(stops.size * 2) { i -> if (i % 2 == 0) stops[i / 2].first else stops[(i - 1) / 2].second }) + +public inline fun interpolateHcl( + type: InterpolationType, + input: Expression, + vararg stops: Pair, +): Expression = + expression( + "interpolate-hcl", + type, + input.parts, + *Array(stops.size * 2) { i -> if (i % 2 == 0) stops[i / 2].first else stops[(i - 1) / 2].second }) + +public inline fun interpolateLab( + type: InterpolationType, + input: Expression, + vararg stops: Pair, +): Expression = + expression( + "interpolate-lab", + type, + input.parts, + *Array(stops.size * 2) { i -> if (i % 2 == 0) stops[i / 2].first else stops[(i - 1) / 2].second }) diff --git a/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/StyleProperties.kt b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/StyleProperties.kt new file mode 100644 index 0000000..770e06e --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/ca/derekellis/mapbox/style/StyleProperties.kt @@ -0,0 +1,101 @@ +package ca.derekellis.mapbox.style + +sealed interface Anchor { + companion object { + inline val map: Anchor get() = "map".unsafeCast() + inline val viewport: Anchor get() = "viewport".unsafeCast() + } +} + +sealed interface PositionAnchor { + companion object { + inline val center: PositionAnchor get() = "center".unsafeCast() + inline val left: PositionAnchor get() = "left".unsafeCast() + inline val right: PositionAnchor get() = "right".unsafeCast() + inline val bottom: PositionAnchor get() = "bottom".unsafeCast() + inline val topLeft: PositionAnchor get() = "top-left".unsafeCast() + inline val topRight: PositionAnchor get() = "top-right".unsafeCast() + inline val bottomLeft: PositionAnchor get() = "bottom-left".unsafeCast() + inline val bottomRight: PositionAnchor get() = "bottom-right".unsafeCast() + } +} + +sealed interface Justify { + companion object { + inline val auto: Justify get() = "auto".unsafeCast() + inline val left: Justify get() = "left".unsafeCast() + inline val center: Justify get() = "center".unsafeCast() + inline val right: Justify get() = "right".unsafeCast() + } +} + +sealed interface Visibility { + companion object { + inline val visible: Visibility get() = "visible".unsafeCast() + inline val none: Visibility get() = "none".unsafeCast() + } +} + +sealed interface LineCap { + companion object { + inline val butt: LineCap get() = "butt".unsafeCast() + inline val round: LineCap get() = "round".unsafeCast() + inline val square: LineCap get() = "square".unsafeCast() + } +} + +sealed interface LineJoin { + companion object { + inline val bevel: LineJoin get() = "bevel".unsafeCast() + inline val round: LineJoin get() = "round".unsafeCast() + inline val miter: LineJoin get() = "miter".unsafeCast() + } +} + +sealed interface Alignment { + companion object { + inline val map: Alignment get() = "map".unsafeCast() + inline val viewport: Alignment get() = "viewport".unsafeCast() + inline val auto: Alignment get() = "auto".unsafeCast() + } +} + +sealed interface TextFit { + companion object { + inline val none: TextFit get() = "none".unsafeCast() + inline val width: TextFit get() = "width".unsafeCast() + inline val height: TextFit get() = "height".unsafeCast() + inline val both: TextFit get() = "both".unsafeCast() + } +} + +sealed interface SymbolPlacement { + companion object { + inline val point: SymbolPlacement get() = "point".unsafeCast() + inline val line: SymbolPlacement get() = "line".unsafeCast() + inline val lineCenter: SymbolPlacement get() = "line-center".unsafeCast() + } +} + +sealed interface SymbolZOrder { + companion object { + inline val auto: SymbolZOrder get() = "auto".unsafeCast() + inline val viewportY: SymbolZOrder get() = "viewport-y".unsafeCast() + inline val source: SymbolZOrder get() = "source".unsafeCast() + } +} + +sealed interface TextTransform { + companion object { + inline val none: TextTransform get() = "none".unsafeCast() + inline val uppercase: TextTransform get() = "uppercase".unsafeCast() + inline val lowercase: TextTransform get() = "lowercase".unsafeCast() + } +} + +sealed interface WritingMode { + companion object { + inline val horizontal: WritingMode get() = "horizontal".unsafeCast() + inline val vertical: WritingMode get() = "vertical".unsafeCast() + } +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/geojson/GeoJson.kt b/compose-mapbox-library/src/jsMain/kotlin/geojson/GeoJson.kt new file mode 100644 index 0000000..6137d14 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/geojson/GeoJson.kt @@ -0,0 +1,63 @@ +package geojson + +import kotlin.js.Json + +typealias Position = Array + +external interface GeoJsonObject { + var type: String /* "Point" | "MultiPoint" | "LineString" | "MultiLineString" | "Polygon" | "MultiPolygon" | "GeometryCollection" */ + var bbox: dynamic /* JsTuple | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface Geometry + +external interface Point : GeoJsonObject, Geometry { + override var type: String /* "Point" */ + var coordinates: Position +} + +external interface MultiPoint : GeoJsonObject, Geometry { + override var type: String /* "MultiPoint" */ + var coordinates: Array +} + +external interface LineString : GeoJsonObject, Geometry { + override var type: String /* "LineString" */ + var coordinates: Array +} + +external interface MultiLineString : GeoJsonObject, Geometry { + override var type: String /* "MultiLineString" */ + var coordinates: Array> +} + +external interface Polygon : GeoJsonObject, Geometry { + override var type: String /* "Polygon" */ + var coordinates: Array> +} + +external interface MultiPolygon : GeoJsonObject, Geometry { + override var type: String /* "MultiPolygon" */ + var coordinates: Array>> +} + +external interface GeometryCollection : GeoJsonObject, Geometry { + override var type: String /* "GeometryCollection" */ + var geometries: Array +} + +external interface Feature : GeoJsonObject { + override var type: String /* "Feature" */ + var geometry: Geometry + var id: dynamic /* String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var properties: Json? +} + +external interface FeatureCollection : GeoJsonObject { + override var type: String /* "FeatureCollection" */ + var features: Array +} diff --git a/compose-mapbox-library/src/jsMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.js.kt b/compose-mapbox-library/src/jsMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.js.kt new file mode 100644 index 0000000..3e6ad4e --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.js.kt @@ -0,0 +1,39 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import ca.derekellis.mapbox.MapboxMapInternal +import ca.derekellis.mapbox.rememberMapboxStateInternal +import io.architecture.mapbox.compose.library.state.MapboxState +import org.jetbrains.compose.web.css.height +import org.jetbrains.compose.web.css.vh +import org.jetbrains.compose.web.css.vw +import org.jetbrains.compose.web.css.width + +@Composable +actual fun MapBoxMap( + modifier: Modifier, + accessToken: String, + state: MapboxState, + style: String, + content: @MapboxMapComposableMarker @Composable (MapboxMapScope.() -> Unit)?, +) { + MapboxMapInternal( + accessToken = accessToken, + style = style, + state = rememberMapboxStateInternal( + zoom = state.zoom, + pitch = state.pitch, + bearing = state.bearing, + center = LngLat(state.center.longitude, state.center.latitude), + ), + containerAttrs = { + style { + height(100.vh) + width(100.vw) + } + }, + ) { + + } +} \ No newline at end of file diff --git a/compose-mapbox-library/src/jsMain/kotlin/mapbox/Declarations.kt b/compose-mapbox-library/src/jsMain/kotlin/mapbox/Declarations.kt new file mode 100644 index 0000000..da80638 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/mapbox/Declarations.kt @@ -0,0 +1,11 @@ +package mapbox + +typealias quat = Array + +typealias vec3 = Array + +typealias TransformRequestFunction = (url: String, resourceType: String /* "Unknown" | "Style" | "Source" | "Tile" | "Glyphs" | "SpriteImage" | "SpriteJSON" | "Image" */) -> RequestParameters + +typealias ExpressionSpecification = Array + +typealias EventedListener = (obj: Any) -> Any diff --git a/compose-mapbox-library/src/jsMain/kotlin/mapbox/Mapbox.kt b/compose-mapbox-library/src/jsMain/kotlin/mapbox/Mapbox.kt new file mode 100644 index 0000000..c89da61 --- /dev/null +++ b/compose-mapbox-library/src/jsMain/kotlin/mapbox/Mapbox.kt @@ -0,0 +1,2327 @@ +@file:JsModule("mapbox-gl") +@file:JsNonModule +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", + "OVERRIDING_FINAL_MEMBER", + "RETURN_TYPE_MISMATCH_ON_OVERRIDE", + "CONFLICTING_OVERLOADS" +) + +package mapbox + +import geojson.Feature +import geojson.FeatureCollection +import geojson.Point +import org.khronos.webgl.ArrayBufferView +import org.khronos.webgl.WebGLContextEvent +import org.khronos.webgl.WebGLRenderingContext +import org.w3c.dom.HTMLCanvasElement +import org.w3c.dom.HTMLElement +import org.w3c.dom.HTMLImageElement +import org.w3c.dom.HTMLVideoElement +import org.w3c.dom.ImageBitmap +import org.w3c.dom.ImageData +import org.w3c.dom.Node +import org.w3c.dom.TouchEvent +import org.w3c.dom.events.MouseEvent +import org.w3c.dom.events.WheelEvent +import kotlin.js.Json +import kotlin.js.Promise + +external var accessToken: String + +external var version: String + +external var baseApiUrl: String + +external var workerCount: Number + +external var maxParallelImageRequests: Number + +external interface `T$0` { + var failIfMajorPerformanceCaveat: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external fun supported(options: `T$0` = definedExternally): Boolean + +external fun clearStorage(callback: (err: Error) -> Unit = definedExternally) + +external fun setRTLTextPlugin( + pluginURL: String, + callback: (error: Error) -> Unit, + deferred: Boolean = definedExternally, +) + +external fun getRTLTextPluginStatus(): String /* "unavailable" | "loading" | "loaded" | "error" */ + +external fun prewarm() + +external fun clearPrewarmedResources() + +external interface `T$1` { + var lng: Number + var lat: Number +} + +external interface `T$2` { + var lon: Number + var lat: Number +} + +external interface `T$3` { + @nativeGetter + operator fun get(`_`: String): dynamic /* Point? | JsTuple */ + + @nativeSetter + operator fun set(`_`: String, value: Point) + + @nativeSetter + operator fun set(`_`: String, value: dynamic /* JsTuple */) +} + +external interface DragPanOptions { + var linearity: Number? + get() = definedExternally + set(value) = definedExternally + var easing: ((t: Number) -> Number)? + get() = definedExternally + set(value) = definedExternally + var deceleration: Number? + get() = definedExternally + set(value) = definedExternally + var maxSpeed: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface InteractiveOptions { + var around: String? /* "center" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$4` { + var layers: Array? + get() = definedExternally + set(value) = definedExternally + var filter: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$5` { + var sourceLayer: String? + get() = definedExternally + set(value) = definedExternally + var filter: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$6` { + var diff: Boolean? + get() = definedExternally + set(value) = definedExternally + var localIdeographFontFamily: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$7` { + var width: Number + var height: Number + var data: dynamic /* Uint8Array | Uint8ClampedArray */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$8` { + var pixelRatio: Number? + get() = definedExternally + set(value) = definedExternally + var sdf: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +open external class Map(options: MapboxOptions = definedExternally) : Evented { + open fun addControl( + control: Control, + position: String /* "top-right" | "top-left" | "bottom-right" | "bottom-left" */ = definedExternally, + ): Map /* this */ + + open fun addControl(control: Control): Map /* this */ + open fun addControl( + control: IControl, + position: String /* "top-right" | "top-left" | "bottom-right" | "bottom-left" */ = definedExternally, + ): Map /* this */ + + open fun addControl(control: IControl): Map /* this */ + open fun removeControl(control: Control): Map /* this */ + open fun removeControl(control: IControl): Map /* this */ + open fun hasControl(control: IControl): Boolean + open fun resize(eventData: EventData = definedExternally): Map /* this */ + open fun getBounds(): LngLatBounds + open fun getMaxBounds(): LngLatBounds? + open fun setMaxBounds(lnglatbounds: LngLatBounds = definedExternally): Map /* this */ + open fun setMaxBounds(): Map /* this */ + open fun setMaxBounds(lnglatbounds: Any /* JsTuple | JsTuple | JsTuple */ = definedExternally): Map /* this */ + open fun setMaxBounds(lnglatbounds: LngLat = definedExternally): Map /* this */ + open fun setMaxBounds(lnglatbounds: `T$1` = definedExternally): Map /* this */ + open fun setMaxBounds(lnglatbounds: `T$2` = definedExternally): Map /* this */ + open fun setMinZoom(minZoom: Number? = definedExternally): Map /* this */ + open fun getMinZoom(): Number + open fun setMaxZoom(maxZoom: Number? = definedExternally): Map /* this */ + open fun getMaxZoom(): Number + open fun setMinPitch(minPitch: Number? = definedExternally): Map /* this */ + open fun getMinPitch(): Number + open fun setMaxPitch(maxPitch: Number? = definedExternally): Map /* this */ + open fun getMaxPitch(): Number + open fun getRenderWorldCopies(): Boolean + open fun setRenderWorldCopies(renderWorldCopies: Boolean = definedExternally): Map /* this */ + open fun project(lnglat: Any /* JsTuple */): Point + open fun project(lnglat: LngLat): Point + open fun project(lnglat: `T$1`): Point + open fun project(lnglat: `T$2`): Point + open fun unproject(point: Point): LngLat + open fun unproject(point: Any /* JsTuple */): LngLat + open fun isMoving(): Boolean + open fun isZooming(): Boolean + open fun isRotating(): Boolean + open fun queryRenderedFeatures( + pointOrBox: Point = definedExternally, + options: `T$4` /* `T$4` & FilterOptions */ = definedExternally, + ): Array + + open fun queryRenderedFeatures(): Array + open fun queryRenderedFeatures(pointOrBox: Point = definedExternally): Array + open fun queryRenderedFeatures( + pointOrBox: Any /* JsTuple | JsTuple */ = definedExternally, + options: `T$4` /* `T$4` & FilterOptions */ = definedExternally, + ): Array + + open fun queryRenderedFeatures(pointOrBox: Any /* JsTuple | JsTuple */ = definedExternally): Array + open fun querySourceFeatures( + sourceID: String, + parameters: `T$5` /* `T$5` & FilterOptions */ = definedExternally, + ): Array + + open fun setStyle(style: Style, options: `T$6` = definedExternally): Map /* this */ + open fun setStyle(style: Style): Map /* this */ + open fun setStyle(style: String, options: `T$6` = definedExternally): Map /* this */ + open fun setStyle(style: String): Map /* this */ + open fun getStyle(): Style + open fun setProjection(projection: String): Map + open fun getProjection(): String + open fun isStyleLoaded(): Boolean + open fun addSource(id: String, source: GeoJSONSourceRaw): Map /* this */ + open fun addSource(id: String, source: VideoSourceRaw): Map /* this */ + open fun addSource(id: String, source: ImageSourceRaw): Map /* this */ + open fun addSource(id: String, source: CanvasSourceRaw): Map /* this */ + open fun addSource(id: String, source: VectorSource): Map /* this */ + open fun addSource(id: String, source: RasterSource): Map /* this */ + open fun addSource(id: String, source: RasterDemSource): Map /* this */ + open fun isSourceLoaded(id: String): Boolean + open fun areTilesLoaded(): Boolean + open fun removeSource(id: String): Map /* this */ + open fun getSource(id: String): dynamic /* GeoJSONSource | VideoSource | ImageSource | CanvasSource | VectorSourceImpl | RasterSource | RasterDemSource */ + open fun addImage(name: String, image: HTMLImageElement, options: `T$8` = definedExternally) + open fun addImage(name: String, image: HTMLImageElement) + open fun addImage(name: String, image: ArrayBufferView, options: `T$8` = definedExternally) + open fun addImage(name: String, image: ArrayBufferView) + open fun addImage(name: String, image: `T$7`, options: `T$8` = definedExternally) + open fun addImage(name: String, image: `T$7`) + open fun addImage(name: String, image: ImageData, options: `T$8` = definedExternally) + open fun addImage(name: String, image: ImageData) + open fun addImage(name: String, image: ImageBitmap, options: `T$8` = definedExternally) + open fun addImage(name: String, image: ImageBitmap) + open fun updateImage(name: String, image: HTMLImageElement) + open fun updateImage(name: String, image: ArrayBufferView) + open fun updateImage(name: String, image: `T$7`) + open fun updateImage(name: String, image: ImageData) + open fun updateImage(name: String, image: ImageBitmap) + open fun hasImage(name: String): Boolean + open fun removeImage(name: String) + open fun loadImage( + url: String, + callback: (error: Error, result: Any /* HTMLImageElement | ImageBitmap */) -> Unit, + ) + + open fun listImages(): Array + open fun addLayer(layer: BackgroundLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: BackgroundLayer): Map /* this */ + open fun addLayer(layer: CircleLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: CircleLayer): Map /* this */ + open fun addLayer(layer: FillExtrusionLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: FillExtrusionLayer): Map /* this */ + open fun addLayer(layer: FillLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: FillLayer): Map /* this */ + open fun addLayer(layer: HeatmapLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: HeatmapLayer): Map /* this */ + open fun addLayer(layer: HillshadeLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: HillshadeLayer): Map /* this */ + open fun addLayer(layer: LineLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: LineLayer): Map /* this */ + open fun addLayer(layer: RasterLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: RasterLayer): Map /* this */ + open fun addLayer(layer: SymbolLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: SymbolLayer): Map /* this */ + open fun addLayer( + layer: CustomLayerInterface, + before: String = definedExternally, + ): Map /* this */ + + open fun addLayer(layer: CustomLayerInterface): Map /* this */ + open fun addLayer(layer: SkyLayer, before: String = definedExternally): Map /* this */ + open fun addLayer(layer: SkyLayer): Map /* this */ + open fun moveLayer(id: String, beforeId: String = definedExternally): Map /* this */ + open fun removeLayer(id: String): Map /* this */ + open fun getLayer(id: String): dynamic /* BackgroundLayer | CircleLayer | FillExtrusionLayer | FillLayer | HeatmapLayer | HillshadeLayer | LineLayer | RasterLayer | SymbolLayer | CustomLayerInterface | SkyLayer */ + open fun setFilter( + layer: String, + filter: Array? = definedExternally, + options: FilterOptions? = definedExternally, + ): Map /* this */ + + open fun setFilter(layer: String): Map /* this */ + open fun setFilter(layer: String, filter: Array? = definedExternally): Map /* this */ + open fun setFilter( + layer: String, + filter: Boolean? = definedExternally, + options: FilterOptions? = definedExternally, + ): Map /* this */ + + open fun setFilter(layer: String, filter: Boolean? = definedExternally): Map /* this */ + open fun setLayerZoomRange(layerId: String, minzoom: Number, maxzoom: Number): Map /* this */ + open fun getFilter(layer: String): Array + open fun setPaintProperty( + layer: String, + name: String, + value: dynamic, + klass: String = definedExternally, + ): Map /* this */ + + open fun getPaintProperty(layer: String, name: String): Any + open fun setLayoutProperty(layer: String, name: String, value: dynamic): Map /* this */ + open fun getLayoutProperty(layer: String, name: String): Any + open fun setLight(options: Light, lightOptions: Any = definedExternally): Map /* this */ + open fun getLight(): Light + open fun setTerrain(terrain: TerrainSpecification? = definedExternally): Map /* this */ + open fun getTerrain(): TerrainSpecification? + open var showTerrainWireframe: Boolean + open fun queryTerrainElevation( + lngLat: Any, /* JsTuple */ + options: ElevationQueryOptions = definedExternally, + ): Number? + + open fun queryTerrainElevation(lngLat: Any /* JsTuple */): Number? + open fun queryTerrainElevation( + lngLat: LngLat, + options: ElevationQueryOptions = definedExternally, + ): Number? + + open fun queryTerrainElevation(lngLat: LngLat): Number? + open fun queryTerrainElevation( + lngLat: `T$1`, + options: ElevationQueryOptions = definedExternally, + ): Number? + + open fun queryTerrainElevation(lngLat: `T$1`): Number? + open fun queryTerrainElevation( + lngLat: `T$2`, + options: ElevationQueryOptions = definedExternally, + ): Number? + + open fun queryTerrainElevation(lngLat: `T$2`): Number? + open fun setFeatureState(feature: FeatureIdentifier, state: Json) + open fun setFeatureState(feature: Feature, state: Json) + open fun getFeatureState(feature: FeatureIdentifier): Json + open fun getFeatureState(feature: Feature): Json + open fun removeFeatureState(target: FeatureIdentifier, key: String = definedExternally) + open fun removeFeatureState(target: FeatureIdentifier) + open fun removeFeatureState(target: Feature, key: String = definedExternally) + open fun removeFeatureState(target: Feature) + open fun getContainer(): HTMLElement + open fun getCanvasContainer(): HTMLElement + open fun getCanvas(): HTMLCanvasElement + open fun loaded(): Boolean + open fun remove() + open fun triggerRepaint() + open var showTileBoundaries: Boolean + open var showCollisionBoxes: Boolean + open var showPadding: Boolean + open var repaint: Boolean + open fun getCenter(): LngLat + open fun setCenter( + center: Any, /* JsTuple */ + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun setCenter(center: Any /* JsTuple */): Map /* this */ + open fun setCenter(center: LngLat, eventData: EventData = definedExternally): Map /* this */ + open fun setCenter(center: LngLat): Map /* this */ + open fun setCenter(center: `T$1`, eventData: EventData = definedExternally): Map /* this */ + open fun setCenter(center: `T$1`): Map /* this */ + open fun setCenter(center: `T$2`, eventData: EventData = definedExternally): Map /* this */ + open fun setCenter(center: `T$2`): Map /* this */ + open fun panBy( + offset: Point, + options: AnimationOptions = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun panBy(offset: Point): Map /* this */ + open fun panBy(offset: Point, options: AnimationOptions = definedExternally): Map /* this */ + open fun panBy( + offset: Any, /* JsTuple */ + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun panBy(offset: Any /* JsTuple */): Map /* this */ + open fun panBy( + offset: Any, /* JsTuple */ + options: AnimationOptions? = definedExternally, + ): Map /* this */ + + open fun panTo( + lnglat: Any, /* JsTuple */ + options: AnimationOptions? = definedExternally, + eventdata: EventData = definedExternally, + ): Map /* this */ + + open fun panTo(lnglat: Any /* JsTuple */): Map /* this */ + open fun panTo( + lnglat: Any, /* JsTuple */ + options: AnimationOptions? = definedExternally, + ): Map /* this */ + + open fun panTo( + lnglat: LngLat, + options: AnimationOptions? = definedExternally, + eventdata: EventData = definedExternally, + ): Map /* this */ + + open fun panTo(lnglat: LngLat): Map /* this */ + open fun panTo(lnglat: LngLat, options: AnimationOptions = definedExternally): Map /* this */ + open fun panTo( + lnglat: `T$1`, + options: AnimationOptions = definedExternally, + eventdata: EventData = definedExternally, + ): Map /* this */ + + open fun panTo(lnglat: `T$1`): Map /* this */ + open fun panTo(lnglat: `T$1`, options: AnimationOptions = definedExternally): Map /* this */ + open fun panTo( + lnglat: `T$2`, + options: AnimationOptions = definedExternally, + eventdata: EventData = definedExternally, + ): Map /* this */ + + open fun panTo(lnglat: `T$2`): Map /* this */ + open fun panTo(lnglat: `T$2`, options: AnimationOptions = definedExternally): Map /* this */ + open fun getZoom(): Number + open fun setZoom(zoom: Number, eventData: EventData = definedExternally): Map /* this */ + open fun zoomTo( + zoom: Number, + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun zoomIn( + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun zoomOut( + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun getBearing(): Number + open fun setBearing(bearing: Number, eventData: EventData = definedExternally): Map /* this */ + open fun getPadding(): PaddingOptions + open fun setPadding( + padding: PaddingOptions, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun rotateTo( + bearing: Number, + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun resetNorth( + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun resetNorthPitch( + options: AnimationOptions? = definedExternally, + eventData: EventData? = definedExternally, + ): Map /* this */ + + open fun snapToNorth( + options: AnimationOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun getPitch(): Number + open fun setPitch(pitch: Number, eventData: EventData = definedExternally): Map /* this */ + open fun cameraForBounds( + bounds: LngLatBounds, + options: CameraForBoundsOptions? = definedExternally, + ): Any /* Required> & `T$20` */ + + open fun cameraForBounds(bounds: LngLatBounds): Any /* Required> & `T$20` */ + open fun cameraForBounds( + bounds: Any, /* JsTuple | JsTuple | JsTuple */ + options: CameraForBoundsOptions? = definedExternally, + ): Any /* Required> & `T$20` */ + + open fun cameraForBounds(bounds: Any /* JsTuple | JsTuple | JsTuple */): Any /* Required> & `T$20` */ + open fun cameraForBounds( + bounds: LngLat, + options: CameraForBoundsOptions? = definedExternally, + ): Any /* Required> & `T$20` */ + + open fun cameraForBounds(bounds: LngLat): Any /* Required> & `T$20` */ + open fun cameraForBounds( + bounds: `T$1`, + options: CameraForBoundsOptions? = definedExternally, + ): Any /* Required> & `T$20` */ + + open fun cameraForBounds(bounds: `T$1`): Any /* Required> & `T$20` */ + open fun cameraForBounds( + bounds: `T$2`, + options: CameraForBoundsOptions? = definedExternally, + ): Any /* Required> & `T$20` */ + + open fun cameraForBounds(bounds: `T$2`): Any /* Required> & `T$20` */ + open fun fitBounds( + bounds: LngLatBounds, + options: FitBoundsOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitBounds(bounds: LngLatBounds): Map /* this */ + open fun fitBounds( + bounds: LngLatBounds, + options: FitBoundsOptions? = definedExternally, + ): Map /* this */ + + open fun fitBounds( + bounds: Any, /* JsTuple | JsTuple | JsTuple */ + options: FitBoundsOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitBounds(bounds: Any /* JsTuple | JsTuple | JsTuple */): Map /* this */ + open fun fitBounds( + bounds: Any, /* JsTuple | JsTuple | JsTuple */ + options: FitBoundsOptions? = definedExternally, + ): Map /* this */ + + open fun fitBounds( + bounds: LngLat, + options: FitBoundsOptions = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitBounds(bounds: LngLat): Map /* this */ + open fun fitBounds( + bounds: LngLat, + options: FitBoundsOptions? = definedExternally, + ): Map /* this */ + + open fun fitBounds( + bounds: `T$1`, + options: FitBoundsOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitBounds(bounds: `T$1`): Map /* this */ + open fun fitBounds( + bounds: `T$1`, + options: FitBoundsOptions? = definedExternally, + ): Map /* this */ + + open fun fitBounds( + bounds: `T$2`, + options: FitBoundsOptions? = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitBounds(bounds: `T$2`): Map /* this */ + open fun fitBounds( + bounds: `T$2`, + options: FitBoundsOptions? = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Point, + p1: Point, + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates(p0: Point, p1: Point, bearing: Number): Map /* this */ + open fun fitScreenCoordinates( + p0: Point, + p1: Point, + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Point, + p1: Any, /* JsTuple */ + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Point, + p1: Any, /* JsTuple */ + bearing: Number, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Point, + p1: Any, /* JsTuple */ + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Any, /* JsTuple */ + p1: Point, + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Any, /* JsTuple */ + p1: Point, + bearing: Number, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Any, /* JsTuple */ + p1: Point, + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Any, /* JsTuple */ + p1: Any, /* JsTuple */ + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Any, /* JsTuple */ + p1: Any, /* JsTuple */ + bearing: Number, + ): Map /* this */ + + open fun fitScreenCoordinates( + p0: Any, /* JsTuple */ + p1: Any, /* JsTuple */ + bearing: Number, + options: AnimationOptions /* AnimationOptions & CameraOptions */ = definedExternally, + ): Map /* this */ + + open fun jumpTo( + options: CameraOptions, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun getFreeCameraOptions(): FreeCameraOptions + open fun setFreeCameraOptions( + options: FreeCameraOptions, + eventData: Any = definedExternally, + ): Map /* this */ + + open fun easeTo( + options: EaseToOptions, + eventData: EventData = definedExternally, + ): Map /* this */ + + open fun flyTo(options: FlyToOptions, eventData: EventData = definedExternally): Map /* this */ + open fun isEasing(): Boolean + open fun stop(): Map /* this */ + open fun on(type: T, layer: String, listener: (ev: Any) -> Unit): Map /* this */ + open fun on(type: String, layers: Array, listener: (ev: Any) -> Unit): Map + open fun on(type: T, listener: (ev: Any) -> Unit): Map /* this */ + open fun on(type: String, listener: (ev: Any) -> Unit): Map /* this */ + open fun once(type: T, layer: String, listener: (ev: Any) -> Unit): Map /* this */ + open fun once(type: T, listener: (ev: Any) -> Unit): Map /* this */ + open fun once(type: String, listener: (ev: Any) -> Unit): Map /* this */ + open fun once(type: T): Promise + open fun off(type: T, layer: String, listener: (ev: Any) -> Unit): Map /* this */ + open fun off(type: T, listener: (ev: Any) -> Unit): Map /* this */ + open fun off(type: String, listener: (ev: Any) -> Unit): Map /* this */ + open var scrollZoom: ScrollZoomHandler + open var boxZoom: BoxZoomHandler + open var dragRotate: DragRotateHandler + open var dragPan: DragPanHandler + open var keyboard: KeyboardHandler + open var doubleClickZoom: DoubleClickZoomHandler + open var touchZoomRotate: TouchZoomRotateHandler + open var touchPitch: TouchPitchHandler + open fun getFog(): Fog? + open fun setFog(fog: Fog): Map /* this */ +} + +external interface `T$9` { + @nativeGetter + operator fun get(key: String): String? + + @nativeSetter + operator fun set(key: String, value: String) +} + +external interface MapboxOptions { + var antialias: Boolean? + get() = definedExternally + set(value) = definedExternally + var attributionControl: Boolean? + get() = definedExternally + set(value) = definedExternally + var bearing: Number? + get() = definedExternally + set(value) = definedExternally + var bearingSnap: Number? + get() = definedExternally + set(value) = definedExternally + var bounds: dynamic /* LngLatBounds? | JsTuple | JsTuple | JsTuple | LngLat? | `T$1`? | `T$2`? */ + get() = definedExternally + set(value) = definedExternally + var boxZoom: Boolean? + get() = definedExternally + set(value) = definedExternally + var center: dynamic /* JsTuple | LngLat? | `T$1`? | `T$2`? */ + get() = definedExternally + set(value) = definedExternally + var clickTolerance: Number? + get() = definedExternally + set(value) = definedExternally + var collectResourceTiming: Boolean? + get() = definedExternally + set(value) = definedExternally + var crossSourceCollisions: Boolean? + get() = definedExternally + set(value) = definedExternally + var container: dynamic /* String | HTMLElement */ + get() = definedExternally + set(value) = definedExternally + var cooperativeGestures: Boolean? + get() = definedExternally + set(value) = definedExternally + var customAttribution: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var dragPan: dynamic /* Boolean? | DragPanOptions? */ + get() = definedExternally + set(value) = definedExternally + var dragRotate: Boolean? + get() = definedExternally + set(value) = definedExternally + var doubleClickZoom: Boolean? + get() = definedExternally + set(value) = definedExternally + var hash: dynamic /* Boolean? | String? */ + get() = definedExternally + set(value) = definedExternally + var fadeDuration: Number? + get() = definedExternally + set(value) = definedExternally + var failIfMajorPerformanceCaveat: Boolean? + get() = definedExternally + set(value) = definedExternally + var fitBoundsOptions: FitBoundsOptions? + get() = definedExternally + set(value) = definedExternally + var interactive: Boolean? + get() = definedExternally + set(value) = definedExternally + var keyboard: Boolean? + get() = definedExternally + set(value) = definedExternally + var locale: `T$9`? + get() = definedExternally + set(value) = definedExternally + var localFontFamily: String? + get() = definedExternally + set(value) = definedExternally + var localIdeographFontFamily: String? + get() = definedExternally + set(value) = definedExternally + var logoPosition: String? /* "top-left" | "top-right" | "bottom-left" | "bottom-right" */ + get() = definedExternally + set(value) = definedExternally + var maxBounds: dynamic /* LngLatBounds? | JsTuple | JsTuple | JsTuple | LngLat? | `T$1`? | `T$2`? */ + get() = definedExternally + set(value) = definedExternally + var maxPitch: Number? + get() = definedExternally + set(value) = definedExternally + var maxZoom: Number? + get() = definedExternally + set(value) = definedExternally + var minPitch: Number? + get() = definedExternally + set(value) = definedExternally + var minZoom: Number? + get() = definedExternally + set(value) = definedExternally + var optimizeForTerrain: Boolean? + get() = definedExternally + set(value) = definedExternally + var preserveDrawingBuffer: Boolean? + get() = definedExternally + set(value) = definedExternally + var pitch: Number? + get() = definedExternally + set(value) = definedExternally + var pitchWithRotate: Boolean? + get() = definedExternally + set(value) = definedExternally + var projection: String? + get() = definedExternally + set(value) = definedExternally + var refreshExpiredTiles: Boolean? + get() = definedExternally + set(value) = definedExternally + var renderWorldCopies: Boolean? + get() = definedExternally + set(value) = definedExternally + var scrollZoom: dynamic /* Boolean? | InteractiveOptions? */ + get() = definedExternally + set(value) = definedExternally + var style: dynamic /* mapboxgl.Style? | String? */ + get() = definedExternally + set(value) = definedExternally + var trackResize: Boolean? + get() = definedExternally + set(value) = definedExternally + var transformRequest: TransformRequestFunction? + get() = definedExternally + set(value) = definedExternally + var touchZoomRotate: dynamic /* Boolean? | InteractiveOptions? */ + get() = definedExternally + set(value) = definedExternally + var touchPitch: dynamic /* Boolean? | InteractiveOptions? */ + get() = definedExternally + set(value) = definedExternally + var zoom: Number? + get() = definedExternally + set(value) = definedExternally + var maxTileCacheSize: Number? + get() = definedExternally + set(value) = definedExternally + var accessToken: String? + get() = definedExternally + set(value) = definedExternally + var testMode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +open external class FreeCameraOptions( + position: MercatorCoordinate = definedExternally, + orientation: quat = definedExternally, +) { + open var position: MercatorCoordinate? + open fun lookAtPoint(location: Any /* JsTuple */, up: vec3 = definedExternally) + open fun lookAtPoint(location: Any /* JsTuple */) + open fun lookAtPoint(location: LngLat, up: vec3 = definedExternally) + open fun lookAtPoint(location: LngLat) + open fun lookAtPoint(location: `T$1`, up: vec3 = definedExternally) + open fun lookAtPoint(location: `T$1`) + open fun lookAtPoint(location: `T$2`, up: vec3 = definedExternally) + open fun lookAtPoint(location: `T$2`) + open fun setPitchBearing(pitch: Number, bearing: Number) +} + +external interface RequestParameters { + var url: String + var credentials: String? /* "same-origin" | "include" */ + get() = definedExternally + set(value) = definedExternally + var headers: Json? + get() = definedExternally + set(value) = definedExternally + var method: String? /* "GET" | "POST" | "PUT" */ + get() = definedExternally + set(value) = definedExternally + var collectResourceTiming: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface PaddingOptions { + var top: Number + var bottom: Number + var left: Number + var right: Number +} + +external interface FeatureIdentifier { + var id: dynamic /* String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var source: String + var sourceLayer: String? + get() = definedExternally + set(value) = definedExternally +} + +open external class BoxZoomHandler(map: Map) { + open fun isEnabled(): Boolean + open fun isActive(): Boolean + open fun enable() + open fun disable() +} + +open external class ScrollZoomHandler(map: Map) { + open fun isEnabled(): Boolean + open fun enable(options: InteractiveOptions = definedExternally) + open fun disable() + open fun setZoomRate(zoomRate: Number) + open fun setWheelZoomRate(wheelZoomRate: Number) +} + +open external class DragPanHandler(map: Map) { + open fun isEnabled(): Boolean + open fun isActive(): Boolean + open fun enable(options: DragPanOptions = definedExternally) + open fun disable() +} + +external interface `T$10` { + var bearingSnap: Number? + get() = definedExternally + set(value) = definedExternally + var pitchWithRotate: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +open external class DragRotateHandler(map: Map, options: `T$10` = definedExternally) { + open fun isEnabled(): Boolean + open fun isActive(): Boolean + open fun enable() + open fun disable() +} + +open external class KeyboardHandler(map: Map) { + open fun isEnabled(): Boolean + open fun enable() + open fun disable() + open fun isActive(): Boolean + open fun disableRotation() + open fun enableRotation() +} + +open external class DoubleClickZoomHandler(map: Map) { + open fun isEnabled(): Boolean + open fun enable() + open fun disable() +} + +open external class TouchZoomRotateHandler(map: Map) { + open fun isEnabled(): Boolean + open fun enable(options: InteractiveOptions = definedExternally) + open fun disable() + open fun disableRotation() + open fun enableRotation() +} + +open external class TouchPitchHandler(map: Map) { + open fun enable(options: InteractiveOptions = definedExternally) + open fun isActive(): Boolean + open fun isEnabled(): Boolean + open fun disable() +} + +external interface IControl { + fun onAdd(map: Map): HTMLElement + fun onRemove(map: Map) + var getDefaultPosition: (() -> String)? + get() = definedExternally + set(value) = definedExternally +} + +open external class Control : Evented, IControl { + override fun onAdd(map: Map): HTMLElement + override fun onRemove(map: Map) + override var getDefaultPosition: (() -> String)? +} + +external interface `T$11` { + var showCompass: Boolean? + get() = definedExternally + set(value) = definedExternally + var showZoom: Boolean? + get() = definedExternally + set(value) = definedExternally + var visualizePitch: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +open external class NavigationControl(options: `T$11` = definedExternally) : Control + +open external class PositionOptions { + open var enableHighAccuracy: Boolean? + open var timeout: Number? + open var maximumAge: Number? +} + +external interface `T$12` { + var positionOptions: PositionOptions? + get() = definedExternally + set(value) = definedExternally + var fitBoundsOptions: FitBoundsOptions? + get() = definedExternally + set(value) = definedExternally + var trackUserLocation: Boolean? + get() = definedExternally + set(value) = definedExternally + var showAccuracyCircle: Boolean? + get() = definedExternally + set(value) = definedExternally + var showUserLocation: Boolean? + get() = definedExternally + set(value) = definedExternally + var showUserHeading: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +open external class GeolocateControl(options: `T$12` = definedExternally) : Control { + open fun trigger(): Boolean +} + +external interface `T$13` { + var compact: Boolean? + get() = definedExternally + set(value) = definedExternally + var customAttribution: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally +} + +open external class AttributionControl(options: `T$13` = definedExternally) : Control + +external interface `T$14` { + var maxWidth: Number? + get() = definedExternally + set(value) = definedExternally + var unit: String? + get() = definedExternally + set(value) = definedExternally +} + +open external class ScaleControl(options: `T$14` = definedExternally) : Control { + open fun setUnit(unit: String /* "imperial" | "metric" | "nautical" */) +} + +open external class FullscreenControl(options: FullscreenControlOptions? = definedExternally) : + Control + +external interface FullscreenControlOptions { + var container: HTMLElement? + get() = definedExternally + set(value) = definedExternally +} + +open external class Popup(options: PopupOptions = definedExternally) : Evented { + open fun addTo(map: Map): Popup /* this */ + open fun isOpen(): Boolean + open fun remove(): Popup /* this */ + open fun getLngLat(): LngLat + open fun setLngLat(lnglat: Any /* JsTuple */): Popup /* this */ + open fun setLngLat(lnglat: LngLat): Popup /* this */ + open fun setLngLat(lnglat: `T$1`): Popup /* this */ + open fun setLngLat(lnglat: `T$2`): Popup /* this */ + open fun trackPointer(): Popup /* this */ + open fun getElement(): HTMLElement + open fun setText(text: String): Popup /* this */ + open fun setHTML(html: String): Popup /* this */ + open fun setDOMContent(htmlNode: Node): Popup /* this */ + open fun getMaxWidth(): String + open fun setMaxWidth(maxWidth: String): Popup /* this */ + open fun addClassName(className: String) + open fun removeClassName(className: String) + open fun setOffset(offset: Number? = definedExternally): Popup /* this */ + open fun setOffset(): Popup /* this */ + open fun setOffset(offset: Point? = definedExternally): Popup /* this */ + open fun setOffset(offset: Any /* JsTuple */ = definedExternally): Popup /* this */ + open fun setOffset(offset: `T$3`? = definedExternally): Popup /* this */ + open fun toggleClassName(className: String) +} + +external interface PopupOptions { + var closeButton: Boolean? + get() = definedExternally + set(value) = definedExternally + var closeOnClick: Boolean? + get() = definedExternally + set(value) = definedExternally + var closeOnMove: Boolean? + get() = definedExternally + set(value) = definedExternally + var focusAfterOpen: Boolean? + get() = definedExternally + set(value) = definedExternally + var anchor: String? /* "center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right" */ + get() = definedExternally + set(value) = definedExternally + var offset: dynamic /* Number? | Point? | JsTuple | `T$3`? */ + get() = definedExternally + set(value) = definedExternally + var className: String? + get() = definedExternally + set(value) = definedExternally + var maxWidth: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface Style { + var bearing: Number? + get() = definedExternally + set(value) = definedExternally + var center: Array? + get() = definedExternally + set(value) = definedExternally + var fog: Fog? + get() = definedExternally + set(value) = definedExternally + var glyphs: String? + get() = definedExternally + set(value) = definedExternally + var layers: Array? + get() = definedExternally + set(value) = definedExternally + var metadata: Any? + get() = definedExternally + set(value) = definedExternally + var name: String? + get() = definedExternally + set(value) = definedExternally + var pitch: Number? + get() = definedExternally + set(value) = definedExternally + var light: Light? + get() = definedExternally + set(value) = definedExternally + var sources: Sources? + get() = definedExternally + set(value) = definedExternally + var sprite: String? + get() = definedExternally + set(value) = definedExternally + var terrain: TerrainSpecification? + get() = definedExternally + set(value) = definedExternally + var transition: Transition? + get() = definedExternally + set(value) = definedExternally + var version: Number + var zoom: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Transition { + var delay: Number? + get() = definedExternally + set(value) = definedExternally + var duration: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Light { + @nativeGetter + operator fun get(key: String): Transition? + + @nativeSetter + operator fun set(key: String, value: Transition?) + var anchor: String? /* "map" | "viewport" */ + get() = definedExternally + set(value) = definedExternally + var position: Array? + get() = definedExternally + set(value) = definedExternally + var color: String? + get() = definedExternally + set(value) = definedExternally + var intensity: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Fog { + @nativeGetter + operator fun get(key: String): dynamic? /* Number? | JsTuple */ + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) + var color: dynamic /* String? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var range: dynamic /* Array? | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface Sources { + @nativeGetter + operator fun get(sourceName: String): dynamic /* GeoJSONSourceRaw? | VideoSourceRaw? | ImageSourceRaw? | CanvasSourceRaw? | VectorSource? | RasterSource? | RasterDemSource? */ + + @nativeSetter + operator fun set(sourceName: String, value: GeoJSONSourceRaw) + + @nativeSetter + operator fun set(sourceName: String, value: VideoSourceRaw) + + @nativeSetter + operator fun set(sourceName: String, value: ImageSourceRaw) + + @nativeSetter + operator fun set(sourceName: String, value: CanvasSourceRaw) + + @nativeSetter + operator fun set(sourceName: String, value: VectorSource) + + @nativeSetter + operator fun set(sourceName: String, value: RasterSource) + + @nativeSetter + operator fun set(sourceName: String, value: RasterDemSource) +} + +external interface VectorSourceImpl : VectorSource { + fun setTiles(tiles: Array): VectorSourceImpl + fun setUrl(url: String): VectorSourceImpl +} + +external interface Source { + var type: String /* "vector" | "raster" | "raster-dem" | "geojson" | "image" | "video" | "canvas" */ +} + +external interface GeoJSONSourceRaw : Source, GeoJSONSourceOptions { + override var type: String /* "geojson" */ +} + +open external class GeoJSONSource(options: GeoJSONSourceOptions = definedExternally) : + GeoJSONSourceRaw { + override var type: String /* "geojson" */ + open fun setData(data: Feature): GeoJSONSource /* this */ + open fun setData(data: FeatureCollection): GeoJSONSource /* this */ + open fun setData(data: String): GeoJSONSource /* this */ + open fun getClusterExpansionZoom( + clusterId: Number, + callback: (error: Any, zoom: Number) -> Unit, + ): GeoJSONSource /* this */ + + open fun getClusterChildren( + clusterId: Number, + callback: (error: Any, features: Array) -> Unit, + ): GeoJSONSource /* this */ + + open fun getClusterLeaves( + clusterId: Number, + limit: Number, + offset: Number, + callback: (error: Any, features: Array) -> Unit, + ): GeoJSONSource /* this */ +} + +external interface GeoJSONSourceOptions { + var data: dynamic /* Feature__1? | FeatureCollection__1? | String? */ + get() = definedExternally + set(value) = definedExternally + var maxzoom: Number? + get() = definedExternally + set(value) = definedExternally + var attribution: String? + get() = definedExternally + set(value) = definedExternally + var buffer: Number? + get() = definedExternally + set(value) = definedExternally + var tolerance: Number? + get() = definedExternally + set(value) = definedExternally + var cluster: dynamic /* Number? | Boolean? */ + get() = definedExternally + set(value) = definedExternally + var clusterRadius: Number? + get() = definedExternally + set(value) = definedExternally + var clusterMaxZoom: Number? + get() = definedExternally + set(value) = definedExternally + var clusterMinPoints: Number? + get() = definedExternally + set(value) = definedExternally + var clusterProperties: Any? + get() = definedExternally + set(value) = definedExternally + var lineMetrics: Boolean? + get() = definedExternally + set(value) = definedExternally + var generateId: Boolean? + get() = definedExternally + set(value) = definedExternally + var promoteId: dynamic /* `T$9`? | String? */ + get() = definedExternally + set(value) = definedExternally + var filter: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface VideoSourceRaw : Source, VideoSourceOptions { + override var type: String /* "video" */ +} + +open external class VideoSource(options: VideoSourceOptions = definedExternally) : VideoSourceRaw { + override var type: String /* "video" */ + open fun getVideo(): HTMLVideoElement + open fun setCoordinates(coordinates: Array>): VideoSource /* this */ +} + +external interface VideoSourceOptions { + var urls: Array? + get() = definedExternally + set(value) = definedExternally + var coordinates: Array>? + get() = definedExternally + set(value) = definedExternally +} + +external interface ImageSourceRaw : Source, ImageSourceOptions { + override var type: String /* "image" */ +} + +open external class ImageSource(options: ImageSourceOptions = definedExternally) : ImageSourceRaw { + override var type: String /* "image" */ + open fun updateImage(options: ImageSourceOptions): ImageSource /* this */ + open fun setCoordinates(coordinates: Array>): ImageSource /* this */ +} + +external interface ImageSourceOptions { + var url: String? + get() = definedExternally + set(value) = definedExternally + var coordinates: Array>? + get() = definedExternally + set(value) = definedExternally +} + +external interface CanvasSourceRaw : Source, CanvasSourceOptions { + override var type: String /* "canvas" */ +} + +open external class CanvasSource : CanvasSourceRaw { + override var type: String /* "canvas" */ + override var coordinates: Array> + override var canvas: dynamic /* String | HTMLCanvasElement */ + open fun play() + open fun pause() + open fun getCanvas(): HTMLCanvasElement + open fun setCoordinates(coordinates: Array>): CanvasSource /* this */ +} + +external interface CanvasSourceOptions { + var coordinates: Array> + var animate: Boolean? + get() = definedExternally + set(value) = definedExternally + var canvas: dynamic /* String | HTMLCanvasElement */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$15` { + var type: String /* "exponential" */ + var stops: Array */> +} + +external interface `T$16` { + var type: String /* "interval" */ + var stops: Array */> +} + +external interface TerrainSpecification { + var source: String + var exaggeration: dynamic /* Number? | `T$15`? | `T$16`? | ExpressionSpecification? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface VectorSource : Source { + override var type: String /* "vector" */ + var url: String? + get() = definedExternally + set(value) = definedExternally + var tiles: Array? + get() = definedExternally + set(value) = definedExternally + var bounds: Array? + get() = definedExternally + set(value) = definedExternally + var scheme: String? /* "xyz" | "tms" */ + get() = definedExternally + set(value) = definedExternally + var minzoom: Number? + get() = definedExternally + set(value) = definedExternally + var maxzoom: Number? + get() = definedExternally + set(value) = definedExternally + var attribution: String? + get() = definedExternally + set(value) = definedExternally + var promoteId: dynamic /* `T$9`? | String? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface RasterSource : Source { + override var type: String /* "raster" */ + var url: String? + get() = definedExternally + set(value) = definedExternally + var tiles: Array? + get() = definedExternally + set(value) = definedExternally + var bounds: Array? + get() = definedExternally + set(value) = definedExternally + var minzoom: Number? + get() = definedExternally + set(value) = definedExternally + var maxzoom: Number? + get() = definedExternally + set(value) = definedExternally + var tileSize: Number? + get() = definedExternally + set(value) = definedExternally + var scheme: String? /* "xyz" | "tms" */ + get() = definedExternally + set(value) = definedExternally + var attribution: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface RasterDemSource : Source { + override var type: String /* "raster-dem" */ + var url: String? + get() = definedExternally + set(value) = definedExternally + var tiles: Array? + get() = definedExternally + set(value) = definedExternally + var bounds: Array? + get() = definedExternally + set(value) = definedExternally + var minzoom: Number? + get() = definedExternally + set(value) = definedExternally + var maxzoom: Number? + get() = definedExternally + set(value) = definedExternally + var tileSize: Number? + get() = definedExternally + set(value) = definedExternally + var attribution: String? + get() = definedExternally + set(value) = definedExternally + var encoding: String? /* "terrarium" | "mapbox" */ + get() = definedExternally + set(value) = definedExternally +} + +open external class LngLat(lng: Number, lat: Number) { + open var lng: Number + open var lat: Number + open fun wrap(): LngLat + open fun toArray(): Array + override fun toString(): String + open fun distanceTo(lngLat: LngLat): Number + open fun toBounds(radius: Number): LngLatBounds + + companion object { + fun convert(input: Any /* JsTuple */): LngLat + fun convert(input: LngLat): LngLat + fun convert(input: `T$1`): LngLat + fun convert(input: `T$2`): LngLat + } +} + +open external class LngLatBounds { + open var sw: dynamic /* JsTuple | LngLat | `T$1` | `T$2` */ + open var ne: dynamic /* JsTuple | LngLat | `T$1` | `T$2` */ + + constructor(boundsLike: Any = definedExternally) + constructor() + constructor(sw: Any, ne: Any) + constructor(sw: LngLat, ne: Any) + constructor(sw: `T$1`, ne: Any) + constructor(sw: `T$2`, ne: Any) + + open fun setNorthEast(ne: Any /* JsTuple */): LngLatBounds /* this */ + open fun setNorthEast(ne: LngLat): LngLatBounds /* this */ + open fun setNorthEast(ne: `T$1`): LngLatBounds /* this */ + open fun setNorthEast(ne: `T$2`): LngLatBounds /* this */ + open fun setSouthWest(sw: Any /* JsTuple */): LngLatBounds /* this */ + open fun setSouthWest(sw: LngLat): LngLatBounds /* this */ + open fun setSouthWest(sw: `T$1`): LngLatBounds /* this */ + open fun setSouthWest(sw: `T$2`): LngLatBounds /* this */ + open fun contains(lnglat: Any /* JsTuple */): Boolean + open fun contains(lnglat: LngLat): Boolean + open fun contains(lnglat: `T$1`): Boolean + open fun contains(lnglat: `T$2`): Boolean + open fun extend(obj: Any /* JsTuple | JsTuple | JsTuple */): LngLatBounds /* this */ + open fun extend(obj: LngLat): LngLatBounds /* this */ + open fun extend(obj: `T$1`): LngLatBounds /* this */ + open fun extend(obj: `T$2`): LngLatBounds /* this */ + open fun extend(obj: LngLatBounds): LngLatBounds /* this */ + open fun getCenter(): LngLat + open fun getSouthWest(): LngLat + open fun getNorthEast(): LngLat + open fun getNorthWest(): LngLat + open fun getSouthEast(): LngLat + open fun getWest(): Number + open fun getSouth(): Number + open fun getEast(): Number + open fun getNorth(): Number + open fun toArray(): Array> + override fun toString(): String + open fun isEmpty(): Boolean + + companion object { + fun convert(input: LngLatBounds): LngLatBounds + fun convert(input: Any /* JsTuple */): LngLatBounds + fun convert(input: LngLat): LngLatBounds + fun convert(input: `T$1`): LngLatBounds + fun convert(input: `T$2`): LngLatBounds + } +} + +open external class Point(x: Number, y: Number) { + open var x: Number + open var y: Number + open fun clone(): Point + open fun add(p: Point): Point + open fun sub(p: Point): Point + open fun mult(k: Number): Point + open fun div(k: Number): Point + open fun rotate(a: Number): Point + open fun matMult(m: Number): Point + open fun unit(): Point + open fun perp(): Point + open fun round(): Point + open fun mag(): Number + open fun equals(p: Point): Boolean + open fun dist(p: Point): Number + open fun distSqr(p: Point): Number + open fun angle(): Number + open fun angleTo(p: Point): Number + open fun angleWidth(p: Point): Number + open fun angleWithSep(x: Number, y: Number): Number + + companion object { + fun convert(a: Point): Point + fun convert(a: Any /* JsTuple */): Point + } +} + +open external class MercatorCoordinate(x: Number, y: Number, z: Number = definedExternally) { + open var x: Number + open var y: Number + open var z: Number? + open fun toAltitude(): Number + open fun toLngLat(): LngLat + open fun meterInMercatorCoordinateUnits(): Number + + companion object { + fun fromLngLat( + lngLatLike: Any, /* JsTuple */ + altitude: Number = definedExternally, + ): MercatorCoordinate + + fun fromLngLat(lngLatLike: LngLat, altitude: Number = definedExternally): MercatorCoordinate + fun fromLngLat(lngLatLike: `T$1`, altitude: Number = definedExternally): MercatorCoordinate + fun fromLngLat(lngLatLike: `T$2`, altitude: Number = definedExternally): MercatorCoordinate + } +} + +open external class Marker : Evented { + constructor(options: MarkerOptions = definedExternally) + constructor() + constructor( + element: HTMLElement = definedExternally, + options: MarkerOptions = definedExternally, + ) + + constructor(element: HTMLElement = definedExternally) + + open fun addTo(map: Map): Marker /* this */ + open fun remove(): Marker /* this */ + open fun getLngLat(): LngLat + open fun setLngLat(lngLat: Any /* JsTuple */): Marker /* this */ + open fun setLngLat(lngLat: LngLat): Marker /* this */ + open fun setLngLat(lngLat: `T$1`): Marker /* this */ + open fun setLngLat(lngLat: `T$2`): Marker /* this */ + open fun getElement(): HTMLElement + open fun setPopup(popup: Popup = definedExternally): Marker /* this */ + open fun getPopup(): Popup + open fun togglePopup(): Marker /* this */ + open fun getOffset(): dynamic /* Point | JsTuple */ + open fun setOffset(offset: Point): Marker /* this */ + open fun setOffset(offset: Any /* JsTuple */): Marker /* this */ + open fun setDraggable(shouldBeDraggable: Boolean): Marker /* this */ + open fun isDraggable(): Boolean + open fun getRotation(): Number + open fun setRotation(rotation: Number): Marker /* this */ + open fun getRotationAlignment(): String /* "map" | "viewport" | "auto" */ + open fun setRotationAlignment(alignment: String /* "map" | "viewport" | "auto" */): Marker /* this */ + open fun getPitchAlignment(): String /* "map" | "viewport" | "auto" */ + open fun setPitchAlignment(alignment: String /* "map" | "viewport" | "auto" */): Marker /* this */ +} + +external interface MarkerOptions { + var element: HTMLElement? + get() = definedExternally + set(value) = definedExternally + var offset: dynamic /* Point? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var anchor: String? /* "center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right" */ + get() = definedExternally + set(value) = definedExternally + var color: String? + get() = definedExternally + set(value) = definedExternally + var draggable: Boolean? + get() = definedExternally + set(value) = definedExternally + var clickTolerance: Number? + get() = definedExternally + set(value) = definedExternally + var rotation: Number? + get() = definedExternally + set(value) = definedExternally + var rotationAlignment: String? /* "map" | "viewport" | "auto" */ + get() = definedExternally + set(value) = definedExternally + var pitchAlignment: String? /* "map" | "viewport" | "auto" */ + get() = definedExternally + set(value) = definedExternally + var scale: Number? + get() = definedExternally + set(value) = definedExternally +} + +open external class Evented { + open fun on(type: String, listener: EventedListener): Evented /* this */ + open fun off( + type: String = definedExternally, + listener: EventedListener = definedExternally, + ): Evented /* this */ + + open fun off(): Evented /* this */ + open fun off(type: String = definedExternally): Evented /* this */ + open fun off( + type: Any = definedExternally, + listener: EventedListener = definedExternally, + ): Evented /* this */ + + open fun off(type: Any = definedExternally): Evented /* this */ + open fun once(type: String, listener: EventedListener): Evented /* this */ + open fun fire(type: String, properties: Json = definedExternally): Evented /* this */ +} + +external interface StyleOptions { + var transition: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$17` { + var layer: Layer + var source: String + var sourceLayer: String + var state: Json +} + +external interface EventData { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: Any) +} + +open external class MapboxEvent { + open var type: String + open var target: Map + open var originalEvent: TOrig +} + +open external class MapboxEvent__0 : MapboxEvent + +open external class MapMouseEvent : MapboxEvent { + override var type: String /* "mousedown" | "mouseup" | "click" | "dblclick" | "mousemove" | "mouseover" | "mouseenter" | "mouseleave" | "mouseout" | "contextmenu" */ + open var point: Point + open var lngLat: LngLat + open fun preventDefault() + open var defaultPrevented: Boolean +} + +external interface `T$18` { + var features: Array? + get() = definedExternally + set(value) = definedExternally +} + +open external class MapTouchEvent : MapboxEvent { + override var type: String /* "touchstart" | "touchend" | "touchcancel" */ + open var point: Point + open var lngLat: LngLat + open var points: Array + open var lngLats: Array + open fun preventDefault() + open var defaultPrevented: Boolean +} + +external interface `T$19` { + var features: Array? + get() = definedExternally + set(value) = definedExternally +} + +open external class MapWheelEvent : MapboxEvent { + override var type: String /* "wheel" */ + open fun preventDefault() + open var defaultPrevented: Boolean +} + +external interface MapBoxZoomEvent : MapboxEvent { + override var type: String /* "boxzoomstart" | "boxzoomend" | "boxzoomcancel" */ + var boxZoomBounds: LngLatBounds +} + +external interface MapStyleDataEvent : MapboxEvent__0 { + var dataType: String /* "style" */ +} + +external interface MapSourceDataEvent : MapboxEvent__0 { + var dataType: String /* "source" */ + var isSourceLoaded: Boolean + var source: Source + var sourceId: String + var sourceDataType: String /* "metadata" | "content" */ + var tile: Any + var coord: Coordinate +} + +external interface Coordinate { + var canonical: CanonicalCoordinate + var wrap: Number + var key: Number +} + +external interface CanonicalCoordinate { + var x: Number + var y: Number + var z: Number + var key: Number + fun equals(coord: CanonicalCoordinate): Boolean +} + +external interface MapContextEvent : MapboxEvent { + override var type: String /* "webglcontextlost" | "webglcontextrestored" */ +} + +open external class ErrorEvent : MapboxEvent__0 { + override var type: String /* "error" */ + open var error: Error +} + +external interface FilterOptions { + var validate: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface AnimationOptions { + var duration: Number? + get() = definedExternally + set(value) = definedExternally + var easing: ((time: Number) -> Number)? + get() = definedExternally + set(value) = definedExternally + var offset: dynamic /* Point? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var animate: Boolean? + get() = definedExternally + set(value) = definedExternally + var essential: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CameraOptions { + var center: dynamic /* JsTuple | LngLat? | `T$1`? | `T$2`? */ + get() = definedExternally + set(value) = definedExternally + var zoom: Number? + get() = definedExternally + set(value) = definedExternally + var bearing: Number? + get() = definedExternally + set(value) = definedExternally + var pitch: Number? + get() = definedExternally + set(value) = definedExternally + var around: dynamic /* JsTuple | LngLat? | `T$1`? | `T$2`? */ + get() = definedExternally + set(value) = definedExternally + var padding: dynamic /* Number? | PaddingOptions? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface CameraForBoundsOptions : CameraOptions { + var offset: dynamic /* Point? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var maxZoom: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$20` { + var center: `T$1` +} + +external interface FlyToOptions : AnimationOptions, CameraOptions { + var curve: Number? + get() = definedExternally + set(value) = definedExternally + var minZoom: Number? + get() = definedExternally + set(value) = definedExternally + var speed: Number? + get() = definedExternally + set(value) = definedExternally + var screenSpeed: Number? + get() = definedExternally + set(value) = definedExternally + var maxDuration: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface EaseToOptions : AnimationOptions, CameraOptions { + var delayEndEvents: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface FitBoundsOptions : FlyToOptions { + var linear: Boolean? + get() = definedExternally + set(value) = definedExternally + override var offset: dynamic /* Point? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var maxZoom: Number? + get() = definedExternally + set(value) = definedExternally + override var maxDuration: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface MapEventType { + var error: ErrorEvent + var load: MapboxEvent__0 + var idle: MapboxEvent__0 + var remove: MapboxEvent__0 + var render: MapboxEvent__0 + var resize: MapboxEvent__0 + var webglcontextlost: MapContextEvent + var webglcontextrestored: MapContextEvent + var dataloading: dynamic /* MapSourceDataEvent | MapStyleDataEvent */ + get() = definedExternally + set(value) = definedExternally + var data: dynamic /* MapSourceDataEvent | MapStyleDataEvent */ + get() = definedExternally + set(value) = definedExternally + var tiledataloading: dynamic /* MapSourceDataEvent | MapStyleDataEvent */ + get() = definedExternally + set(value) = definedExternally + var sourcedataloading: MapSourceDataEvent + var styledataloading: MapStyleDataEvent + var sourcedata: MapSourceDataEvent + var styledata: MapStyleDataEvent + var boxzoomcancel: MapBoxZoomEvent + var boxzoomstart: MapBoxZoomEvent + var boxzoomend: MapBoxZoomEvent + var touchcancel: MapTouchEvent + var touchmove: MapTouchEvent + var touchend: MapTouchEvent + var touchstart: MapTouchEvent + var click: MapMouseEvent + var contextmenu: MapMouseEvent + var dblclick: MapMouseEvent + var mousemove: MapMouseEvent + var mouseup: MapMouseEvent + var mousedown: MapMouseEvent + var mouseout: MapMouseEvent + var mouseover: MapMouseEvent + var movestart: MapboxEvent + var move: MapboxEvent + var moveend: MapboxEvent + var zoomstart: MapboxEvent + var zoom: MapboxEvent + var zoomend: MapboxEvent + var rotatestart: MapboxEvent + var rotate: MapboxEvent + var rotateend: MapboxEvent + var dragstart: MapboxEvent + var drag: MapboxEvent + var dragend: MapboxEvent + var pitchstart: MapboxEvent + var pitch: MapboxEvent + var pitchend: MapboxEvent + var wheel: MapWheelEvent +} + +external interface MapLayerEventType { + var click: MapMouseEvent /* MapMouseEvent & `T$18` */ + var dblclick: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mousedown: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mouseup: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mousemove: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mouseenter: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mouseleave: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mouseover: MapMouseEvent /* MapMouseEvent & `T$18` */ + var mouseout: MapMouseEvent /* MapMouseEvent & `T$18` */ + var contextmenu: MapMouseEvent /* MapMouseEvent & `T$18` */ + var touchstart: MapTouchEvent /* MapTouchEvent & `T$19` */ + var touchend: MapTouchEvent /* MapTouchEvent & `T$19` */ + var touchcancel: MapTouchEvent /* MapTouchEvent & `T$19` */ +} + +external interface Layer { + @nativeGetter + operator fun get(key: String): String? + + @nativeSetter + operator fun set(key: String, value: String?) + var id: String + var type: String + var metadata: Any? + get() = definedExternally + set(value) = definedExternally + var ref: String? + get() = definedExternally + set(value) = definedExternally + var source: dynamic /* String? | GeoJSONSourceRaw? | VideoSourceRaw? | ImageSourceRaw? | CanvasSourceRaw? | VectorSource? | RasterSource? | RasterDemSource? */ + get() = definedExternally + set(value) = definedExternally + var minzoom: Number? + get() = definedExternally + set(value) = definedExternally + var maxzoom: Number? + get() = definedExternally + set(value) = definedExternally + var interactive: Boolean? + get() = definedExternally + set(value) = definedExternally + var filter: Array? + get() = definedExternally + set(value) = definedExternally + var layout: dynamic /* BackgroundLayout? | FillLayout? | FillExtrusionLayout? | LineLayout? | SymbolLayout? | RasterLayout? | CircleLayout? | HeatmapLayout? | HillshadeLayout? | SkyLayout? */ + get() = definedExternally + set(value) = definedExternally + var paint: dynamic /* BackgroundPaint? | FillPaint? | FillExtrusionPaint? | LinePaint? | SymbolPaint? | RasterPaint? | CirclePaint? | HeatmapPaint? | HillshadePaint? | SkyPaint? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BackgroundLayer : Layer { + override var type: String /* "background" */ + override var layout: BackgroundLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: BackgroundPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface CircleLayer : Layer { + override var type: String /* "circle" */ + override var layout: CircleLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: CirclePaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface FillExtrusionLayer : Layer { + override var type: String /* "fill-extrusion" */ + override var layout: FillExtrusionLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: FillExtrusionPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface FillLayer : Layer { + override var type: String /* "fill" */ + override var layout: FillLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: FillPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface HeatmapLayer : Layer { + override var type: String /* "heatmap" */ + override var layout: HeatmapLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: HeatmapPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface HillshadeLayer : Layer { + override var type: String /* "hillshade" */ + override var layout: HillshadeLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: HillshadePaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface LineLayer : Layer { + override var type: String /* "line" */ + override var layout: LineLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: LinePaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface RasterLayer : Layer { + override var type: String /* "raster" */ + override var layout: RasterLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: RasterPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface SymbolLayer : Layer { + override var type: String /* "symbol" */ + override var layout: SymbolLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: SymbolPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface SkyLayer : Layer { + override var type: String /* "sky" */ + override var layout: SkyLayout? + get() = definedExternally + set(value) = definedExternally + override var paint: SkyPaint? + get() = definedExternally + set(value) = definedExternally +} + +external interface CustomLayerInterface { + var id: String + var type: String /* "custom" */ + var renderingMode: String? /* "2d" | "3d" */ + get() = definedExternally + set(value) = definedExternally + val onRemove: ((map: Map, gl: WebGLRenderingContext) -> Unit)? + val onAdd: ((map: Map, gl: WebGLRenderingContext) -> Unit)? + val prerender: ((gl: WebGLRenderingContext, matrix: Array) -> Unit)? + fun render(gl: WebGLRenderingContext, matrix: Array) +} + +external interface StyleFunction { + var stops: Array>? + get() = definedExternally + set(value) = definedExternally + var property: String? + get() = definedExternally + set(value) = definedExternally + var base: Number? + get() = definedExternally + set(value) = definedExternally + var type: String? /* "identity" | "exponential" | "interval" | "categorical" */ + get() = definedExternally + set(value) = definedExternally + var default: Any? + get() = definedExternally + set(value) = definedExternally + var colorSpace: String? /* "rgb" | "lab" | "hcl" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface Layout { + var visibility: String? /* "visible" | "none" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BackgroundLayout : Layout + +external interface BackgroundPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: dynamic /* String? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: String?) +} + +external interface FillLayout : Layout { + @nativeGetter + operator fun get(key: String): dynamic? /* Number? | JsTuple */ + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) +} + +external interface FillPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: dynamic /* Boolean? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: Array?) + + @nativeSetter + operator fun set(key: String, value: String? /* "map" | "viewport" */) +} + +external interface FillExtrusionLayout : Layout + +external interface FillExtrusionPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: String? /* "map" | "viewport" */) + + @nativeSetter + operator fun set(key: String, value: Boolean?) +} + +external interface LineLayout : Layout { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set( + key: String, + value: dynamic, /* "butt" | "round" | "square" | JsTuple */ + ) +} + +external interface LinePaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set( + key: String, + value: dynamic, /* Number? | StyleFunction? | JsTuple */ + ) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: String? /* "map" | "viewport" */) +} + +external interface SymbolLayout : Layout { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: String? /* "point" | "line" | "line-center" */) + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: Boolean?) + + @nativeSetter + operator fun set( + key: String, + value: Array?, + ) +} + +external interface SymbolPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set( + key: String, + value: dynamic, /* Number? | StyleFunction? | JsTuple */ + ) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: String? /* "map" | "viewport" */) +} + +external interface RasterLayout : Layout + +external interface RasterPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: String? /* "linear" | "nearest" */) +} + +external interface CircleLayout : Layout { + @nativeGetter + operator fun get(key: String): dynamic? /* Number? | JsTuple */ + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) +} + +external interface CirclePaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set( + key: String, + value: dynamic, /* Number? | StyleFunction? | JsTuple */ + ) + + @nativeSetter + operator fun set(key: String, value: Transition?) + + @nativeSetter + operator fun set(key: String, value: String? /* "map" | "viewport" */) +} + +external interface HeatmapLayout : Layout + +external interface HeatmapPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set( + key: String, + value: dynamic, /* Number? | StyleFunction? | JsTuple */ + ) + + @nativeSetter + operator fun set(key: String, value: Transition?) +} + +external interface HillshadeLayout : Layout + +external interface HillshadePaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: dynamic /* Number? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: String? /* "map" | "viewport" */) + + @nativeSetter + operator fun set(key: String, value: Transition?) +} + +external interface SkyLayout : Layout + +external interface SkyPaint { + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: dynamic /* String? | JsTuple */) + + @nativeSetter + operator fun set(key: String, value: String? /* "gradient" | "atmosphere" */) +} + +external interface ElevationQueryOptions { + var exaggerated: Boolean +} diff --git a/compose-mapbox-library/src/jvmMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.jvm.kt b/compose-mapbox-library/src/jvmMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.jvm.kt new file mode 100644 index 0000000..8ffba04 --- /dev/null +++ b/compose-mapbox-library/src/jvmMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.jvm.kt @@ -0,0 +1,15 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.architecture.mapbox.compose.library.state.MapboxState + +@Composable +actual fun MapBoxMap( + modifier: Modifier, + accessToken: String, + state: MapboxState, + style: String, + content: @MapboxMapComposableMarker @Composable (MapboxMapScope.() -> Unit)?, +) { +} \ No newline at end of file diff --git a/compose-mapbox-library/src/wasmJsMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.wasmJs.kt b/compose-mapbox-library/src/wasmJsMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.wasmJs.kt new file mode 100644 index 0000000..8ffba04 --- /dev/null +++ b/compose-mapbox-library/src/wasmJsMain/kotlin/io/architecture/mapbox/compose/library/MapBoxMap.wasmJs.kt @@ -0,0 +1,15 @@ +package io.architecture.mapbox.compose.library + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.architecture.mapbox.compose.library.state.MapboxState + +@Composable +actual fun MapBoxMap( + modifier: Modifier, + accessToken: String, + state: MapboxState, + style: String, + content: @MapboxMapComposableMarker @Composable (MapboxMapScope.() -> Unit)?, +) { +} \ No newline at end of file diff --git a/compose-web-js-wasm-app/build.gradle.kts b/compose-web-js-wasm-app/build.gradle.kts new file mode 100644 index 0000000..2a92641 --- /dev/null +++ b/compose-web-js-wasm-app/build.gradle.kts @@ -0,0 +1,116 @@ +import com.codingfeline.buildkonfig.compiler.FieldSpec +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import java.util.Properties + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") + classpath("com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:${libs.versions.buildKonfig.get()}") + } +} + +//var version = "0.0.0-SNAPSHOT" +//if (project.hasProperty("skiko.version")) { +// version = project.properties["skiko.version"] as String +//} +val resourcesDir = "${layout.buildDirectory}buildDir/resources/" + +val skikoWasm by configurations.creating + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.buildKonfig) + alias(libs.plugins.jetbrainsCompose) +} + +dependencies { + skikoWasm(libs.skiko.js.wasm.runtime) +} + +val unzipTask = tasks.register("unzipWasm", Copy::class) { + destinationDir = file(resourcesDir) + from(skikoWasm.map { zipTree(it) }) +} + +tasks.withType().configureEach { + dependsOn(unzipTask) +} + +kotlin { + js(IR) { + browser { + commonWebpackConfig { + cssSupport { + enabled.set(true) + } + } + } + binaries.executable() + } + + sourceSets { + val commonMain by getting { + dependencies { + implementation(projects.core.designsystem) + + implementation(compose.runtime) + implementation(compose.ui) + implementation(compose.foundation) + implementation(compose.html.core) + implementation(compose.material) + + implementation(libs.skiko) + } + } + val jsWasmMain by creating { + dependsOn(commonMain) + resources.setSrcDirs(resources.srcDirs) + resources.srcDirs(unzipTask.map { it.destinationDir }) + } + jsMain.dependencies { + implementation(projects.core.di) + implementation(projects.core.datasource.api) + implementation(projects.feature.map) + + // from Composite Gradle Build. See root setting.gradle.kts + //noinspection UseTomlInstead + implementation("ca.derekellis.mapbox:compose-mapbox-library") + + implementation(libs.koin.core) + implementation(libs.koin.mp.compose) + + } + } +} + +compose.experimental { + web.application {} +} + +rootProject.plugins.withType { + rootProject.the().nodeVersion = "16.0.0" +} + +val fileMapBoxProperties = "mapbox.properties" +val mapBoxPropertyKey = "MAPBOX_ACCESS_TOKEN" + +buildkonfig { + packageName = "io.architecture.compose.web.application" + defaultConfigs { + val file = rootProject.file(fileMapBoxProperties) + val properties = Properties().apply { + if (file.exists()) { + load(file.reader()) + } + } + + val accessToken: String? = + System.getenv()[mapBoxPropertyKey] ?: properties[mapBoxPropertyKey]?.toString() + checkNotNull(accessToken) { "'$mapBoxPropertyKey' not defined in $fileMapBoxProperties" } + buildConfigField(FieldSpec.Type.STRING, mapBoxPropertyKey, accessToken) + } +} \ No newline at end of file diff --git a/compose-web-js-wasm-app/src/jsMain/kotlin/io/architecture/compose/web/app/Application.kt b/compose-web-js-wasm-app/src/jsMain/kotlin/io/architecture/compose/web/app/Application.kt new file mode 100644 index 0000000..8d2e95c --- /dev/null +++ b/compose-web-js-wasm-app/src/jsMain/kotlin/io/architecture/compose/web/app/Application.kt @@ -0,0 +1,56 @@ +package io.architecture.compose.web.app + +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.CanvasBasedWindow +import ca.derekellis.mapbox.MapboxMapInternal +import ca.derekellis.mapbox.rememberMapboxStateInternal +import io.architecture.compose.web.application.BuildKonfig +import io.architecture.core.design.system.theme.UAVTheme +import io.architecture.core.di.coreKoinModules +import io.architecture.datasource.api.di.inMemoryLocalDatasourceModule +import io.architecture.feature.common.map.MapScreen +import io.architecture.feature.common.map.di.mapFeatureModule +import org.jetbrains.compose.web.css.Style +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.renderComposable +import org.jetbrains.skiko.wasm.onWasmReady +import org.koin.compose.KoinApplication + +external fun require(module: String): dynamic + +@OptIn(ExperimentalComposeUiApi::class) +fun main() { + require("mapbox-gl/dist/mapbox-gl.css") + + onWasmReady { + CanvasBasedWindow( + title = "Node trace tracking", + canvasElementId = "composeTarget", + applyDefaultStyles = false + ) { + KoinApplication(application = { + modules(coreKoinModules, mapFeatureModule, inMemoryLocalDatasourceModule) + }) { + UAVTheme { + MapScreen() + } + } + } + } + + renderComposable(rootElementId = "root") { + Style(MainStyleSheet) + Div(attrs = { classes(MainStyleSheet.overlay) }) { + Div { + val mapState = rememberMapboxStateInternal() + MapboxMapInternal( + accessToken = BuildKonfig.MAPBOX_ACCESS_TOKEN, + style = "mapbox://styles/mapbox/dark-v10", + state = mapState, + ) { + // TODO GeoJson source... + } + } + } + } +} \ No newline at end of file diff --git a/compose-web-js-wasm-app/src/jsMain/kotlin/io/architecture/compose/web/app/MainStyles.kt b/compose-web-js-wasm-app/src/jsMain/kotlin/io/architecture/compose/web/app/MainStyles.kt new file mode 100644 index 0000000..e98c587 --- /dev/null +++ b/compose-web-js-wasm-app/src/jsMain/kotlin/io/architecture/compose/web/app/MainStyles.kt @@ -0,0 +1,45 @@ +package io.architecture.compose.web.app + +import org.jetbrains.compose.web.css.CSSColorValue +import org.jetbrains.compose.web.css.Position +import org.jetbrains.compose.web.css.StyleSheet +import org.jetbrains.compose.web.css.backgroundColor +import org.jetbrains.compose.web.css.color +import org.jetbrains.compose.web.css.fontFamily +import org.jetbrains.compose.web.css.height +import org.jetbrains.compose.web.css.left +import org.jetbrains.compose.web.css.margin +import org.jetbrains.compose.web.css.percent +import org.jetbrains.compose.web.css.position +import org.jetbrains.compose.web.css.px +import org.jetbrains.compose.web.css.top +import org.jetbrains.compose.web.css.value +import org.jetbrains.compose.web.css.variable +import org.jetbrains.compose.web.css.width + +object MainStyle { + val textPrimary by variable() + val backgroundPrimary by variable() +} + +object MainStyleSheet : StyleSheet() { + init { + "html, body, #root" style { + width(100.percent) + height(100.percent) + margin(0.px) + fontFamily("sans-serif") + } + + "body" { + backgroundColor(MainStyle.backgroundPrimary.value()) + } + } + + val overlay by style { + position(Position.Fixed) + top(0.px) + left(0.px) + color(MainStyle.textPrimary.value()) + } +} \ No newline at end of file diff --git a/compose-web-js-wasm-app/src/jsMain/resources/index.html b/compose-web-js-wasm-app/src/jsMain/resources/index.html new file mode 100644 index 0000000..9b62de2 --- /dev/null +++ b/compose-web-js-wasm-app/src/jsMain/resources/index.html @@ -0,0 +1,19 @@ + + + + Node tracing playground + + + + + + + +
+ +
+
+ + + + \ No newline at end of file diff --git a/compose-web-wasm-app/build.gradle.kts b/compose-web-wasm-app/build.gradle.kts new file mode 100644 index 0000000..ad955a9 --- /dev/null +++ b/compose-web-wasm-app/build.gradle.kts @@ -0,0 +1,56 @@ +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.jetbrainsCompose) +} + +kotlin { + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + moduleName = "compose-web-app" + binaries.executable() + browser { + commonWebpackConfig { + outputFileName = "composeApp.js" + devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply { + // Uncomment and configure this if you want to open a browser different from the system default + // open = mapOf( + // "app" to mapOf( + // "name" to "google chrome" + // ) + // ) + } + } + } + + // Uncomment the next line to apply Binaryen and get optimized wasm binaries + // applyBinaryen() + } + + sourceSets { + val wasmJsTest by getting + val wasmJsMain by getting { + dependencies { + implementation(projects.core.di) + implementation(projects.core.datasource.api) + implementation(projects.core.designsystem) + implementation(projects.feature.map) + + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.ui) + implementation(compose.components.resources) + + // Koin + implementation(libs.koin.mp.compose) + } + } + } +} + +compose.experimental { + web.application {} +} \ No newline at end of file diff --git a/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/uav_osd_mono.ttf b/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/uav_osd_mono.ttf new file mode 100644 index 0000000..eff34e3 Binary files /dev/null and b/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/uav_osd_mono.ttf differ diff --git a/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/uav_osd_sans_mono.ttf b/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/uav_osd_sans_mono.ttf new file mode 100644 index 0000000..61b7a16 Binary files /dev/null and b/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/uav_osd_sans_mono.ttf differ diff --git a/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/vcr_osd_mono.ttf b/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/vcr_osd_mono.ttf new file mode 100644 index 0000000..9322814 Binary files /dev/null and b/compose-web-wasm-app/src/wasmJsMain/composeResources/fonts/vcr_osd_mono.ttf differ diff --git a/compose-web-wasm-app/src/wasmJsMain/kotlin/Application.kt b/compose-web-wasm-app/src/wasmJsMain/kotlin/Application.kt new file mode 100644 index 0000000..7b3099c --- /dev/null +++ b/compose-web-wasm-app/src/wasmJsMain/kotlin/Application.kt @@ -0,0 +1,21 @@ +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.CanvasBasedWindow +import io.architecture.core.design.system.theme.UAVTheme +import io.architecture.core.di.coreKoinModules +import io.architecture.datasource.api.di.inMemoryLocalDatasourceModule +import io.architecture.feature.common.map.MapScreen +import io.architecture.feature.common.map.di.mapFeatureModule +import org.koin.compose.KoinApplication + +@OptIn(ExperimentalComposeUiApi::class) +fun main() { + CanvasBasedWindow(canvasElementId = "ComposeTarget") { + KoinApplication(application = { + modules(coreKoinModules, mapFeatureModule, inMemoryLocalDatasourceModule) + }) { + UAVTheme { + MapScreen() + } + } + } +} \ No newline at end of file diff --git a/compose-web-wasm-app/src/wasmJsMain/resources/index.html b/compose-web-wasm-app/src/wasmJsMain/resources/index.html new file mode 100644 index 0000000..9ba000f --- /dev/null +++ b/compose-web-wasm-app/src/wasmJsMain/resources/index.html @@ -0,0 +1,12 @@ + + + + + Compose App + + + + + + + \ No newline at end of file diff --git a/core/common/.gitignore b/core/common/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/common/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 608637c..2291718 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -1,11 +1,15 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { - implementation(projects.core.runtime.logging) - - implementation(libs.kotlinx.coroutine.android) - testImplementation(libs.junit.junit) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(libs.koin.core) + implementation(libs.kotlinx.coroutine.core) + implementation(projects.core.runtime.logging) + } + } } \ No newline at end of file diff --git a/core/common/src/commonMain/kotlin/io/architecture/common/Logger.kt b/core/common/src/commonMain/kotlin/io/architecture/common/Logger.kt new file mode 100644 index 0000000..da248e2 --- /dev/null +++ b/core/common/src/commonMain/kotlin/io/architecture/common/Logger.kt @@ -0,0 +1,8 @@ +package io.architecture.common + +import io.architecture.runtime.logging.Logger + + +// todo +// internal fun logCoroutineInfo(tag: String, msg: String) = +// Logger.debug(tag, "Running on: [${Thread.currentThread().name}] | $msg") diff --git a/core/common/src/main/java/io/architecture/common/Result.kt b/core/common/src/commonMain/kotlin/io/architecture/common/Result.kt similarity index 100% rename from core/common/src/main/java/io/architecture/common/Result.kt rename to core/common/src/commonMain/kotlin/io/architecture/common/Result.kt diff --git a/core/common/src/main/java/io/architecture/common/ext/FlowChunkedExt.kt b/core/common/src/commonMain/kotlin/io/architecture/common/ext/FlowChunkedExt.kt similarity index 100% rename from core/common/src/main/java/io/architecture/common/ext/FlowChunkedExt.kt rename to core/common/src/commonMain/kotlin/io/architecture/common/ext/FlowChunkedExt.kt diff --git a/core/common/src/main/java/io/architecture/common/Logger.kt b/core/common/src/main/java/io/architecture/common/Logger.kt deleted file mode 100644 index 883f356..0000000 --- a/core/common/src/main/java/io/architecture/common/Logger.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.architecture.common - -import io.architecture.runtime.logging.Logger - - -internal fun logCoroutineInfo(tag: String, msg: String) = - Logger.debug(tag, "Running on: [${Thread.currentThread().name}] | $msg") diff --git a/core/data/.gitignore b/core/data/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/data/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts index 97f28d2..f010061 100644 --- a/core/data/build.gradle.kts +++ b/core/data/build.gradle.kts @@ -1,27 +1,24 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) - alias(libs.plugins.ksp) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -sourceSets.main { - java.srcDirs("build/generated/ksp/main/kotlin") -} - - -dependencies { - implementation(projects.core.common) - implementation(projects.core.database.api) - implementation(projects.core.datasource.api) - implementation(projects.core.model) - implementation(projects.core.network.websocket.api) - implementation(projects.core.runtime.logging) - - implementation(libs.kotlinx.coroutine.core) - - // Koin - implementation(libs.koin.core) - ksp(libs.koin.ksp.compiler) +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(projects.core.common) + implementation(projects.core.database.api) + implementation(projects.core.datasource.api) + implementation(projects.core.model) + implementation(projects.core.network.websocket.api) + implementation(projects.core.runtime.logging) - testImplementation(libs.junit.junit) + implementation(libs.koin.core) + implementation(libs.kotlinx.coroutine.core) + implementation(libs.kotlinx.datetime) + } + } + } } \ No newline at end of file diff --git a/core/data/src/main/java/io/architecture/data/DefaultNodeRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/DefaultNodeRepository.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/DefaultNodeRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/DefaultNodeRepository.kt diff --git a/core/data/src/main/java/io/architecture/data/RepositoryKoinModule.kt b/core/data/src/commonMain/kotlin/io/architecture/data/RepositoryKoinModule.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/RepositoryKoinModule.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/RepositoryKoinModule.kt diff --git a/core/data/src/main/java/io/architecture/data/mapping/RouteMappingExt.kt b/core/data/src/commonMain/kotlin/io/architecture/data/mapping/RouteMappingExt.kt similarity index 96% rename from core/data/src/main/java/io/architecture/data/mapping/RouteMappingExt.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/mapping/RouteMappingExt.kt index 5ec1e94..643d4c5 100644 --- a/core/data/src/main/java/io/architecture/data/mapping/RouteMappingExt.kt +++ b/core/data/src/commonMain/kotlin/io/architecture/data/mapping/RouteMappingExt.kt @@ -5,6 +5,7 @@ import io.architecture.database.api.model.RouteEntity import io.architecture.database.api.model.toExternal import io.architecture.model.Route import io.architecture.network.websocket.api.model.NetworkRoute +import kotlin.jvm.JvmName internal fun NetworkRoute.toLocal() = RouteEntity( diff --git a/core/data/src/main/java/io/architecture/data/mapping/TraceMappingExt.kt b/core/data/src/commonMain/kotlin/io/architecture/data/mapping/TraceMappingExt.kt similarity index 78% rename from core/data/src/main/java/io/architecture/data/mapping/TraceMappingExt.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/mapping/TraceMappingExt.kt index 27f0575..476f189 100644 --- a/core/data/src/main/java/io/architecture/data/mapping/TraceMappingExt.kt +++ b/core/data/src/commonMain/kotlin/io/architecture/data/mapping/TraceMappingExt.kt @@ -4,7 +4,9 @@ import io.architecture.database.api.model.TraceEntity import io.architecture.model.Node import io.architecture.model.Trace import io.architecture.network.websocket.api.model.NetworkTrace -import java.util.Date +import kotlinx.datetime.Instant +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime internal fun Trace.toNode() = Node(id = nodeId, mode = 1) // TODO mode is always ACTIVE @@ -12,7 +14,7 @@ internal fun Trace.toNode() = Node(id = nodeId, mode = 1) // TODO mode is always internal fun NetworkTrace.toLocal() = TraceEntity( nodeId = nodeId, lon = lon, - sentAtTime = Date(sentAtTime), + sentAtTime = Instant.fromEpochMilliseconds(sentAtTime).toLocalDateTime(TimeZone.UTC), speed = speed, azimuth = azimuth, alt = alt, diff --git a/core/data/src/main/java/io/architecture/data/repository/DefaultConnectionStateRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultConnectionStateRepository.kt similarity index 91% rename from core/data/src/main/java/io/architecture/data/repository/DefaultConnectionStateRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultConnectionStateRepository.kt index aa67e03..3123471 100644 --- a/core/data/src/main/java/io/architecture/data/repository/DefaultConnectionStateRepository.kt +++ b/core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultConnectionStateRepository.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart +import kotlinx.datetime.Clock import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @@ -38,7 +39,7 @@ class DefaultConnectionStateRepository( ) sendClientTimeWith(2.seconds) // TODO Start on connection opened state } - .map { serverTime -> UpstreamRtt(System.currentTimeMillis() - serverTime.clientSentTime) } + .map { serverTime -> UpstreamRtt(Clock.System.now().toEpochMilliseconds() - serverTime.clientSentTime) } .onEach { sendClientTimeWith(interval) } .catch { error -> Logger.error("RTT_NETWORK", "streamRoundTripTime ", error) } .flowOn(ioDispatcher) @@ -46,7 +47,7 @@ class DefaultConnectionStateRepository( private suspend fun sendClientTimeWith(interval: Duration) { delay(interval) try { - network.sendClientTime(NetworkClientTime(System.currentTimeMillis())) + network.sendClientTime(NetworkClientTime(Clock.System.now().toEpochMilliseconds())) // TODO Look up deatils } catch (exception: Exception) { Logger.error("RTT_NETWORK", "sendClientTimeWith: error -> ", exception) } diff --git a/core/data/src/main/java/io/architecture/data/repository/DefaultRouteRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultRouteRepository.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/repository/DefaultRouteRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultRouteRepository.kt diff --git a/core/data/src/main/java/io/architecture/data/repository/DefaultTraceRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultTraceRepository.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/repository/DefaultTraceRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/DefaultTraceRepository.kt diff --git a/core/data/src/main/java/io/architecture/data/repository/interfaces/ConnectionStateRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/ConnectionStateRepository.kt similarity index 92% rename from core/data/src/main/java/io/architecture/data/repository/interfaces/ConnectionStateRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/ConnectionStateRepository.kt index 6298a1d..cea2372 100644 --- a/core/data/src/main/java/io/architecture/data/repository/interfaces/ConnectionStateRepository.kt +++ b/core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/ConnectionStateRepository.kt @@ -1,6 +1,5 @@ package io.architecture.data.repository.interfaces -import io.architecture.model.Connection import io.architecture.model.ConnectionEvent import io.architecture.model.UpstreamRtt import kotlinx.coroutines.flow.Flow diff --git a/core/data/src/main/java/io/architecture/data/repository/interfaces/NodeRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/NodeRepository.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/repository/interfaces/NodeRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/NodeRepository.kt diff --git a/core/data/src/main/java/io/architecture/data/repository/interfaces/RouteRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/RouteRepository.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/repository/interfaces/RouteRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/RouteRepository.kt diff --git a/core/data/src/main/java/io/architecture/data/repository/interfaces/TraceRepository.kt b/core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/TraceRepository.kt similarity index 100% rename from core/data/src/main/java/io/architecture/data/repository/interfaces/TraceRepository.kt rename to core/data/src/commonMain/kotlin/io/architecture/data/repository/interfaces/TraceRepository.kt diff --git a/core/database/api/.gitignore b/core/database/api/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/database/api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/database/api/build.gradle.kts b/core/database/api/build.gradle.kts index db9d463..ecacbf3 100644 --- a/core/database/api/build.gradle.kts +++ b/core/database/api/build.gradle.kts @@ -1,11 +1,17 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { - implementation(projects.core.common) - implementation(projects.core.model) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.common) + implementation(projects.core.model) - implementation(libs.kotlinx.coroutine.core) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.coroutine.core) + } + } } \ No newline at end of file diff --git a/core/database/api/src/main/java/io/architecture/database/api/dao/InterfaceNodeDao.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/dao/InterfaceNodeDao.kt similarity index 100% rename from core/database/api/src/main/java/io/architecture/database/api/dao/InterfaceNodeDao.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/dao/InterfaceNodeDao.kt diff --git a/core/database/api/src/main/java/io/architecture/database/api/dao/InterfaceRouteDao.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/dao/InterfaceRouteDao.kt similarity index 100% rename from core/database/api/src/main/java/io/architecture/database/api/dao/InterfaceRouteDao.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/dao/InterfaceRouteDao.kt diff --git a/core/database/api/src/main/java/io/architecture/database/api/dao/InterfaceTraceDao.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/dao/InterfaceTraceDao.kt similarity index 100% rename from core/database/api/src/main/java/io/architecture/database/api/dao/InterfaceTraceDao.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/dao/InterfaceTraceDao.kt diff --git a/core/database/api/src/main/java/io/architecture/database/api/model/CoordinateEntity.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/CoordinateEntity.kt similarity index 95% rename from core/database/api/src/main/java/io/architecture/database/api/model/CoordinateEntity.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/CoordinateEntity.kt index 337e539..6d4264d 100644 --- a/core/database/api/src/main/java/io/architecture/database/api/model/CoordinateEntity.kt +++ b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/CoordinateEntity.kt @@ -1,6 +1,7 @@ package io.architecture.database.api.model import io.architecture.model.Coordinate +import kotlin.jvm.JvmName open class CoordinateEntity( open val lat: Double, diff --git a/core/database/api/src/main/java/io/architecture/database/api/model/NodeEntity.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/NodeEntity.kt similarity index 81% rename from core/database/api/src/main/java/io/architecture/database/api/model/NodeEntity.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/NodeEntity.kt index ed99da3..d2f6ffb 100644 --- a/core/database/api/src/main/java/io/architecture/database/api/model/NodeEntity.kt +++ b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/NodeEntity.kt @@ -2,12 +2,17 @@ package io.architecture.database.api.model import io.architecture.model.Node import io.architecture.model.NodeMode +import kotlin.jvm.JvmName open class NodeEntity( open var id: String, open var mode: Int, -) +) { + override fun toString(): String { + return "NodeEntity(id='$id', mode=$mode)" + } +} fun T.toExternal(): Node = Node(id = id, mode = NodeMode.valueOf(mode)) diff --git a/core/database/api/src/main/java/io/architecture/database/api/model/RouteEntity.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/RouteEntity.kt similarity index 83% rename from core/database/api/src/main/java/io/architecture/database/api/model/RouteEntity.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/RouteEntity.kt index d84a3ed..4770176 100644 --- a/core/database/api/src/main/java/io/architecture/database/api/model/RouteEntity.kt +++ b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/RouteEntity.kt @@ -2,12 +2,17 @@ package io.architecture.database.api.model import io.architecture.model.Coordinate import io.architecture.model.Route +import kotlin.jvm.JvmName open class RouteEntity( open var nodeId: String, open var route: List?, -) +) { + override fun toString(): String { + return "RouteEntity(nodeId='$nodeId', route=$route)" + } +} fun T.toExternal() = Route( nodeId = nodeId, diff --git a/core/database/api/src/main/java/io/architecture/database/api/model/TraceEntity.kt b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/TraceEntity.kt similarity index 74% rename from core/database/api/src/main/java/io/architecture/database/api/model/TraceEntity.kt rename to core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/TraceEntity.kt index 4176154..3607589 100644 --- a/core/database/api/src/main/java/io/architecture/database/api/model/TraceEntity.kt +++ b/core/database/api/src/commonMain/kotlin/io/architecture/database/api/model/TraceEntity.kt @@ -1,7 +1,8 @@ package io.architecture.database.api.model import io.architecture.model.Trace -import java.util.Date +import kotlinx.datetime.LocalDateTime +import kotlin.jvm.JvmName open class TraceEntity( open var nodeId: String, @@ -10,8 +11,12 @@ open class TraceEntity( open var speed: Int, open var azimuth: Double, open var alt: Double, - open var sentAtTime: Date, -) + open var sentAtTime: LocalDateTime, +) { + override fun toString(): String { + return "TraceEntity(nodeId='$nodeId', lon=$lon, lat=$lat, speed=$speed, azimuth=$azimuth, alt=$alt, sentAtTime=$sentAtTime)" + } +} fun T.toExternal(): Trace = Trace( nodeId = nodeId, diff --git a/core/database/imp/room/.gitignore b/core/database/imp/room/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/database/imp/room/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/database/imp/room/build.gradle.kts b/core/database/imp/room/build.gradle.kts index 970d10d..23e31ae 100644 --- a/core/database/imp/room/build.gradle.kts +++ b/core/database/imp/room/build.gradle.kts @@ -10,11 +10,7 @@ android { namespace = "io.architecture.database.imp.room" compileSdk = libs.versions.compileSdk.get().toInt() - buildTypes { - release { - isMinifyEnabled = false - } - } + libraryVariants.all { val variantName = name sourceSets { @@ -24,8 +20,8 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = libs.versions.jvmTarget.get() @@ -37,6 +33,8 @@ dependencies { implementation(projects.core.datasource.api) implementation(projects.core.model) + implementation(libs.kotlinx.datetime) + // Room implementation(libs.androidx.room.runtime) implementation(libs.androidx.material3) diff --git a/core/database/imp/room/src/main/java/io/architecture/database/imp/room/convertors/DateTypeConvertor.kt b/core/database/imp/room/src/main/java/io/architecture/database/imp/room/convertors/DateTypeConvertor.kt index 8295750..0ddfbf5 100644 --- a/core/database/imp/room/src/main/java/io/architecture/database/imp/room/convertors/DateTypeConvertor.kt +++ b/core/database/imp/room/src/main/java/io/architecture/database/imp/room/convertors/DateTypeConvertor.kt @@ -1,15 +1,24 @@ package io.architecture.database.imp.room.convertors +import android.os.Build +import androidx.annotation.RequiresApi import androidx.room.TypeConverter -import java.util.Date - +import kotlinx.datetime.LocalDateTime internal class DateTypeConvertor { + @RequiresApi(Build.VERSION_CODES.O) @TypeConverter - fun fromTimestamp(value: Long?): Date? = value?.let { Date(it) } + fun toDate(dateString: String?): LocalDateTime? { + return if (dateString == null) { + null + } else { + LocalDateTime.parse(dateString) + } + } @TypeConverter - fun dateToTimestamp(date: Date?): Long? = date?.time - + fun toDateString(date: LocalDateTime?): String? { + return date?.toString() + } } \ No newline at end of file diff --git a/core/database/imp/room/src/main/java/io/architecture/database/imp/room/entity/RoomTraceEntity.kt b/core/database/imp/room/src/main/java/io/architecture/database/imp/room/entity/RoomTraceEntity.kt index b8f30a5..f116ef8 100644 --- a/core/database/imp/room/src/main/java/io/architecture/database/imp/room/entity/RoomTraceEntity.kt +++ b/core/database/imp/room/src/main/java/io/architecture/database/imp/room/entity/RoomTraceEntity.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import io.architecture.database.api.model.TraceEntity -import java.util.Date +import kotlinx.datetime.LocalDateTime @Entity( tableName = "traces" @@ -18,7 +18,7 @@ internal data class RoomTraceEntity( override var speed: Int, override var azimuth: Double, override var alt: Double, - override var sentAtTime: Date, + override var sentAtTime: LocalDateTime, ) : TraceEntity(nodeId, lon, lat, speed, azimuth, alt, sentAtTime) { companion object { diff --git a/core/datasource/api/.gitignore b/core/datasource/api/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/datasource/api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/datasource/api/build.gradle.kts b/core/datasource/api/build.gradle.kts index 36270c8..8b378c4 100644 --- a/core/datasource/api/build.gradle.kts +++ b/core/datasource/api/build.gradle.kts @@ -1,12 +1,19 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { - implementation(projects.core.model) - implementation(projects.core.database.api) - implementation(projects.core.network.websocket.api) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.model) + implementation(projects.core.database.api) + implementation(projects.core.network.websocket.api) - implementation(libs.kotlinx.coroutine.core) + implementation(libs.koin.core) + implementation(libs.kotlinx.coroutine.core) + implementation(libs.kotlinx.datetime) + } + } } \ No newline at end of file diff --git a/core/datasource/api/src/main/java/io/architecture/datasource/api/LocalDataSource.kt b/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/LocalDataSource.kt similarity index 100% rename from core/datasource/api/src/main/java/io/architecture/datasource/api/LocalDataSource.kt rename to core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/LocalDataSource.kt diff --git a/core/datasource/api/src/main/java/io/architecture/datasource/api/NetworkDataSource.kt b/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/NetworkDataSource.kt similarity index 100% rename from core/datasource/api/src/main/java/io/architecture/datasource/api/NetworkDataSource.kt rename to core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/NetworkDataSource.kt diff --git a/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/di/EmptyLocalDataSource.kt b/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/di/EmptyLocalDataSource.kt new file mode 100644 index 0000000..a6f4c16 --- /dev/null +++ b/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/di/EmptyLocalDataSource.kt @@ -0,0 +1,27 @@ +package io.architecture.datasource.api.di + +import io.architecture.database.api.model.NodeEntity +import io.architecture.database.api.model.RouteEntity +import io.architecture.database.api.model.TraceEntity +import io.architecture.datasource.api.LocalDataSource +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import org.koin.dsl.bind +import org.koin.dsl.module + +val emptyMockLocalDatasourceModule = module { + single { + object : LocalDataSource { + override fun observeAllTraces(): Flow> = emptyFlow() + override fun observeAllNodes(): Flow> = emptyFlow() + override fun observeTraceCount(): Flow = emptyFlow() + override fun observeTraceBy(nodeId: String): Flow = emptyFlow() + override fun observeNodeCount(): Flow = emptyFlow() + override suspend fun getRouteBy(nodeId: String): RouteEntity? = null + override suspend fun deleteAllTraces() {} + override suspend fun createOrUpdate(trace: TraceEntity) {} + override suspend fun createOrUpdate(route: RouteEntity) {} + override suspend fun createOrUpdate(node: NodeEntity) {} + } + } bind LocalDataSource::class +} \ No newline at end of file diff --git a/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/di/InMemoryDataSource.kt b/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/di/InMemoryDataSource.kt new file mode 100644 index 0000000..10261d0 --- /dev/null +++ b/core/datasource/api/src/commonMain/kotlin/io/architecture/datasource/api/di/InMemoryDataSource.kt @@ -0,0 +1,73 @@ +package io.architecture.datasource.api.di + +import io.architecture.database.api.model.NodeEntity +import io.architecture.database.api.model.RouteEntity +import io.architecture.database.api.model.TraceEntity +import io.architecture.database.api.model.toExternal +import io.architecture.database.api.model.toLocal +import io.architecture.datasource.api.LocalDataSource +import io.architecture.model.Node +import io.architecture.model.Route +import io.architecture.model.Trace +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.distinctUntilChangedBy +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.onEach +import org.koin.dsl.bind +import org.koin.dsl.module + +@OptIn(ExperimentalCoroutinesApi::class) +val inMemoryLocalDatasourceModule = module { + single { + object : LocalDataSource { + val tracesMem = LinkedHashMap() + val traceCountFlow = MutableSharedFlow() + val tracesFlow = MutableSharedFlow>() + + val nodesMem = LinkedHashMap() + val nodeCountFlow = MutableSharedFlow() + val nodesFlow = MutableSharedFlow>() + + val routesMem = LinkedHashMap() + val routesFlow = MutableSharedFlow>() + + override fun observeAllTraces(): Flow> = tracesFlow + override fun observeAllNodes(): Flow> = nodesFlow + override fun observeTraceCount(): Flow = traceCountFlow + override fun observeTraceBy(nodeId: String): Flow = + tracesFlow.flatMapLatest { it.asFlow() } + .distinctUntilChangedBy { it.sentAtTime } + .filter { it.nodeId == nodeId } + .onEach { println(it.toString()) } + + override fun observeNodeCount(): Flow = nodeCountFlow + + override suspend fun getRouteBy(nodeId: String): RouteEntity? = + routesMem[nodeId]?.toLocal() + + override suspend fun deleteAllTraces() = tracesMem.clear() + + override suspend fun createOrUpdate(trace: TraceEntity) { + tracesMem[trace.nodeId] = trace.toExternal() + tracesFlow.emit(tracesMem.values.map { it.toLocal() }.toList()) + createOrUpdate(NodeEntity(trace.nodeId, 1)) // TODO Always moving + traceCountFlow.emit(tracesMem.size) + } + + override suspend fun createOrUpdate(route: RouteEntity) { + routesMem[route.nodeId] = route.toExternal() + routesFlow.emit(routesMem.values.map { it.toLocal() }.toList()) + } + + override suspend fun createOrUpdate(node: NodeEntity) { + nodesMem[node.id] = node.toExternal() + nodesFlow.emit(nodesMem.values.map { it.toLocal() }.toList()) + nodeCountFlow.emit(nodesMem.size) + } + } + } bind LocalDataSource::class +} \ No newline at end of file diff --git a/core/designsystem/.gitignore b/core/designsystem/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/designsystem/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts index c5df4ea..6bad32c 100644 --- a/core/designsystem/build.gradle.kts +++ b/core/designsystem/build.gradle.kts @@ -1,31 +1,23 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.convention.multiplatform.target.default) } -android { - namespace = "io.architecture.core.design.system" - compileSdk = libs.versions.compileSdk.get().toInt() +kotlin { + sourceSets { + commonMain.dependencies { + implementation(libs.koin.core) + implementation(libs.koin.mp.compose) - buildTypes { - release { - isMinifyEnabled = false + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.ui) + implementation(compose.components.resources) + + implementation(libs.kotlinx.coroutine.core) } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = libs.versions.jvmTarget.get() - } -} - -dependencies { - implementation(libs.androidx.coreKtx) - testImplementation(libs.junit.junit) - implementation(libs.androidx.ui.graphics.android) - androidTestImplementation(libs.junit) - androidTestImplementation(libs.espresso.core) } \ No newline at end of file diff --git a/core/designsystem/src/androidMain/kotlin/io/architecture/core/design/system/theme/Font.android.kt b/core/designsystem/src/androidMain/kotlin/io/architecture/core/design/system/theme/Font.android.kt new file mode 100644 index 0000000..cf2dc4d --- /dev/null +++ b/core/designsystem/src/androidMain/kotlin/io/architecture/core/design/system/theme/Font.android.kt @@ -0,0 +1,19 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight + +@Composable +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font { + val context = LocalContext.current + val id = context.resources.getIdentifier(res, "font", context.packageName) + return Font(id, weight, style) +} \ No newline at end of file diff --git a/core/designsystem/src/commonMain/composeResources/font/uav_osd_mono.ttf b/core/designsystem/src/commonMain/composeResources/font/uav_osd_mono.ttf new file mode 100644 index 0000000..eff34e3 Binary files /dev/null and b/core/designsystem/src/commonMain/composeResources/font/uav_osd_mono.ttf differ diff --git a/core/designsystem/src/commonMain/composeResources/font/uav_osd_sans_mono.ttf b/core/designsystem/src/commonMain/composeResources/font/uav_osd_sans_mono.ttf new file mode 100644 index 0000000..61b7a16 Binary files /dev/null and b/core/designsystem/src/commonMain/composeResources/font/uav_osd_sans_mono.ttf differ diff --git a/core/designsystem/src/commonMain/composeResources/font/vcr_osd_mono.ttf b/core/designsystem/src/commonMain/composeResources/font/vcr_osd_mono.ttf new file mode 100644 index 0000000..9322814 Binary files /dev/null and b/core/designsystem/src/commonMain/composeResources/font/vcr_osd_mono.ttf differ diff --git a/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/component/BlinkAnimatedText.kt b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/component/BlinkAnimatedText.kt new file mode 100644 index 0000000..f18f457 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/component/BlinkAnimatedText.kt @@ -0,0 +1,79 @@ +package io.architecture.core.design.system.component + +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.material.LocalTextStyle +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.TransformOrigin +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.text.TextLayoutResult +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.text.style.TextMotion +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.TextUnit + +@Composable +fun AnimatedBlinkText( + modifier: Modifier = Modifier, + text: String, + color: Color = Color.Unspecified, + fontSize: TextUnit = TextUnit.Unspecified, + fontStyle: FontStyle? = null, + fontWeight: FontWeight? = null, + fontFamily: FontFamily? = null, + letterSpacing: TextUnit = TextUnit.Unspecified, + textDecoration: TextDecoration? = null, + textAlign: TextAlign? = null, + lineHeight: TextUnit = TextUnit.Unspecified, + overflow: TextOverflow = TextOverflow.Clip, + softWrap: Boolean = true, + maxLines: Int = Int.MAX_VALUE, + minLines: Int = 1, + onTextLayout: ((TextLayoutResult) -> Unit)? = null, +) { + val infiniteTransition = rememberInfiniteTransition(label = "infinite transition") + val alphaTransition by infiniteTransition.animateFloat( + initialValue = 1f, + targetValue = 0f, + animationSpec = infiniteRepeatable(tween(700), RepeatMode.Reverse), + label = "alpha" + ) + Text( + text = text, + color = color, + fontSize = fontSize, + fontStyle = fontStyle, + fontWeight = fontWeight, + fontFamily = fontFamily, + letterSpacing = letterSpacing, + textDecoration = textDecoration, + textAlign = textAlign, + lineHeight = lineHeight, + overflow = overflow, + softWrap = softWrap, + maxLines = maxLines, + minLines = minLines, + onTextLayout = onTextLayout, + + modifier = Modifier + .graphicsLayer { + alpha = alphaTransition + transformOrigin = TransformOrigin.Center + } + .then(modifier), + // Text composable does not take TextMotion as a parameter. + // Provide it via style argument but make sure that we are copying from current theme + style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated), + ) +} \ No newline at end of file diff --git a/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Color.kt b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Color.kt new file mode 100644 index 0000000..9871cec --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Color.kt @@ -0,0 +1,39 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.material.darkColors +import androidx.compose.ui.graphics.Color + +val purple_500 = Color(0xFF6200EE) +val purple_700 = Color(0xFF3700B3) +val orange_700 = Color(0xFFA00000) +val teal_200 = Color(0xFF03DAC5) +val teal_700 = Color(0xFF018786) +val teal_700_dark = Color(0xFF006463) +val teal_red = Color(0xFFD32F2F) +val black = Color(0xFF000000) +val white = Color(0xFFFFFFFF) + +val colorPallete = + darkColors( + primary = purple_500, + primaryVariant = purple_700, + secondary = teal_700, + secondaryVariant = teal_700_dark, + background = black, + surface = black, + onPrimary = black, + onSecondary = black, + onBackground = black, + onSurface = black, + error = teal_red, + onError = teal_red + ) + +val yellow_green = Color(0xFFA2F854) +val yellow_green_secondary = Color(0xFF6EF633) +val green_secondary = Color(0xFF02BC87) +val marquee_background = Color(0xFF62E788) + +val green_state_success = Color(0xFF2ED573) +val yellow_state_warning = Color(0xFFFFBE21) +val red_state_danger = Color(0xFFEA5B5B) \ No newline at end of file diff --git a/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Font.kt b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Font.kt new file mode 100644 index 0000000..c70b19a --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Font.kt @@ -0,0 +1,14 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight + +@Composable +expect fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font \ No newline at end of file diff --git a/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Shape.kt b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Shape.kt new file mode 100644 index 0000000..c379b25 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Shape.kt @@ -0,0 +1,11 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Shapes +import androidx.compose.ui.unit.dp + +val shapes = Shapes( + small = RoundedCornerShape(1.dp), + medium = RoundedCornerShape(1.dp), + large = RoundedCornerShape(1.dp) +) \ No newline at end of file diff --git a/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Theme.kt b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Theme.kt new file mode 100644 index 0000000..6270062 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Theme.kt @@ -0,0 +1,16 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.Composable + +@Composable +fun UAVTheme( + content: @Composable () -> Unit, +) { + MaterialTheme( + colors = colorPallete, + content = content, + shapes = shapes, + typography = getTypography() + ) +} \ No newline at end of file diff --git a/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Typography.kt b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Typography.kt new file mode 100644 index 0000000..bd0b2b2 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/io/architecture/core/design/system/theme/Typography.kt @@ -0,0 +1,115 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.material.Typography +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +@Composable +fun getTypography(): Typography { + FontFamily( + font( + name = "UAV OSD Mono", + res = "uav_osd_mono", + weight = FontWeight.Normal, + style = FontStyle.Normal + ) + ) + FontFamily( + font( + name = "UAV OSD Sans Mono", + res = "vcr_osd_mono", + weight = FontWeight.Normal, + style = FontStyle.Normal + ) + ) + + val default = FontFamily( + font( + name = "UAV OSD Sans Mono", + res = "uav_osd_sans_mono", + weight = FontWeight.Normal, + style = FontStyle.Normal + ) + ) + + return Typography( + defaultFontFamily = default, + h1 = TextStyle( + fontSize = 38.sp, + fontWeight = FontWeight.Bold, + ), + h2 = TextStyle( + fontWeight = FontWeight.Light, + fontSize = 60.sp, + lineHeight = 72.sp, + letterSpacing = (-0.5).sp + ), + h3 = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 48.sp, + lineHeight = 56.sp, + letterSpacing = 0.sp + ), + h4 = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 34.sp, + lineHeight = 36.sp, + letterSpacing = 0.25.sp + ), + h5 = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 24.sp, + lineHeight = 24.sp, + letterSpacing = 0.sp + ), + h6 = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 20.sp, + lineHeight = 24.sp, + letterSpacing = 0.15.sp + ), + subtitle1 = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.15.sp + ), + subtitle2 = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + lineHeight = 24.sp, + letterSpacing = 0.1.sp + ), + body1 = TextStyle( + fontSize = 12.sp, + lineHeight = 20.sp, + fontWeight = FontWeight.Normal, + ), + body2 = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + lineHeight = 20.sp, + letterSpacing = 0.25.sp + ), + button = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 15.sp, + ), + caption = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.4.sp + ), + overline = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 10.sp, + lineHeight = 16.sp, + letterSpacing = 1.5.sp + ) + ) +} \ No newline at end of file diff --git a/core/designsystem/src/iosMain/kotlin/io/architecture/core/design/system/theme/Font.ios.kt b/core/designsystem/src/iosMain/kotlin/io/architecture/core/design/system/theme/Font.ios.kt new file mode 100644 index 0000000..c77e143 --- /dev/null +++ b/core/designsystem/src/iosMain/kotlin/io/architecture/core/design/system/theme/Font.ios.kt @@ -0,0 +1,28 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.platform.Font +import kotlinx.coroutines.runBlocking +import node_traces_streaming.core.designsystem.generated.resources.Res +import org.jetbrains.compose.resources.ExperimentalResourceApi + +private val cache: MutableMap = mutableMapOf() + +@OptIn(ExperimentalResourceApi::class) +@Composable +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font = cache.getOrPut(res) { + Font( + res, + runBlocking { + Res.readBytes("font/$res.ttf") + }, weight, style + ) +} \ No newline at end of file diff --git a/core/designsystem/src/jsMain/kotlin/io/architecture/core/design/system/theme/Font.js.kt b/core/designsystem/src/jsMain/kotlin/io/architecture/core/design/system/theme/Font.js.kt new file mode 100644 index 0000000..5981c27 --- /dev/null +++ b/core/designsystem/src/jsMain/kotlin/io/architecture/core/design/system/theme/Font.js.kt @@ -0,0 +1,17 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.font.Font + +@Composable +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font = TODO( + "@Composable\n" + + "actual fun font() js" +) \ No newline at end of file diff --git a/core/designsystem/src/jvmMain/kotlin/io/architecture/core/design/system/theme/Font.jvm.kt b/core/designsystem/src/jvmMain/kotlin/io/architecture/core/design/system/theme/Font.jvm.kt new file mode 100644 index 0000000..04c34e5 --- /dev/null +++ b/core/designsystem/src/jvmMain/kotlin/io/architecture/core/design/system/theme/Font.jvm.kt @@ -0,0 +1,15 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.platform.Font + +@Composable +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font = Font("font/$res.ttf", weight, style) \ No newline at end of file diff --git a/core/designsystem/src/main/java/io/architecture/core/design/system/theme/Color.kt b/core/designsystem/src/main/java/io/architecture/core/design/system/theme/Color.kt deleted file mode 100644 index 80134d3..0000000 --- a/core/designsystem/src/main/java/io/architecture/core/design/system/theme/Color.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.architecture.core.design.system.theme - -import androidx.compose.ui.graphics.Color - -val purple_500 = Color(0xFF6200EE) -val purple_700 = Color(0xFF3700B3) -val orange_700 = Color(0xFFA00000) -val teal_200 = Color(0xFF03DAC5) -val teal_700 = Color(0xFF018786) -val teal_700_dark = Color(0xFF006463) -val teal_red = Color(0xFFD32F2F) -val black = Color(0xFF000000) -val white = Color(0xFFFFFFFF) \ No newline at end of file diff --git a/core/designsystem/src/wasmJsMain/kotlin/io/architecture/core/design/system/theme/Font.wasmJs.kt b/core/designsystem/src/wasmJsMain/kotlin/io/architecture/core/design/system/theme/Font.wasmJs.kt new file mode 100644 index 0000000..77c7b09 --- /dev/null +++ b/core/designsystem/src/wasmJsMain/kotlin/io/architecture/core/design/system/theme/Font.wasmJs.kt @@ -0,0 +1,18 @@ +package io.architecture.core.design.system.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.Font +import org.jetbrains.compose.resources.FontResource + +@OptIn(ExperimentalResourceApi::class) +@Composable +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font = Font(FontResource("fonts/$res.ttf")) \ No newline at end of file diff --git a/core/di/.gitignore b/core/di/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/di/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/di/build.gradle.kts b/core/di/build.gradle.kts index 2dfdc09..8564a10 100644 --- a/core/di/build.gradle.kts +++ b/core/di/build.gradle.kts @@ -1,35 +1,32 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) - alias(libs.plugins.ksp) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -sourceSets.main { - java.srcDirs("build/generated/ksp/main/kotlin") -} - -dependencies { - implementation(projects.core.common) - implementation(projects.core.domain) - implementation(projects.core.data) - implementation(projects.core.network.websocket.imp.ktor) - implementation(projects.core.runtime.configuration) - - implementation(libs.kotlinx.coroutine.android) - - implementation(libs.koin.core) - implementation(libs.koin.annotations) - implementation(libs.koin.test) - ksp(libs.koin.ksp.compiler) +kotlin { + sourceSets { + commonMain.dependencies { + api(projects.core.common) + api(projects.core.domain) + api(projects.core.data) + api(projects.core.model) + api(projects.core.network.websocket.imp.ktor) + api(projects.core.runtime.configuration) - testImplementation(projects.core.datasource.api) + implementation(libs.kotlinx.coroutine.core) + implementation(libs.koin.core) + implementation(libs.koin.test) + } + commonTest.dependencies { + implementation(projects.core.datasource.api) + implementation(projects.core.network.websocket.api) + implementation(projects.core.database.api) + implementation(projects.core.model) - testImplementation(libs.ktor.client.core) - testImplementation(libs.ktor.client.cio) - testImplementation(libs.ktor.client.websockets) - testImplementation(libs.ktor.client.serialization.jvm) - testImplementation(libs.ktor.serialization.kotlinx.protobuf) - testImplementation(libs.ktor.client.logging.jvm) - testImplementation(libs.junit.junit) + implementation(kotlin("reflect")) + implementation(kotlin("test")) + } + } } \ No newline at end of file diff --git a/core/di/src/androidMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt b/core/di/src/androidMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt new file mode 100644 index 0000000..ac4ac85 --- /dev/null +++ b/core/di/src/androidMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt @@ -0,0 +1,11 @@ +package io.architecture.core.di + +import kotlinx.coroutines.Dispatchers +import org.koin.core.qualifier.named +import org.koin.dsl.module + +actual val coroutineDispatcherModule = module { + single(named("ioDispatcher")) { Dispatchers.IO } + single(named("defaultDispatcher")) { Dispatchers.Default } + single(named("mainDispatcher")) { Dispatchers.Main } +} \ No newline at end of file diff --git a/core/di/src/main/java/io/architecture/core/di/CoreKoinModule.kt b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoreKoinModule.kt similarity index 72% rename from core/di/src/main/java/io/architecture/core/di/CoreKoinModule.kt rename to core/di/src/commonMain/kotlin/io/architecture/core/di/CoreKoinModule.kt index dad4685..a8e36d5 100644 --- a/core/di/src/main/java/io/architecture/core/di/CoreKoinModule.kt +++ b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoreKoinModule.kt @@ -1,18 +1,18 @@ package io.architecture.core.di -import io.architecture.core.runtime.configuration.RuntimeConfigurationModule +import io.architecture.core.runtime.configuration.runtimeModule import io.architecture.data.repositoryModule import io.architecture.domain.di.useCaseModule import io.architecture.network.websocket.imp.ktor.di.ktorClientModule import io.architecture.network.websocket.imp.ktor.di.ktorModule import io.architecture.network.websocket.imp.ktor.di.ktorServiceModule import org.koin.dsl.module -import org.koin.ksp.generated.module +// umbrella module val coreKoinModules = module { includes( - CoroutineKoinModule().module, - RuntimeConfigurationModule().module, + coroutineModule, + runtimeModule, repositoryModule, useCaseModule, ktorModule, diff --git a/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModuleExpected.kt b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModuleExpected.kt new file mode 100644 index 0000000..c16471d --- /dev/null +++ b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModuleExpected.kt @@ -0,0 +1,5 @@ +package io.architecture.core.di + +import org.koin.core.module.Module + +expect val coroutineDispatcherModule: Module \ No newline at end of file diff --git a/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineKoinModule.kt b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineKoinModule.kt new file mode 100644 index 0000000..632abd5 --- /dev/null +++ b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineKoinModule.kt @@ -0,0 +1,7 @@ +package io.architecture.core.di + +import org.koin.dsl.module + +val coroutineModule = module { + includes(coroutineDispatcherModule, coroutineScopeModule) +} \ No newline at end of file diff --git a/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineScopeKoinModule.kt b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineScopeKoinModule.kt new file mode 100644 index 0000000..846d5d3 --- /dev/null +++ b/core/di/src/commonMain/kotlin/io/architecture/core/di/CoroutineScopeKoinModule.kt @@ -0,0 +1,27 @@ +package io.architecture.core.di + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import org.koin.core.qualifier.named +import org.koin.dsl.module + +val coroutineScopeModule = module { + single(named("applicationScope")) { + CoroutineScope( + SupervisorJob() + get( + named("defaultDispatcher") + ) + ) + } + single(named("applicationIoScope")) { + CoroutineScope( + SupervisorJob() + get( + named("ioDispatcher") + ) + ) + } +} + + + diff --git a/core/di/src/commonTest/kotlin/io/architecture/core/di/CoreKoinCheckModulesTest.kt b/core/di/src/commonTest/kotlin/io/architecture/core/di/CoreKoinCheckModulesTest.kt new file mode 100644 index 0000000..077b0ae --- /dev/null +++ b/core/di/src/commonTest/kotlin/io/architecture/core/di/CoreKoinCheckModulesTest.kt @@ -0,0 +1,54 @@ +package io.architecture.core.di + +import io.architecture.database.api.model.NodeEntity +import io.architecture.database.api.model.RouteEntity +import io.architecture.database.api.model.TraceEntity +import io.architecture.datasource.api.LocalDataSource +import io.architecture.datasource.api.NetworkDataSource +import io.architecture.model.ConnectionEvent +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.emptyFlow +import org.koin.dsl.bind +import org.koin.dsl.module +import org.koin.test.check.checkModules +import kotlin.test.Test + +class CoreKoinCheckModulesTest { + + @Test + fun checkKoinModule() { + + val mockModules = module { + single { + object : NetworkDataSource { + override fun openSession() {} + override fun closeSession() {} + override fun streamTraces(): Flow = emptyFlow() + override fun streamRoutes(): Flow = emptyFlow() + override suspend fun sendClientTime(time: io.architecture.network.websocket.api.model.NetworkClientTime) {} + override fun streamServerTime(): Flow = emptyFlow() + override fun streamConnectionEvents(): SharedFlow = emptyFlow() as SharedFlow + } + } bind NetworkDataSource::class + single { + object : LocalDataSource { + override fun observeAllTraces(): Flow> = emptyFlow() + override fun observeAllNodes(): Flow> = emptyFlow() + override fun observeTraceCount(): Flow = emptyFlow() + override fun observeTraceBy(nodeId: String): Flow = emptyFlow() + override fun observeNodeCount(): Flow = emptyFlow() + override suspend fun getRouteBy(nodeId: String): RouteEntity? = null + override suspend fun deleteAllTraces() {} + override suspend fun createOrUpdate(trace: TraceEntity) {} + override suspend fun createOrUpdate(route: RouteEntity) {} + override suspend fun createOrUpdate(node: NodeEntity) {} + } + } bind LocalDataSource::class + } + + checkModules { + modules(coreKoinModules, mockModules) + } + } +} \ No newline at end of file diff --git a/core/di/src/iosMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt b/core/di/src/iosMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt new file mode 100644 index 0000000..26740ce --- /dev/null +++ b/core/di/src/iosMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt @@ -0,0 +1,12 @@ +package io.architecture.core.di + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import org.koin.core.qualifier.named +import org.koin.dsl.module + +actual val coroutineDispatcherModule = module { + single(named("ioDispatcher")) { Dispatchers.IO } + single(named("defaultDispatcher")) { Dispatchers.Default } + single(named("mainDispatcher")) { Dispatchers.Main } +} \ No newline at end of file diff --git a/core/di/src/jsMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt b/core/di/src/jsMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt new file mode 100644 index 0000000..715d779 --- /dev/null +++ b/core/di/src/jsMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt @@ -0,0 +1,11 @@ +package io.architecture.core.di + +import kotlinx.coroutines.Dispatchers +import org.koin.core.qualifier.named +import org.koin.dsl.module + +actual val coroutineDispatcherModule = module { + single(named("ioDispatcher")) { Dispatchers.Default } // Replaced + single(named("defaultDispatcher")) { Dispatchers.Default } + single(named("mainDispatcher")) { Dispatchers.Main } +} \ No newline at end of file diff --git a/core/di/src/jvmMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt b/core/di/src/jvmMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt new file mode 100644 index 0000000..ac4ac85 --- /dev/null +++ b/core/di/src/jvmMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt @@ -0,0 +1,11 @@ +package io.architecture.core.di + +import kotlinx.coroutines.Dispatchers +import org.koin.core.qualifier.named +import org.koin.dsl.module + +actual val coroutineDispatcherModule = module { + single(named("ioDispatcher")) { Dispatchers.IO } + single(named("defaultDispatcher")) { Dispatchers.Default } + single(named("mainDispatcher")) { Dispatchers.Main } +} \ No newline at end of file diff --git a/core/di/src/main/java/io/architecture/core/di/CoroutineDispatcherKoinModule.kt b/core/di/src/main/java/io/architecture/core/di/CoroutineDispatcherKoinModule.kt deleted file mode 100644 index cf9b303..0000000 --- a/core/di/src/main/java/io/architecture/core/di/CoroutineDispatcherKoinModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.architecture.core.di - -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import org.koin.core.annotation.Module -import org.koin.core.annotation.Named -import org.koin.core.annotation.Single - -@Module -internal class CoroutineDispatcherKoinModule { - - @Single - @Named("ioDispatcher") - fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO - - @Single - @Named("defaultDispatcher") - fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default -} \ No newline at end of file diff --git a/core/di/src/main/java/io/architecture/core/di/CoroutineKoinModule.kt b/core/di/src/main/java/io/architecture/core/di/CoroutineKoinModule.kt deleted file mode 100644 index efe0bc7..0000000 --- a/core/di/src/main/java/io/architecture/core/di/CoroutineKoinModule.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.architecture.core.di - -import org.koin.core.annotation.ComponentScan -import org.koin.core.annotation.Module - -@Module(includes = [CoroutineScopeKoinModule::class, CoroutineDispatcherKoinModule::class]) -@ComponentScan("io.architecture.common") -class CoroutineKoinModule \ No newline at end of file diff --git a/core/di/src/main/java/io/architecture/core/di/CoroutineScopeKoinModule.kt b/core/di/src/main/java/io/architecture/core/di/CoroutineScopeKoinModule.kt deleted file mode 100644 index 7c1488a..0000000 --- a/core/di/src/main/java/io/architecture/core/di/CoroutineScopeKoinModule.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.architecture.core.di - -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import org.koin.core.annotation.Module -import org.koin.core.annotation.Named -import org.koin.core.annotation.Single - -@Module(includes = [CoroutineDispatcherKoinModule::class]) -internal class CoroutineScopeKoinModule { - - @Single - @Named("applicationScope") - fun providesCoroutineScope( - @Named("defaultDispatcher") dispatcher: CoroutineDispatcher, - ): CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher) - - @Single - @Named("applicationIoScope") - fun providesIoCoroutineScope( - @Named("ioDispatcher") dispatcher: CoroutineDispatcher, - ): CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher) -} - - - diff --git a/core/di/src/test/java/io/architecture/core/di/CoreKoinCheckModulesTest.kt b/core/di/src/test/java/io/architecture/core/di/CoreKoinCheckModulesTest.kt deleted file mode 100644 index 43f984d..0000000 --- a/core/di/src/test/java/io/architecture/core/di/CoreKoinCheckModulesTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -package io.architecture.core.di - -import io.architecture.core.runtime.configuration.RuntimeConfigurationModule -import io.architecture.data.repositoryModule -import io.architecture.datasource.api.LocalDataSource -import io.architecture.datasource.api.NetworkDataSource -import io.architecture.domain.di.useCaseModule -import io.architecture.network.websocket.imp.ktor.di.ktorClientModule -import io.architecture.network.websocket.imp.ktor.di.ktorModule -import io.architecture.network.websocket.imp.ktor.di.ktorServiceModule -import org.junit.Test -import org.koin.core.annotation.KoinExperimentalAPI -import org.koin.dsl.module -import org.koin.ksp.generated.module -import org.koin.test.verify.verify - -class CoreKoinCheckModulesTest { - - private val coreModule = module { - includes( - CoroutineKoinModule().module, - RuntimeConfigurationModule().module, - repositoryModule, - useCaseModule, - ktorModule, - ktorClientModule, - ktorServiceModule, - ) - } - - @Test - @OptIn(KoinExperimentalAPI::class) - fun checkKoinModule() { - coreModule.verify( - extraTypes = listOf( - LocalDataSource::class, // Ignore. Provided in target module (:compose-app) - NetworkDataSource::class, // Ignore. Provided in target module (:compose-app) - kotlin.reflect.KClass::class, - io.ktor.client.engine.HttpClientEngine::class, - io.ktor.client.HttpClientConfig::class - ) - ) - } -} \ No newline at end of file diff --git a/core/di/src/wasmJsMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt b/core/di/src/wasmJsMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt new file mode 100644 index 0000000..9bbd053 --- /dev/null +++ b/core/di/src/wasmJsMain/kotlin/io/architecture/core/di/CoroutineDispatcherKoinModule.kt @@ -0,0 +1,11 @@ +package io.architecture.core.di + +import kotlinx.coroutines.Dispatchers +import org.koin.core.qualifier.named +import org.koin.dsl.module + +actual val coroutineDispatcherModule = module { + single(named("ioDispatcher")) { Dispatchers.Default } // Replaced as the same as jsMain has + single(named("defaultDispatcher")) { Dispatchers.Default } + single(named("mainDispatcher")) { Dispatchers.Main } +} \ No newline at end of file diff --git a/core/domain/.gitignore b/core/domain/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/domain/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/domain/build.gradle.kts b/core/domain/build.gradle.kts index 9b29e81..b50c6a5 100644 --- a/core/domain/build.gradle.kts +++ b/core/domain/build.gradle.kts @@ -1,22 +1,20 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) - alias(libs.plugins.ksp) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -sourceSets.main { - java.srcDirs("build/generated/ksp/main/kotlin") -} - -dependencies { - implementation(projects.core.data) - implementation(projects.core.common) - implementation(projects.core.model) - implementation(projects.core.runtime.logging) - - implementation(libs.kotlinx.coroutine.core) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.data) + implementation(projects.core.common) + implementation(projects.core.model) + implementation(projects.core.runtime.logging) - // Koin - implementation(libs.koin.core) - ksp(libs.koin.ksp.compiler) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.coroutine.core) + implementation(libs.koin.core) + } + } } \ No newline at end of file diff --git a/core/domain/src/main/java/io/architecture/domain/ConvertAzimuthToDirectionUseCase.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/ConvertAzimuthToDirectionUseCase.kt similarity index 100% rename from core/domain/src/main/java/io/architecture/domain/ConvertAzimuthToDirectionUseCase.kt rename to core/domain/src/commonMain/kotlin/io/architecture/domain/ConvertAzimuthToDirectionUseCase.kt diff --git a/core/domain/src/commonMain/kotlin/io/architecture/domain/FormatDatetimeUseCase.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/FormatDatetimeUseCase.kt new file mode 100644 index 0000000..341a786 --- /dev/null +++ b/core/domain/src/commonMain/kotlin/io/architecture/domain/FormatDatetimeUseCase.kt @@ -0,0 +1,16 @@ +package io.architecture.domain + +import kotlinx.datetime.LocalDateTime + +class FormatDatetimeUseCase { + + operator fun invoke( + date: LocalDateTime + ): String { + // TODO Better to have user data repository for local and other parameters + // If you target Android devices running below API 26, you need to use Android Gradle plugin 4.0 + // or newer and enable core library desugaring. + // https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#using-in-your-projects + return date.toString() + } +} \ No newline at end of file diff --git a/core/domain/src/main/java/io/architecture/domain/GetConnectionStateUseCase.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/GetConnectionStateUseCase.kt similarity index 100% rename from core/domain/src/main/java/io/architecture/domain/GetConnectionStateUseCase.kt rename to core/domain/src/commonMain/kotlin/io/architecture/domain/GetConnectionStateUseCase.kt diff --git a/core/domain/src/main/java/io/architecture/domain/GetStreamChunkedNodeWithTraceUseCase.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/GetStreamChunkedNodeWithTraceUseCase.kt similarity index 100% rename from core/domain/src/main/java/io/architecture/domain/GetStreamChunkedNodeWithTraceUseCase.kt rename to core/domain/src/commonMain/kotlin/io/architecture/domain/GetStreamChunkedNodeWithTraceUseCase.kt diff --git a/core/domain/src/main/java/io/architecture/domain/GetStreamTraceByIdUseCase.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/GetStreamTraceByIdUseCase.kt similarity index 100% rename from core/domain/src/main/java/io/architecture/domain/GetStreamTraceByIdUseCase.kt rename to core/domain/src/commonMain/kotlin/io/architecture/domain/GetStreamTraceByIdUseCase.kt diff --git a/core/domain/src/main/java/io/architecture/domain/PersistRoutesUseCase.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/PersistRoutesUseCase.kt similarity index 100% rename from core/domain/src/main/java/io/architecture/domain/PersistRoutesUseCase.kt rename to core/domain/src/commonMain/kotlin/io/architecture/domain/PersistRoutesUseCase.kt diff --git a/core/domain/src/main/java/io/architecture/domain/di/UseCaseKoinModule.kt b/core/domain/src/commonMain/kotlin/io/architecture/domain/di/UseCaseKoinModule.kt similarity index 100% rename from core/domain/src/main/java/io/architecture/domain/di/UseCaseKoinModule.kt rename to core/domain/src/commonMain/kotlin/io/architecture/domain/di/UseCaseKoinModule.kt diff --git a/core/domain/src/main/java/io/architecture/domain/FormatDatetimeUseCase.kt b/core/domain/src/main/java/io/architecture/domain/FormatDatetimeUseCase.kt deleted file mode 100644 index 9c33366..0000000 --- a/core/domain/src/main/java/io/architecture/domain/FormatDatetimeUseCase.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.architecture.domain - -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale - -class FormatDatetimeUseCase { - - operator fun invoke(date: Date, preferredPattern: String = DEFAULT_DATETIME_FORMAT): String = - SimpleDateFormat( - preferredPattern, - Locale.getDefault() - ).format(date) // TODO Better to have user data repository for local and other parameters - - companion object { - const val DEFAULT_DATETIME_FORMAT: String = "yyyy-MM-dd HH:mm:ss:SSSSSSS" - } -} \ No newline at end of file diff --git a/core/model/.gitignore b/core/model/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/model/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/model/build.gradle.kts b/core/model/build.gradle.kts index 88da1d4..6a181d0 100644 --- a/core/model/build.gradle.kts +++ b/core/model/build.gradle.kts @@ -1,7 +1,13 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { +kotlin { + sourceSets { + commonMain.dependencies { + implementation(libs.kotlinx.datetime) + } + } } \ No newline at end of file diff --git a/core/model/src/main/java/io/architecture/model/CompositeNodeTrace.kt b/core/model/src/commonMain/kotlin/io/architecture/model/CompositeNodeTrace.kt similarity index 89% rename from core/model/src/main/java/io/architecture/model/CompositeNodeTrace.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/CompositeNodeTrace.kt index 2f2c178..6ec2531 100644 --- a/core/model/src/main/java/io/architecture/model/CompositeNodeTrace.kt +++ b/core/model/src/commonMain/kotlin/io/architecture/model/CompositeNodeTrace.kt @@ -6,7 +6,6 @@ data class CompositeNodeTrace( ) { override fun equals(other: Any?): Boolean { if (this === other) return true - if (javaClass != other?.javaClass) return false other as CompositeNodeTrace diff --git a/core/model/src/main/java/io/architecture/model/Connection.kt b/core/model/src/commonMain/kotlin/io/architecture/model/Connection.kt similarity index 100% rename from core/model/src/main/java/io/architecture/model/Connection.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/Connection.kt diff --git a/core/model/src/main/java/io/architecture/model/Coordinate.kt b/core/model/src/commonMain/kotlin/io/architecture/model/Coordinate.kt similarity index 100% rename from core/model/src/main/java/io/architecture/model/Coordinate.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/Coordinate.kt diff --git a/core/model/src/main/java/io/architecture/model/Node.kt b/core/model/src/commonMain/kotlin/io/architecture/model/Node.kt similarity index 100% rename from core/model/src/main/java/io/architecture/model/Node.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/Node.kt diff --git a/core/model/src/main/java/io/architecture/model/Route.kt b/core/model/src/commonMain/kotlin/io/architecture/model/Route.kt similarity index 100% rename from core/model/src/main/java/io/architecture/model/Route.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/Route.kt diff --git a/core/model/src/main/java/io/architecture/model/SocketConnectionEvent.kt b/core/model/src/commonMain/kotlin/io/architecture/model/SocketConnectionEvent.kt similarity index 100% rename from core/model/src/main/java/io/architecture/model/SocketConnectionEvent.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/SocketConnectionEvent.kt diff --git a/core/model/src/main/java/io/architecture/model/Trace.kt b/core/model/src/commonMain/kotlin/io/architecture/model/Trace.kt similarity index 71% rename from core/model/src/main/java/io/architecture/model/Trace.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/Trace.kt index 5689b23..9c8fd93 100644 --- a/core/model/src/main/java/io/architecture/model/Trace.kt +++ b/core/model/src/commonMain/kotlin/io/architecture/model/Trace.kt @@ -1,6 +1,6 @@ package io.architecture.model -import java.util.Date +import kotlinx.datetime.LocalDateTime data class Trace( var nodeId: String = "", @@ -9,9 +9,9 @@ data class Trace( var speed: Int = 0, var azimuth: Double = 0.0, var alt: Double = 0.0, - var sentAtTime: Date, + var sentAtTime: LocalDateTime, var formattedDatetime: String? = "", - var direction: String? = "" + var direction: String? = "", ) diff --git a/core/model/src/main/java/io/architecture/model/UpstreamRtt.kt b/core/model/src/commonMain/kotlin/io/architecture/model/UpstreamRtt.kt similarity index 74% rename from core/model/src/main/java/io/architecture/model/UpstreamRtt.kt rename to core/model/src/commonMain/kotlin/io/architecture/model/UpstreamRtt.kt index 6aac084..e8422f1 100644 --- a/core/model/src/main/java/io/architecture/model/UpstreamRtt.kt +++ b/core/model/src/commonMain/kotlin/io/architecture/model/UpstreamRtt.kt @@ -1,4 +1,6 @@ package io.architecture.model +import kotlin.jvm.JvmInline + @JvmInline value class UpstreamRtt(val value: Long) diff --git a/core/network/websocket/api/.gitignore b/core/network/websocket/api/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/network/websocket/api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/network/websocket/api/build.gradle.kts b/core/network/websocket/api/build.gradle.kts index 516c67c..8ce6093 100644 --- a/core/network/websocket/api/build.gradle.kts +++ b/core/network/websocket/api/build.gradle.kts @@ -1,15 +1,20 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) alias(libs.plugins.kotlin.serialize) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { - implementation(projects.core.model) - implementation(libs.gson) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.model) + implementation(libs.gson) - implementation(libs.kotlinx.coroutine.core) + implementation(libs.kotlinx.coroutine.core) - implementation(libs.kotlinx.serialization.json) - implementation(libs.kotlinx.serialization.protobuf) + implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.serialization.protobuf) + } + } } \ No newline at end of file diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/ConnectionEventStreamer.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/ConnectionEventStreamer.kt similarity index 100% rename from core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/ConnectionEventStreamer.kt rename to core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/ConnectionEventStreamer.kt diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/RouteService.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/RouteService.kt similarity index 100% rename from core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/RouteService.kt rename to core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/RouteService.kt diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/RttService.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/RttService.kt similarity index 100% rename from core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/RttService.kt rename to core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/RttService.kt diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/TraceService.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/TraceService.kt similarity index 100% rename from core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/TraceService.kt rename to core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/TraceService.kt diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkRoute.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkRoute.kt similarity index 73% rename from core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkRoute.kt rename to core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkRoute.kt index 4fd50e4..bd70674 100644 --- a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkRoute.kt +++ b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkRoute.kt @@ -1,17 +1,16 @@ package io.architecture.network.websocket.api.model -import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable @Serializable data class NetworkRoute( - @SerializedName("type") var type: String = "", - @SerializedName("n") var nodeId: String, - @SerializedName("r") var route: Array? + // TODO Removed Gson, provide actual-expected for network models + var type: String = "", + var nodeId: String, + var route: Array?, ) { override fun equals(other: Any?): Boolean { if (this === other) return true - if (javaClass != other?.javaClass) return false other as NetworkRoute diff --git a/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkTrace.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkTrace.kt new file mode 100644 index 0000000..6797e63 --- /dev/null +++ b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkTrace.kt @@ -0,0 +1,16 @@ +package io.architecture.network.websocket.api.model + +import kotlinx.serialization.Serializable + +@Serializable +data class NetworkTrace( + var type: String = "", + var lon: Double = 0.0, + var lat: Double = 0.0, + var speed: Int = 0, + var azimuth: Double = 0.0, + var alt: Double = 0.0, + var sentAtTime: Long = 0, + var nodeId: String = "", + var mode: Int = 0, +) \ No newline at end of file diff --git a/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkUpstreamRtt.kt b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkUpstreamRtt.kt new file mode 100644 index 0000000..e6ceab8 --- /dev/null +++ b/core/network/websocket/api/src/commonMain/kotlin/io/architecture/network/websocket/api/model/NetworkUpstreamRtt.kt @@ -0,0 +1,13 @@ +package io.architecture.network.websocket.api.model + +import kotlinx.serialization.Serializable + +@Serializable +data class NetworkServerTime( + var type: String = "", + var clientSentTime: Long = 0, + var serverTime: Long = 0, +) + +@Serializable +data class NetworkClientTime(val time: Long) \ No newline at end of file diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/Configuration.kt b/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/Configuration.kt deleted file mode 100644 index 4c84c9d..0000000 --- a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/Configuration.kt +++ /dev/null @@ -1,29 +0,0 @@ -package io.architecture.network.websocket.api - -//@Module -//@InstallIn(SingletonComponent::class) -//object BaseWebsocketModule { -// -// @Provides -// @Singleton -// fun provideEnabledWebsocketClientProvider(): WebsocketClientProvider = -// WebsocketClientProvider.KTOR_PROTOBUF -// -//} - -const val BASE_WS_HOST = "192.168.1.197" -const val BASE_WS_PORT = 8080 -const val BASE_WS_URL = "ws://$BASE_WS_HOST}:$BASE_WS_PORT" - -// Scarlet uses: -const val NODE_TRACES_WS_URL = "$BASE_WS_URL/nodes/traces" -const val NODE_ROUTES_WS_URL = "$BASE_WS_URL/nodes/routes" - -// Ktor uses: -const val NODE_TRACES_WS_PATH = "/nodes/traces" -const val NODE_ROUTES_WS_PATH = "/nodes/routes" -const val RTT_WS_PATH = "/rtt" - -enum class WebsocketClientProvider { - SCARLET_GSON, KTOR_PROTOBUF -} \ No newline at end of file diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkTrace.kt b/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkTrace.kt deleted file mode 100644 index 354bc2f..0000000 --- a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkTrace.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.architecture.network.websocket.api.model - -import com.google.gson.annotations.SerializedName -import kotlinx.serialization.Serializable - -// Example of payload -// "l": 30.52323011454044, -// "lt": 42.725705657669245, -// "s": 13, -// "az": 3.4595129834094243, -// "a": 0.1, -// "t": 1706894164046, -// "n": "bb0c326c-c1ee-11ee-b86a-d106324846e3", -// "m": 1 - -@Serializable -data class NetworkTrace( - @SerializedName("type") var type: String = "", - @SerializedName("l") var lon: Double = 0.0, - @SerializedName("lt") var lat: Double = 0.0, - @SerializedName("s") var speed: Int = 0, - @SerializedName("az") var azimuth: Double = 0.0, - @SerializedName("a") var alt: Double = 0.0, - @SerializedName("t") var sentAtTime: Long = 0, - @SerializedName("n") var nodeId: String = "", - @SerializedName("m") var mode: Int = 0 -) \ No newline at end of file diff --git a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkUpstreamRtt.kt b/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkUpstreamRtt.kt deleted file mode 100644 index be0818d..0000000 --- a/core/network/websocket/api/src/main/java/io/architecture/network/websocket/api/model/NetworkUpstreamRtt.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.architecture.network.websocket.api.model - -import com.google.gson.annotations.SerializedName -import kotlinx.serialization.Serializable - -@Serializable -data class NetworkServerTime( - @SerializedName("type") var type: String = "", - @SerializedName("clientSentTime") var clientSentTime: Long = 0, - @SerializedName("serverTime") var serverTime: Long = 0 -) - -@Serializable -data class NetworkClientTime(val time: Long) \ No newline at end of file diff --git a/core/network/websocket/imp/ktor/.gitignore b/core/network/websocket/imp/ktor/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/network/websocket/imp/ktor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/network/websocket/imp/ktor/build.gradle.kts b/core/network/websocket/imp/ktor/build.gradle.kts index d44741a..67733d4 100644 --- a/core/network/websocket/imp/ktor/build.gradle.kts +++ b/core/network/websocket/imp/ktor/build.gradle.kts @@ -1,36 +1,48 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl + plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) alias(libs.plugins.kotlin.serialize) - alias(libs.plugins.ksp) -} - -sourceSets.main { - java.srcDirs("build/generated/ksp/main/kotlin") + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { - implementation(projects.core.common) - implementation(projects.core.model) - implementation(projects.core.network.websocket.api) - implementation(projects.core.datasource.api) - implementation(projects.core.runtime.logging) - - // Koin - implementation(libs.koin.core) - ksp(libs.koin.ksp.compiler) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.common) + implementation(projects.core.model) + implementation(projects.core.network.websocket.api) + implementation(projects.core.runtime.configuration) + implementation(projects.core.datasource.api) + implementation(projects.core.runtime.logging) - // kotlinx-serialization - implementation(libs.kotlinx.serialization.json) - implementation(libs.kotlinx.serialization.protobuf) + implementation(libs.koin.core) - // Ktor for Android - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.websockets) - implementation(libs.ktor.client.serialization.jvm) - implementation(libs.ktor.serialization.kotlinx.protobuf) - implementation(libs.ktor.client.logging.jvm) + // https://ktor.io/docs/http-client-engines.html#default + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.serialization.kotlinx.protobuf) + implementation(libs.ktor.client.websockets) - testImplementation(libs.junit.junit) + implementation(libs.kotlinx.coroutine.core) + implementation(libs.kotlinx.serialization.core) + } + commonTest.dependencies { + implementation(libs.junit.junit) + } + androidMain.dependencies { + implementation(libs.ktor.client.okhttp) + } + iosMain.dependencies { + implementation(libs.ktor.client.darwin) + } + jvmMain.dependencies { + implementation(libs.ktor.client.okhttp) + } + jsMain.dependencies { + implementation(libs.ktor.client.js) + } + } } \ No newline at end of file diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorNetworkDataSource.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorNetworkDataSource.kt similarity index 100% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorNetworkDataSource.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorNetworkDataSource.kt diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorRouteService.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorRouteService.kt similarity index 100% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorRouteService.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorRouteService.kt diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorRttService.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorRttService.kt similarity index 100% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorRttService.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorRttService.kt diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorTraceService.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorTraceService.kt similarity index 100% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/KtorTraceService.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/KtorTraceService.kt diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorClientKoinModule.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorClientKoinModule.kt similarity index 63% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorClientKoinModule.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorClientKoinModule.kt index 1cedce9..59be837 100644 --- a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorClientKoinModule.kt +++ b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorClientKoinModule.kt @@ -1,10 +1,6 @@ package io.architecture.network.websocket.imp.ktor.di -import io.architecture.network.websocket.api.BASE_WS_HOST -import io.architecture.network.websocket.api.BASE_WS_PORT -import io.architecture.network.websocket.api.NODE_ROUTES_WS_PATH -import io.architecture.network.websocket.api.NODE_TRACES_WS_PATH -import io.architecture.network.websocket.api.RTT_WS_PATH +import io.architecture.core.runtime.configuration.WebsocketRuntimeConfiguration import io.architecture.network.websocket.api.model.NetworkClientTime import io.architecture.network.websocket.api.model.NetworkRoute import io.architecture.network.websocket.api.model.NetworkServerTime @@ -20,9 +16,9 @@ val ktorClientModule = module { Any::class, NetworkTrace::class, get(), - BASE_WS_HOST, - BASE_WS_PORT, - NODE_TRACES_WS_PATH + get().BASE_WS_HOST, // TODO Refactor it :) + get().BASE_WS_PORT, + get().NODE_TRACES_WS_PATH ) } @@ -31,9 +27,9 @@ val ktorClientModule = module { Any::class, NetworkRoute::class, get(), - BASE_WS_HOST, - BASE_WS_PORT, - NODE_ROUTES_WS_PATH + get().BASE_WS_HOST, + get().BASE_WS_PORT, + get().NODE_ROUTES_WS_PATH ) } @@ -42,9 +38,9 @@ val ktorClientModule = module { NetworkClientTime::class, NetworkServerTime::class, get(), - BASE_WS_HOST, - BASE_WS_PORT, - RTT_WS_PATH + get().BASE_WS_HOST, + get().BASE_WS_PORT, + get().RTT_WS_PATH ) } } \ No newline at end of file diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorKoinModule.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorKoinModule.kt similarity index 78% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorKoinModule.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorKoinModule.kt index 4d1e950..904054e 100644 --- a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorKoinModule.kt +++ b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorKoinModule.kt @@ -1,7 +1,7 @@ package io.architecture.network.websocket.imp.ktor.di import io.ktor.client.HttpClient -import io.ktor.client.engine.cio.CIO +// todo import io.ktor.client.engine.cio.CIO import io.ktor.client.plugins.logging.LogLevel import io.ktor.client.plugins.logging.Logger import io.ktor.client.plugins.logging.Logging @@ -18,7 +18,10 @@ val ktorModule = module { @OptIn(ExperimentalSerializationApi::class) single { - HttpClient(CIO) { + // NOTE: If you call the HttpClient constructor without an argument, the client will choose + // an engine automatically depending on the artifacts added in a build script. + // https://ktor.io/docs/http-client-engines.html#default + HttpClient { install(WebSockets) { contentConverter = KotlinxWebsocketSerializationConverter(ProtoBuf) diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorServiceKoinModule.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorServiceKoinModule.kt similarity index 100% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/di/KtorServiceKoinModule.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/di/KtorServiceKoinModule.kt diff --git a/core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/internal/KtorProtobufClient.kt b/core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/internal/KtorProtobufClient.kt similarity index 100% rename from core/network/websocket/imp/ktor/src/main/java/io/architecture/network/websocket/imp/ktor/internal/KtorProtobufClient.kt rename to core/network/websocket/imp/ktor/src/commonMain/kotlin/io/architecture/network/websocket/imp/ktor/internal/KtorProtobufClient.kt diff --git a/core/network/websocket/imp/scarlet/.gitignore b/core/network/websocket/imp/scarlet/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/network/websocket/imp/scarlet/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/network/websocket/imp/scarlet/build.gradle.kts b/core/network/websocket/imp/scarlet/build.gradle.kts index 90f43d5..7d436f6 100644 --- a/core/network/websocket/imp/scarlet/build.gradle.kts +++ b/core/network/websocket/imp/scarlet/build.gradle.kts @@ -10,11 +10,6 @@ android { namespace = "io.architecture.scarlet" compileSdk = libs.versions.compileSdk.get().toInt() - buildTypes { - release { - isMinifyEnabled = false - } - } libraryVariants.all { val variantName = name sourceSets { @@ -24,8 +19,8 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = libs.versions.jvmTarget.get() diff --git a/core/pool/.gitignore b/core/pool/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/pool/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/pool/build.gradle.kts b/core/pool/build.gradle.kts deleted file mode 100644 index e78dcb2..0000000 --- a/core/pool/build.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed -plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlin.android) -} - -android { - namespace = "io.architecture.core.pool" - compileSdk = libs.versions.compileSdk.get().toInt() - - defaultConfig { - jvmTarget = libs.versions.minSdk.get().toInt() - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = libs.versions.jvmTarget.get() - } -} - -dependencies { - implementation(projects.core.model) - - testImplementation(libs.junit.junit) - androidTestImplementation(libs.junit) -} \ No newline at end of file diff --git a/core/pool/src/androidTest/java/io/architecture/core/pool/ExampleInstrumentedTest.kt b/core/pool/src/androidTest/java/io/architecture/core/pool/ExampleInstrumentedTest.kt deleted file mode 100644 index e396a69..0000000 --- a/core/pool/src/androidTest/java/io/architecture/core/pool/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package io.architecture.core.pool - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("io.architecture.core.pool.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/core/pool/src/test/java/io/architecture/core/pool/ExampleUnitTest.kt b/core/pool/src/test/java/io/architecture/core/pool/ExampleUnitTest.kt deleted file mode 100644 index 79c6dae..0000000 --- a/core/pool/src/test/java/io/architecture/core/pool/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.architecture.core.pool - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/core/runtime/configuration/.gitignore b/core/runtime/configuration/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/runtime/configuration/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/runtime/configuration/build.gradle.kts b/core/runtime/configuration/build.gradle.kts index 03dea96..3e71188 100644 --- a/core/runtime/configuration/build.gradle.kts +++ b/core/runtime/configuration/build.gradle.kts @@ -1,15 +1,15 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) - alias(libs.plugins.ksp) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -sourceSets.main { - java.srcDirs("build/generated/ksp/main/kotlin") +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(libs.koin.core) + } + } + } } - -dependencies { - implementation(libs.koin.core) - implementation(libs.koin.annotations) - ksp(libs.koin.ksp.compiler) -} \ No newline at end of file diff --git a/core/runtime/configuration/src/androidMain/kotlin/io/architecture/core/runtime/configuration/Platform.android.kt b/core/runtime/configuration/src/androidMain/kotlin/io/architecture/core/runtime/configuration/Platform.android.kt new file mode 100644 index 0000000..cf53e78 --- /dev/null +++ b/core/runtime/configuration/src/androidMain/kotlin/io/architecture/core/runtime/configuration/Platform.android.kt @@ -0,0 +1,7 @@ +package io.architecture.core.runtime.configuration + +import android.os.Build + +actual val platform: IPlatform = object : IPlatform { + override val name: String = "Android ${Build.VERSION.SDK_INT}}" +} \ No newline at end of file diff --git a/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/Platform.kt b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/Platform.kt new file mode 100644 index 0000000..1a1a104 --- /dev/null +++ b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/Platform.kt @@ -0,0 +1,7 @@ +package io.architecture.core.runtime.configuration + +interface IPlatform { + val name: String +} + +expect val platform: IPlatform \ No newline at end of file diff --git a/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/Runtime.kt b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/Runtime.kt new file mode 100644 index 0000000..1c634a1 --- /dev/null +++ b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/Runtime.kt @@ -0,0 +1,7 @@ +package io.architecture.core.runtime.configuration + +data class Runtime( + val websocketConfiguration: WebsocketRuntimeConfiguration, + val platform: IPlatform, + val clientProvider: WebsocketClientProvider, +) \ No newline at end of file diff --git a/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/RuntimeKoinModule.kt b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/RuntimeKoinModule.kt new file mode 100644 index 0000000..f598611 --- /dev/null +++ b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/RuntimeKoinModule.kt @@ -0,0 +1,14 @@ +package io.architecture.core.runtime.configuration + +import org.koin.dsl.module + +val runtimeModule = module { + single { WebsocketRuntimeConfiguration() } + single { + Runtime( + get(), + platform, + WebsocketClientProvider.KTOR_PROTOBUF + ) + } +} \ No newline at end of file diff --git a/core/runtime/configuration/src/main/java/io/architecture/core/runtime/configuration/WebsocketClientProvider.kt b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/WebsocketClientProvider.kt similarity index 100% rename from core/runtime/configuration/src/main/java/io/architecture/core/runtime/configuration/WebsocketClientProvider.kt rename to core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/WebsocketClientProvider.kt diff --git a/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/WebsocketRuntimeConfiguration.kt b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/WebsocketRuntimeConfiguration.kt new file mode 100644 index 0000000..caf9386 --- /dev/null +++ b/core/runtime/configuration/src/commonMain/kotlin/io/architecture/core/runtime/configuration/WebsocketRuntimeConfiguration.kt @@ -0,0 +1,16 @@ +package io.architecture.core.runtime.configuration + +data class WebsocketRuntimeConfiguration( + val BASE_WS_HOST: String = "192.168.1.197", + val BASE_WS_PORT: Int = 8080, + val BASE_WS_URL: String = "ws://$BASE_WS_HOST}:$BASE_WS_PORT", + + // Scarlet uses: + val NODE_TRACES_WS_URL: String = "$BASE_WS_URL/nodes/traces", + val NODE_ROUTES_WS_URL: String = "$BASE_WS_URL/nodes/routes", + + // Ktor uses: + val NODE_TRACES_WS_PATH: String = "/nodes/traces", + val NODE_ROUTES_WS_PATH: String = "/nodes/routes", + val RTT_WS_PATH: String = "/rtt", +) diff --git a/core/runtime/configuration/src/iosMain/kotlin/io/architecture/core/runtime/configuration/Platform.ios.kt b/core/runtime/configuration/src/iosMain/kotlin/io/architecture/core/runtime/configuration/Platform.ios.kt new file mode 100644 index 0000000..958826d --- /dev/null +++ b/core/runtime/configuration/src/iosMain/kotlin/io/architecture/core/runtime/configuration/Platform.ios.kt @@ -0,0 +1,8 @@ +package io.architecture.core.runtime.configuration + +import platform.UIKit.UIDevice + +actual val platform: IPlatform = object : IPlatform { + override val name: String = + "Java ${UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion}" +} \ No newline at end of file diff --git a/core/runtime/configuration/src/jsMain/kotlin/io/architecture/core/runtime/configuration/Platform.jvm.kt b/core/runtime/configuration/src/jsMain/kotlin/io/architecture/core/runtime/configuration/Platform.jvm.kt new file mode 100644 index 0000000..a727f1e --- /dev/null +++ b/core/runtime/configuration/src/jsMain/kotlin/io/architecture/core/runtime/configuration/Platform.jvm.kt @@ -0,0 +1,5 @@ +package io.architecture.core.runtime.configuration + +actual val platform: IPlatform = object : IPlatform { + override val name: String = "JS browser" +} \ No newline at end of file diff --git a/core/runtime/configuration/src/jvmMain/kotlin/io/architecture/core/runtime/configuration/Platform.jvm.kt b/core/runtime/configuration/src/jvmMain/kotlin/io/architecture/core/runtime/configuration/Platform.jvm.kt new file mode 100644 index 0000000..f66690b --- /dev/null +++ b/core/runtime/configuration/src/jvmMain/kotlin/io/architecture/core/runtime/configuration/Platform.jvm.kt @@ -0,0 +1,5 @@ +package io.architecture.core.runtime.configuration + +actual val platform: IPlatform = object : IPlatform { + override val name: String = "Java ${System.getProperty("java.version")}" +} \ No newline at end of file diff --git a/core/runtime/configuration/src/main/java/io/architecture/core/runtime/configuration/RuntimeConfugurationModule.kt b/core/runtime/configuration/src/main/java/io/architecture/core/runtime/configuration/RuntimeConfugurationModule.kt deleted file mode 100644 index 2ab8593..0000000 --- a/core/runtime/configuration/src/main/java/io/architecture/core/runtime/configuration/RuntimeConfugurationModule.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.architecture.core.runtime.configuration - -import org.koin.core.annotation.ComponentScan -import org.koin.core.annotation.Module -import org.koin.core.annotation.Single - -class WebsocketRuntimeConfiguration { - val BASE_WS_HOST = "192.168.1.197" - val BASE_WS_PORT = 8080 - val BASE_WS_URL = "ws://$BASE_WS_HOST}:$BASE_WS_PORT" - - // Scarlet uses: - val NODE_TRACES_WS_URL = "$BASE_WS_URL/nodes/traces" - val NODE_ROUTES_WS_URL = "$BASE_WS_URL/nodes/routes" - - // Ktor uses: - val NODE_TRACES_WS_PATH = "/nodes/traces" - val NODE_ROUTES_WS_PATH = "/nodes/routes" - val RTT_WS_PATH = "/rtt" - - override fun toString(): String { - return BASE_WS_URL - } -} - -@Module -@ComponentScan("io.architecture.network.websocket.api") -class RuntimeConfigurationModule { - - @Single - fun websocketRuntimeConfiguration() = WebsocketRuntimeConfiguration() -} \ No newline at end of file diff --git a/core/runtime/configuration/src/wasmJsMain/kotlin/io/architecture/core/runtime/configuration/Platform.wasmJs.kt b/core/runtime/configuration/src/wasmJsMain/kotlin/io/architecture/core/runtime/configuration/Platform.wasmJs.kt new file mode 100644 index 0000000..b7d8c7c --- /dev/null +++ b/core/runtime/configuration/src/wasmJsMain/kotlin/io/architecture/core/runtime/configuration/Platform.wasmJs.kt @@ -0,0 +1,5 @@ +package io.architecture.core.runtime.configuration + +actual val platform: IPlatform = object : IPlatform { + override val name: String = "Wasm" +} \ No newline at end of file diff --git a/core/runtime/logging/.gitignore b/core/runtime/logging/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/runtime/logging/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/runtime/logging/build.gradle.kts b/core/runtime/logging/build.gradle.kts index 88da1d4..b036fff 100644 --- a/core/runtime/logging/build.gradle.kts +++ b/core/runtime/logging/build.gradle.kts @@ -1,7 +1,8 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { +kotlin { } \ No newline at end of file diff --git a/core/runtime/logging/src/main/java/io/architecture/runtime/logging/Logger.kt b/core/runtime/logging/src/commonMain/kotlin/io/architecture/runtime/logging/Logger.kt similarity index 100% rename from core/runtime/logging/src/main/java/io/architecture/runtime/logging/Logger.kt rename to core/runtime/logging/src/commonMain/kotlin/io/architecture/runtime/logging/Logger.kt diff --git a/core/runtime/metrics/.gitignore b/core/runtime/metrics/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/runtime/metrics/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/runtime/metrics/build.gradle.kts b/core/runtime/metrics/build.gradle.kts index 88da1d4..9cc591a 100644 --- a/core/runtime/metrics/build.gradle.kts +++ b/core/runtime/metrics/build.gradle.kts @@ -1,7 +1,13 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.kotlinJvm) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.convention.multiplatform.target.default) } -dependencies { +kotlin { + sourceSets { + commonMain.dependencies { + implementation(libs.koin.core) + } + } } \ No newline at end of file diff --git a/core/ui/.gitignore b/core/ui/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/core/ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index f26286c..6fa107a 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -1,30 +1,27 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed +import org.jetbrains.compose.ExperimentalComposeLibrary + plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.convention.multiplatform.target.default) } -android { - namespace = "io.architecture.ui" - compileSdk = libs.versions.compileSdk.get().toInt() +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.designsystem) + implementation(projects.core.model) + + implementation(libs.koin.core) + implementation(libs.koin.mp.compose) - buildTypes { - release { - isMinifyEnabled = false + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.ui) + @OptIn(ExperimentalComposeLibrary::class) + implementation(compose.components.resources) } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = libs.versions.jvmTarget.get() - } -} - -dependencies { - implementation(libs.androidx.coreKtx) - testImplementation(libs.junit.junit) - androidTestImplementation(libs.junit) - androidTestImplementation(libs.espresso.core) } \ No newline at end of file diff --git a/core/ui/src/commonMain/kotlin/io/architecture/ui/AlertDebugDialog.kt b/core/ui/src/commonMain/kotlin/io/architecture/ui/AlertDebugDialog.kt new file mode 100644 index 0000000..c5a845f --- /dev/null +++ b/core/ui/src/commonMain/kotlin/io/architecture/ui/AlertDebugDialog.kt @@ -0,0 +1,46 @@ +package io.architecture.ui + +import androidx.compose.material.AlertDialog +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember + +@Composable +fun showMessage(msg: String) { + val openAlertDialog = remember { mutableStateOf(true) } + when { + openAlertDialog.value -> AlertDebugDialog( + dialogText = msg, + onConfirmation = { + openAlertDialog.value = false + } + ) + } +} + +@Composable +fun AlertDebugDialog( + onConfirmation: () -> Unit, + dialogText: String, +) { + AlertDialog( + title = { + Text(text = "Debug message") + }, + text = { + Text(text = dialogText) + }, + onDismissRequest = {}, + confirmButton = { + TextButton( + onClick = { + onConfirmation() + } + ) { + Text("Confirm") + } + } + ) +} \ No newline at end of file diff --git a/feature/map/src/main/java/io/architecture/map/BottomSheet.kt b/core/ui/src/commonMain/kotlin/io/architecture/ui/NodeDetailsContent.kt similarity index 54% rename from feature/map/src/main/java/io/architecture/map/BottomSheet.kt rename to core/ui/src/commonMain/kotlin/io/architecture/ui/NodeDetailsContent.kt index 99eaf04..d60ae63 100644 --- a/feature/map/src/main/java/io/architecture/map/BottomSheet.kt +++ b/core/ui/src/commonMain/kotlin/io/architecture/ui/NodeDetailsContent.kt @@ -1,89 +1,107 @@ -package io.architecture.map +package io.architecture.ui import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text +import androidx.compose.material.LinearProgressIndicator +import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import io.architecture.core.design.system.theme.yellow_green +import io.architecture.model.Trace @Composable -fun NodeBottomSheetContent( - state: DetailsUiState, - selectedNode: String -) { +fun NodeDetailsContent(trace: Trace?) { Column( modifier = Modifier.padding(16.dp) ) { listOf( // TODO With map please :) buildAnnotatedString { append( - String.format( - "%s: %f° (reference plane is true north)", - state.lastTrace?.direction, - state.lastTrace?.azimuth, - ) + "${trace?.direction}: ${trace?.azimuth} (reference plane is true north)" ) }, buildAnnotatedString { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { append("Attitude: ") } - append(state.lastTrace?.alt.toString()) + append(trace?.alt.toString()) }, buildAnnotatedString { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { append("Speed: ") } - append("${state.lastTrace?.speed} m/s") + append("${trace?.speed} m/s") }, buildAnnotatedString { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { append("Longitude: ") } - append(state.lastTrace?.lon.toString()) + append(trace?.lon.toString()) }, buildAnnotatedString { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { append("Latitude: ") } - append(state.lastTrace?.lat.toString()) + append(trace?.lat.toString()) }, buildAnnotatedString { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { append("Sent at: ") } - append(state.lastTrace?.formattedDatetime) + append(trace?.formattedDatetime) }, buildAnnotatedString { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { append("Node ID: ") } - append(selectedNode) + append(trace?.nodeId) } ).forEach { text -> Text( text = text, + color = yellow_green, fontSize = 13.sp ) } + Spacer(modifier = Modifier.fillMaxWidth().padding(bottom = 20.dp)) } } @Composable -fun NodeBottomSheetContentEmpty() { +fun NodeDetailsEmpty() { Column( - modifier = Modifier.padding(16.dp) + modifier = Modifier + .padding(16.dp) + .height(50.dp) + .fillMaxWidth() ) { - Text( - text = "No data", - fontSize = 16.sp - ) + Row { + LinearProgressIndicator( + modifier = Modifier.fillMaxWidth() + .padding(12.dp), + color = yellow_green, + ) + } + Row { + Text( + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center, + color = yellow_green, + text = "No data available. Waiting...", + fontSize = 16.sp + ) + } } } diff --git a/core/ui/src/commonMain/kotlin/io/architecture/ui/StatusBar.kt b/core/ui/src/commonMain/kotlin/io/architecture/ui/StatusBar.kt new file mode 100644 index 0000000..e5bd4c7 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/io/architecture/ui/StatusBar.kt @@ -0,0 +1,88 @@ +package io.architecture.ui + +import androidx.compose.animation.animateColor +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.architecture.core.design.system.theme.red_state_danger +import io.architecture.core.design.system.theme.yellow_state_warning +import io.architecture.core.design.system.theme.yellow_green +import io.architecture.core.design.system.theme.yellow_green_secondary +import io.architecture.core.design.system.theme.black +import io.architecture.core.design.system.theme.teal_700 +import io.architecture.core.design.system.theme.white +import io.architecture.model.Connection + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun StatusBar(modifier: Modifier, connection: Connection, nodesCount: Int) { + val infiniteTransition = rememberInfiniteTransition(label = "infinite") + + val color by infiniteTransition.animateColor( + initialValue = yellow_green, + targetValue = yellow_green_secondary, + animationSpec = infiniteRepeatable( + animation = tween(1500, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ), + label = "color" + ) + + val bgColor = when (connection.state) { + Connection.State.UNDEFINED -> black + Connection.State.OPENED -> yellow_green + Connection.State.CLOSED -> white + Connection.State.CLOSING -> yellow_state_warning + Connection.State.FAILED -> red_state_danger + Connection.State.MESSAGE_RECEIVED -> teal_700 + else -> { + black + } + } + + val stateTraces = when (connection.state) { + Connection.State.OPENED -> "opened" + Connection.State.MESSAGE_RECEIVED -> "active" + Connection.State.CLOSING -> "closing..." + Connection.State.CLOSED -> "closed" + Connection.State.FAILED -> "FAILED!" + Connection.State.UNDEFINED -> "UNDEFINED..." + } + + val colorOnState = if (connection.state != Connection.State.OPENED) bgColor else color + val itemModifier = Modifier.padding(2.dp) + val itemTextColorStated = if (connection.state != Connection.State.UNDEFINED) black else white + FlowRow( + modifier = modifier + .drawBehind { + drawRect(colorOnState) + }, + horizontalArrangement = Arrangement.Center + ) { + listOf( + "|Nodes:$nodesCount|", + "|Connection:$stateTraces|", + "|RTT:${connection.rtt.value} ms|" + ).forEach { + Text( + modifier = itemModifier, + text = it, + color = itemTextColorStated, + fontSize = 11.sp, + ) + } + } +} \ No newline at end of file diff --git a/docs/demo/android_demo.webm b/docs/demo/android_demo.webm new file mode 100644 index 0000000..4a6e88e Binary files /dev/null and b/docs/demo/android_demo.webm differ diff --git a/docs/demo/desktop_jvm_demo.webm b/docs/demo/desktop_jvm_demo.webm new file mode 100644 index 0000000..a75fe5e Binary files /dev/null and b/docs/demo/desktop_jvm_demo.webm differ diff --git a/docs/demo/ios_demo.webm b/docs/demo/ios_demo.webm new file mode 100644 index 0000000..bd70f99 Binary files /dev/null and b/docs/demo/ios_demo.webm differ diff --git a/docs/demo/web_wasm_demo.webm b/docs/demo/web_wasm_demo.webm new file mode 100644 index 0000000..22c8f69 Binary files /dev/null and b/docs/demo/web_wasm_demo.webm differ diff --git a/feature/map/.gitignore b/feature/map/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/feature/map/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/feature/map/build.gradle.kts b/feature/map/build.gradle.kts index dddc20b..63aee54 100644 --- a/feature/map/build.gradle.kts +++ b/feature/map/build.gradle.kts @@ -1,85 +1,62 @@ -@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlin.android) - kotlin("kapt") - alias(libs.plugins.ksp) + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.convention.android.library) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.convention.multiplatform.target.default) } -android { - namespace = "io.architecture.map" - compileSdk = libs.versions.compileSdk.get().toInt() +kotlin { + sourceSets { + androidMain.dependencies { + implementation(project.dependencies.platform(libs.compose.bom)) + implementation(libs.compose.ui) + implementation(libs.androidx.animation.core.android) + implementation(libs.androidx.activityCompose) + implementation(libs.compose.uiToolingPreview) + implementation(libs.compose.uiToolingData) + implementation(libs.compose.uiTooling) + + implementation(libs.accompanist.systemuicontroller) + + implementation(libs.androidx.coreKtx) + implementation(libs.androidx.appCompat) + implementation(libs.androidx.foundation.layout.android) + implementation(libs.androidx.material3.android) + implementation(libs.androidx.lifecycle.viewmodel.ktx) + implementation(libs.androidx.lifecycle.viewmodel.savedstate) + implementation(libs.androidx.lifecycle.viewModelCompose) + implementation(libs.androidx.lifecycle.runtimeCompose) + + // Mapbox Maps SDK + implementation(libs.android) + // Note that Compose extension is compatible with Maps SDK v11.0+. + implementation(libs.maps.compose) + implementation(libs.maps.style) + + // Koin + implementation(libs.koin.android) + implementation(libs.koin.compose) + } - buildFeatures { - compose = true - } - libraryVariants.all { - val variantName = name - sourceSets { - getByName("main") { - java.srcDir(File("build/generated/ksp/$variantName/kotlin")) - } + commonMain.dependencies { + implementation(projects.core.model) + implementation(projects.core.di) + implementation(projects.core.ui) + implementation(projects.core.designsystem) + + implementation(libs.koin.core) + implementation(libs.koin.mp.compose) + + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + implementation(compose.ui) + implementation(compose.components.resources) + implementation("ca.derekellis.mapbox:compose-mapbox-library") + implementation(libs.kotlinx.datetime) } - } - buildTypes { - release { - isMinifyEnabled = false + jsMain.dependencies { + implementation(compose.html.core) } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = libs.versions.jvmTarget.get() - } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.kotlinCompilerExtensionVersion.get() - } -} - -dependencies { - implementation(projects.core.model) - implementation(projects.core.common) // TODO - implementation(projects.core.domain) - implementation(projects.core.data) - implementation(projects.core.designsystem) - - implementation(platform(libs.compose.bom)) - implementation(libs.compose.ui) - implementation(libs.androidx.animation.core.android) - implementation(libs.androidx.activityCompose) - implementation(libs.compose.uiToolingPreview) - implementation(libs.compose.uiTooling) - - implementation(libs.accompanist.systemuicontroller) - implementation(libs.lifecycle.android) - - implementation(libs.androidx.coreKtx) - implementation(libs.androidx.appCompat) - implementation(libs.androidx.foundation.layout.android) - implementation(libs.androidx.material3.android) - implementation(libs.androidx.lifecycle) - implementation(libs.androidx.lifecycleKtx) - implementation(libs.androidx.lifecycle.viewmodel.ktx) - implementation(libs.androidx.lifecycle.viewmodel.savedstate) - implementation(libs.androidx.lifecycle.viewModelCompose) - implementation(libs.androidx.lifecycle.runtimeCompose) - implementation(libs.androidx.lifecycle.service) - - // Mapbox Maps SDK - implementation(libs.android) - // Note that Compose extension is compatible with Maps SDK v11.0+. - implementation(libs.maps.compose) - implementation(libs.maps.style) - - // Koin - implementation(libs.koin.core) - implementation(libs.koin.android) - implementation(libs.koin.compose) - ksp(libs.koin.ksp.compiler) - - testImplementation(libs.junit.junit) - androidTestImplementation(libs.junit) - androidTestImplementation(libs.espresso.core) } \ No newline at end of file diff --git a/feature/map/src/main/java/io/architecture/map/MapScreen.kt b/feature/map/src/androidMain/kotlin/io/architecture/feature/common/map/MapComposable.android.kt similarity index 62% rename from feature/map/src/main/java/io/architecture/map/MapScreen.kt rename to feature/map/src/androidMain/kotlin/io/architecture/feature/common/map/MapComposable.android.kt index c7a148e..c370f7b 100644 --- a/feature/map/src/main/java/io/architecture/map/MapScreen.kt +++ b/feature/map/src/androidMain/kotlin/io/architecture/feature/common/map/MapComposable.android.kt @@ -1,22 +1,13 @@ -package io.architecture.map +package io.architecture.feature.common.map import android.util.Log import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.Scaffold -import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.mapbox.geojson.Feature import com.mapbox.geojson.FeatureCollection import com.mapbox.geojson.LineString @@ -34,88 +25,32 @@ import com.mapbox.maps.plugin.compass.generated.CompassSettings import com.mapbox.maps.plugin.gestures.addOnMapClickListener import com.mapbox.maps.plugin.gestures.generated.GesturesSettings import com.mapbox.maps.plugin.scalebar.generated.ScaleBarSettings -import com.mapbox.maps.renderer.OnFpsChangedListener -import io.architecture.map.MapBoxParams.CAMERA_INITIAL_BEARING -import io.architecture.map.MapBoxParams.CAMERA_INITIAL_PITCH -import io.architecture.map.MapBoxParams.CAMERA_INITIAL_POINT -import io.architecture.map.MapBoxParams.CAMERA_INITIAL_ZOOM +import io.architecture.model.Route import io.architecture.model.Trace import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.koin.androidx.compose.koinViewModel import kotlin.time.measureTime - -object MapBoxParams { - val CAMERA_INITIAL_POINT: Point = Point.fromLngLat(34.0828899, 44.1541579) - const val CAMERA_INITIAL_ZOOM = 4.5 - const val CAMERA_INITIAL_PITCH = 0.0 - const val CAMERA_INITIAL_BEARING = 0.0 -} - -@Composable -@OptIn(ExperimentalMaterial3Api::class) -fun MapScreen(viewModel: MapViewModel = koinViewModel()) { - val details by viewModel.detailsUiState.collectAsStateWithLifecycle() - val traces by viewModel.tracesUiState.collectAsStateWithLifecycle() - val nodesCounter by viewModel.nodeCounterUiState.collectAsStateWithLifecycle() - val connectionState by viewModel.connectionsUiState.collectAsStateWithLifecycle() - - var showBottomSheet by remember { mutableStateOf(false) } - var selectedNodeId by remember { mutableStateOf("") } - val sheetState = rememberModalBottomSheetState() - - Scaffold { contentPadding -> - MapNodesContent( - contentPadding, - traces, - details.route, - onNodeClick = { nodeId -> - selectedNodeId = nodeId - viewModel.loadDetails(nodeId) - showBottomSheet = true - } - ) { - - } - StatusBar( - modifier = Modifier - .fillMaxWidth() - .height(20.dp), - connectionState, - nodesCounter - ) - - if (showBottomSheet) { - ModalBottomSheet( - onDismissRequest = { - selectedNodeId = "" - showBottomSheet = false - viewModel.clearDetails(selectedNodeId) - }, - sheetState = sheetState - ) { - NodeBottomSheetContent(details, selectedNodeId) - } - } - } -} - @OptIn(MapboxExperimental::class) @Composable -fun MapNodesContent( +actual fun MapComposable( padding: PaddingValues, nodeTraces: Sequence, - displayRoute: io.architecture.model.Route?, + displayRoute: Route?, onNodeClick: (String) -> Unit, - onReleaseObjectFromPool: () -> Unit, ) { + val mapViewportState = rememberMapViewportState { setCameraOptions { - center(CAMERA_INITIAL_POINT) - zoom(CAMERA_INITIAL_ZOOM) - pitch(CAMERA_INITIAL_PITCH) - bearing(CAMERA_INITIAL_BEARING) + center( + Point.fromLngLat( + MapInitialState.CAMERA_INITIAL_POINT_LNG, + MapInitialState.CAMERA_INITIAL_POINT_LAT + ) + ) + zoom(MapInitialState.CAMERA_INITIAL_ZOOM) + pitch(MapInitialState.CAMERA_INITIAL_PITCH) + bearing(MapInitialState.CAMERA_INITIAL_BEARING) } } val compassSettings: CompassSettings by remember { @@ -159,22 +94,18 @@ fun MapNodesContent( } true } - OnFpsChangedListener { fps -> - Log.d("RENDER_DEBUG", "Changed FPS: $fps") - } } } MapEffect(nodeTraces) { view -> val source = view.mapboxMap.getSource(NODE_DATA_SOURCE_ID) as? GeoJsonSource - val features = mutableListOf() + val features = mutableListOf() // TODO withContext(Dispatchers.Default) { generateFeatures(nodeTraces, features, displayRoute) } val timeAddToFeatureCollection = measureTime { source?.featureCollection(FeatureCollection.fromFeatures(features)) - onReleaseObjectFromPool() } Log.d( "RENDER_DEBUG", @@ -188,7 +119,7 @@ fun MapNodesContent( private fun generateFeatures( mapOfNodes: Sequence, features: MutableList, - displayRoute: io.architecture.model.Route?, + displayRoute: Route?, ) { val timeGeneration = measureTime { mapOfNodes @@ -208,7 +139,7 @@ private fun generateFeatures( } -private fun toLineStringFeature(displayRoute: io.architecture.model.Route) = Feature.fromGeometry( +private fun toLineStringFeature(displayRoute: Route) = Feature.fromGeometry( LineString.fromLngLats(displayRoute.coordinates.map { Point.fromLngLat(it.lon, it.lat) }) diff --git a/feature/map/src/main/java/io/architecture/map/MapStyle.kt b/feature/map/src/androidMain/kotlin/io/architecture/feature/common/map/MapStyle.kt similarity index 92% rename from feature/map/src/main/java/io/architecture/map/MapStyle.kt rename to feature/map/src/androidMain/kotlin/io/architecture/feature/common/map/MapStyle.kt index eec9b4e..3fab1b9 100644 --- a/feature/map/src/main/java/io/architecture/map/MapStyle.kt +++ b/feature/map/src/androidMain/kotlin/io/architecture/feature/common/map/MapStyle.kt @@ -1,4 +1,4 @@ -package io.architecture.map +package io.architecture.feature.common.map import android.content.Context import android.graphics.Bitmap @@ -6,10 +6,8 @@ import android.graphics.Canvas import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.os.Build import androidx.annotation.ColorInt import androidx.annotation.DrawableRes -import androidx.annotation.RequiresApi import androidx.appcompat.content.res.AppCompatResources import com.mapbox.maps.Style import com.mapbox.maps.extension.style.expressions.dsl.generated.eq @@ -26,6 +24,7 @@ import com.mapbox.maps.extension.style.layers.properties.generated.TextAnchor import com.mapbox.maps.extension.style.sources.generated.geoJsonSource import com.mapbox.maps.extension.style.sources.generated.vectorSource import com.mapbox.maps.extension.style.style +import io.architecture.playground.feature.map.R private const val CIRCLE_RADIUS = 2.8 @@ -50,14 +49,13 @@ const val BEARING_KEY_PROPERTY = "bearing" private const val TERRAIN_DATA_MAPBOX_URL = "mapbox://mapbox.mapbox-terrain-v2" -fun createStyle(context: Context) = style(style = Style.LIGHT) { +fun createStyle(context: Context) = style(style = "mapbox://styles/vitaliystoyanov/cltbcw2sk016g01pieyz68hqr") { +vectorSource(TERRAIN_DATA_SOURCE_ID) { url(TERRAIN_DATA_MAPBOX_URL) } +geoJsonSource(NODE_DATA_SOURCE_ID) { buffer(0) } - +lineLayer(TERRAIN_DATA_SOURCE_ID, TERRAIN_DATA_SOURCE_ID) { sourceLayer(TERRAIN_SOURCE_LAYER_ID) lineJoin(LineJoin.ROUND) @@ -65,6 +63,7 @@ fun createStyle(context: Context) = style(style = Style.LIGHT) { lineColor(Color.parseColor("#8C3C64")) lineWidth(1.9) } + // TODO maybe resource not included in source set bitmapFromDrawableRes(context, R.drawable.triangle)?.let { +image(TRIANGLE_IMAGE_ID, it) } @@ -73,15 +72,15 @@ fun createStyle(context: Context) = style(style = Style.LIGHT) { get(MODE_KEY_PROPERTY) stop { literal(io.architecture.model.NodeMode.ACTIVE.toString()) - color(Color.GREEN) + color(Color.parseColor("#A2F854")) } stop { literal(io.architecture.model.NodeMode.INACTIVE.toString()) color(Color.RED) } - color(Color.BLACK) + color(Color.parseColor("#A2F854")) }) - circleStrokeColor(Color.BLACK) + circleStrokeColor(Color.parseColor("#A2F854")) circleStrokeWidth(1.0) circleRadius( interpolate { @@ -156,7 +155,8 @@ fun createStyle(context: Context) = style(style = Style.LIGHT) { textAnchor(TextAnchor.TOP_RIGHT) textPadding(5.0) textOptional(true) - textColor(Color.BLACK) +// textFont(listOf("UAV OSD Sans Mono")) + textColor(Color.parseColor("#A2F854")) textEmissiveStrength(10.0) textSize( interpolate { @@ -170,7 +170,7 @@ fun createStyle(context: Context) = style(style = Style.LIGHT) { } stop { literal(9) - literal(9.0) + literal(11.0) } } ) @@ -198,11 +198,9 @@ fun createStyle(context: Context) = style(style = Style.LIGHT) { } } -@RequiresApi(Build.VERSION_CODES.LOLLIPOP) private fun bitmapFromDrawableRes(context: Context, @DrawableRes resourceId: Int) = drawableToBitmap(AppCompatResources.getDrawable(context, resourceId)) -@RequiresApi(Build.VERSION_CODES.LOLLIPOP) private fun drawableToBitmap( sourceDrawable: Drawable?, flipX: Boolean = false, diff --git a/feature/map/src/androidMain/kotlin/io/architecture/map/MapScreen.kt b/feature/map/src/androidMain/kotlin/io/architecture/map/MapScreen.kt new file mode 100644 index 0000000..ddf1ac5 --- /dev/null +++ b/feature/map/src/androidMain/kotlin/io/architecture/map/MapScreen.kt @@ -0,0 +1,12 @@ +package io.architecture.map + +import androidx.compose.runtime.Composable +import org.koin.androidx.compose.koinViewModel + +@Composable +fun MapScreen(viewModel: MapViewModel = koinViewModel()) { +// val details by viewModel.detailsUiState.collectAsStateWithLifecycle() +// val traces by viewModel.tracesUiState.collectAsStateWithLifecycle() +// val nodesCounter by viewModel.nodeCounterUiState.collectAsStateWithLifecycle() +// val connectionState by viewModel.connectionsUiState.collectAsStateWithLifecycle() +} diff --git a/feature/map/src/androidMain/kotlin/io/architecture/map/MapViewModel.kt b/feature/map/src/androidMain/kotlin/io/architecture/map/MapViewModel.kt new file mode 100644 index 0000000..dcafb89 --- /dev/null +++ b/feature/map/src/androidMain/kotlin/io/architecture/map/MapViewModel.kt @@ -0,0 +1,25 @@ +package io.architecture.map + +import androidx.lifecycle.ViewModel +import io.architecture.data.repository.interfaces.NodeRepository +import io.architecture.data.repository.interfaces.RouteRepository +import io.architecture.domain.GetConnectionStateUseCase +import io.architecture.domain.GetStreamChunkedNodeWithTraceUseCase +import io.architecture.domain.GetStreamTraceByIdUseCase + + +open class MapViewModel( + private val getStreamTrace: GetStreamTraceByIdUseCase, + private val routeRepository: RouteRepository, // TODO Extract to use case + getChunkedNodeWithTrace: GetStreamChunkedNodeWithTraceUseCase, + connectionState: GetConnectionStateUseCase, + nodeRepository: NodeRepository, // TODO Extract to use case +) : ViewModel() { + val composite = MapViewModel( + getStreamTrace, + routeRepository, + getChunkedNodeWithTrace, + connectionState, + nodeRepository + ) +} \ No newline at end of file diff --git a/feature/map/src/main/res/drawable/triangle.xml b/feature/map/src/androidMain/res/drawable/triangle.xml similarity index 88% rename from feature/map/src/main/res/drawable/triangle.xml rename to feature/map/src/androidMain/res/drawable/triangle.xml index e90d0d9..50ce6b4 100644 --- a/feature/map/src/main/res/drawable/triangle.xml +++ b/feature/map/src/androidMain/res/drawable/triangle.xml @@ -5,5 +5,5 @@ android:viewportHeight="120"> + android:fillColor="#A2F854"/> diff --git a/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapComposableExpected.kt b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapComposableExpected.kt new file mode 100644 index 0000000..6016316 --- /dev/null +++ b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapComposableExpected.kt @@ -0,0 +1,14 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import io.architecture.model.Route +import io.architecture.model.Trace + +@Composable +expect fun MapComposable( + padding: PaddingValues, + nodeTraces: Sequence, + displayRoute: Route?, + onNodeClick: (String) -> Unit, +) \ No newline at end of file diff --git a/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapInitialState.kt b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapInitialState.kt new file mode 100644 index 0000000..0aad522 --- /dev/null +++ b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapInitialState.kt @@ -0,0 +1,9 @@ +package io.architecture.feature.common.map + +object MapInitialState { + const val CAMERA_INITIAL_POINT_LNG = 34.0828899 + const val CAMERA_INITIAL_POINT_LAT = 44.1541579 + const val CAMERA_INITIAL_ZOOM = 4.5 + const val CAMERA_INITIAL_PITCH = 0.0 + const val CAMERA_INITIAL_BEARING = 0.0 +} \ No newline at end of file diff --git a/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapReplacement.kt b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapReplacement.kt new file mode 100644 index 0000000..d688081 --- /dev/null +++ b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapReplacement.kt @@ -0,0 +1,57 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredHeight +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ListItem +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.architecture.core.design.system.component.AnimatedBlinkText +import io.architecture.core.design.system.theme.red_state_danger +import io.architecture.core.design.system.theme.yellow_green +import io.architecture.model.Trace + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun MapReplacement( + modifier: Modifier = Modifier, + nodeTraces: Sequence, + onNodeClick: (String) -> Unit, +) { + Column { + AnimatedBlinkText( + modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), + text = "Map not yet implemented. Provided list of latest traces:", + textAlign = TextAlign.Center, + color = red_state_danger + ) + LazyColumn( + modifier = modifier.fillMaxSize() + ) { + itemsIndexed(nodeTraces.take(20).toList()) { index, trace -> + ListItem(modifier = Modifier.requiredHeight(20.dp)) { + Text( + modifier = Modifier.clickable { + onNodeClick(trace.nodeId) + }.fillMaxWidth(), + color = yellow_green, + text = "$index: ${trace.nodeId} [${trace.lon.toString().slice(0..12)}," + + "${trace.lat.toString().slice(0..12)}]", + textAlign = TextAlign.Center, + fontSize = 12.sp + ) + } + } + } + } +} \ No newline at end of file diff --git a/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapScreen.kt b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapScreen.kt new file mode 100644 index 0000000..2a0627f --- /dev/null +++ b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapScreen.kt @@ -0,0 +1,104 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Scaffold +import androidx.compose.material3.ShapeDefaults +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import io.architecture.model.Connection +import io.architecture.model.Trace +import io.architecture.ui.NodeDetailsContent +import io.architecture.ui.NodeDetailsEmpty +import io.architecture.ui.StatusBar +import kotlinx.coroutines.flow.StateFlow +import org.koin.compose.koinInject + +@Composable +fun MapScreen() { + val viewModel = koinInject() + + // https://developer.android.com/jetpack/compose/side-effects?hl=en#remembercoroutinescope + // rememberCoroutineScope is a composable function that returns a CoroutineScope bound + // to the point of the Composition where it's called. + // The scope will be cancelled when the call leaves the Composition. + @Suppress("unused") + val scope = rememberCoroutineScope() + + with(viewModel) { + val connectionsUiState = connectionsUiState + val tracesUiState: StateFlow> = tracesUiState + + RootContent(tracesUiState, connectionsUiState) + } +} + +@Composable +fun RootContent( + tracesUiState: StateFlow>, + connectionsUiState: StateFlow, +) { + val viewModel = koinInject() // TODO ??? Danger + val detailsUiState: StateFlow = viewModel.detailsUiState + + var showBottomSheet by remember { mutableStateOf(false) } + + @OptIn(ExperimentalMaterial3Api::class) + val sheetState = rememberModalBottomSheetState() + + Scaffold { contentPadding -> + Column { + StatusBar( + modifier = Modifier + .wrapContentSize() + .fillMaxWidth() + .defaultMinSize(minHeight = 20.dp), + connectionsUiState.collectAsState().value, + tracesUiState.collectAsState().value.toList().size + ) + MapComposable( + contentPadding, + tracesUiState.value, + null, // TODO + onNodeClick = { nodeId -> + viewModel.loadUpdatableNodeDetails(nodeId) + showBottomSheet = true + } + ) + } + } + + if (showBottomSheet) { + @OptIn(ExperimentalMaterial3Api::class) + ModalBottomSheet( + sheetState = sheetState, + containerColor = Color.Transparent, + contentColor = Color.Transparent, + scrimColor = Color.Transparent, + shape = ShapeDefaults.ExtraLarge, + onDismissRequest = { + showBottomSheet = false + viewModel.stopNodeDetailsUpdates() + }, + ) { + when (val traceLatest = detailsUiState.collectAsState().value.lastTrace) { + null -> NodeDetailsEmpty() + else -> NodeDetailsContent(traceLatest) + } + } + } +} \ No newline at end of file diff --git a/feature/map/src/main/java/io/architecture/map/MapViewModel.kt b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapViewModel.kt similarity index 64% rename from feature/map/src/main/java/io/architecture/map/MapViewModel.kt rename to feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapViewModel.kt index dc8d4a2..cdca3da 100644 --- a/feature/map/src/main/java/io/architecture/map/MapViewModel.kt +++ b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/MapViewModel.kt @@ -1,87 +1,81 @@ -package io.architecture.map +package io.architecture.feature.common.map -import android.util.Log -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import io.architecture.data.repository.interfaces.NodeRepository import io.architecture.data.repository.interfaces.RouteRepository import io.architecture.domain.GetConnectionStateUseCase import io.architecture.domain.GetStreamChunkedNodeWithTraceUseCase import io.architecture.domain.GetStreamTraceByIdUseCase +import io.architecture.model.Connection import io.architecture.model.Route import io.architecture.model.Trace +import io.architecture.model.UpstreamRtt +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlin.time.Duration.Companion.seconds -data class DetailsUiState(val route: Route?, val lastTrace: Trace?) +data class NodeDetailsUiState(val route: Route?, val lastTrace: Trace?) class MapViewModel( + private val scope: CoroutineScope, private val getStreamTrace: GetStreamTraceByIdUseCase, private val routeRepository: RouteRepository, // TODO Extract to use case getChunkedNodeWithTrace: GetStreamChunkedNodeWithTraceUseCase, connectionState: GetConnectionStateUseCase, nodeRepository: NodeRepository, // TODO Extract to use case -) : ViewModel() { +) { private lateinit var job: Job - private val _displayDetails = MutableStateFlow(DetailsUiState(null, null)) + private val _displayDetails = MutableStateFlow(NodeDetailsUiState(null, null)) val connectionsUiState = connectionState() .stateIn( - scope = viewModelScope, + scope = scope, started = SharingStarted.WhileSubscribed(5_000), - initialValue = io.architecture.model.Connection( - rtt = io.architecture.model.UpstreamRtt( + initialValue = Connection( + rtt = UpstreamRtt( 0L ), isConnected = false ) ) - val detailsUiState: StateFlow = _displayDetails + val detailsUiState: StateFlow = _displayDetails .stateIn( - scope = viewModelScope, + scope = scope, started = SharingStarted.WhileSubscribed(5_000), - initialValue = DetailsUiState(null, null) + initialValue = NodeDetailsUiState(null, null) ) val nodeCounterUiState: StateFlow = nodeRepository.streamCount() .stateIn( - scope = viewModelScope, + scope = scope, started = SharingStarted.WhileSubscribed(5_000), initialValue = 0 ) val tracesUiState: StateFlow> = getChunkedNodeWithTrace(isDatabaseOutgoingStream = false, interval = 1.seconds) - .onEach { - Log.d( - "REPOSITORY_DEBUG_N", - "chunked list size of traces to sequence - ${it.count()}" - ) - } .stateIn( - scope = viewModelScope, + scope = scope, started = SharingStarted.WhileSubscribed(5_000), initialValue = emptySequence() ) - fun clearDetails(nodeId: String) { - if (job.isActive) job.cancel() + fun stopNodeDetailsUpdates() { + if (job.isActive) job.cancel() // TODO do it without cancel here in compose function } - fun loadDetails(nodeId: String) { - job = viewModelScope.launch { + fun loadUpdatableNodeDetails(nodeId: String) { + job = scope.launch { val route = routeRepository.getRouteBy(nodeId) getStreamTrace(nodeId).collect { lastTrace -> _displayDetails.update { - DetailsUiState(route, lastTrace) + NodeDetailsUiState(route, lastTrace) } } } diff --git a/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/di/MapFeatureModule.kt b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/di/MapFeatureModule.kt new file mode 100644 index 0000000..f4828a0 --- /dev/null +++ b/feature/map/src/commonMain/kotlin/io/architecture/feature/common/map/di/MapFeatureModule.kt @@ -0,0 +1,24 @@ +package io.architecture.feature.common.map.di + +import io.architecture.data.repository.interfaces.NodeRepository +import io.architecture.data.repository.interfaces.RouteRepository +import io.architecture.domain.GetConnectionStateUseCase +import io.architecture.domain.GetStreamChunkedNodeWithTraceUseCase +import io.architecture.domain.GetStreamTraceByIdUseCase +import io.architecture.feature.common.map.MapViewModel +import kotlinx.coroutines.CoroutineScope +import org.koin.core.qualifier.named +import org.koin.dsl.module + +val mapFeatureModule = module { + single { + MapViewModel( + get(named("applicationScope")), + get(), + get(), + get(), + get(), + get() + ) + } +} \ No newline at end of file diff --git a/feature/map/src/iosMain/kotlin/io/architecture/feature/common/map/MapComposable.ios.kt b/feature/map/src/iosMain/kotlin/io/architecture/feature/common/map/MapComposable.ios.kt new file mode 100644 index 0000000..7c9a9ae --- /dev/null +++ b/feature/map/src/iosMain/kotlin/io/architecture/feature/common/map/MapComposable.ios.kt @@ -0,0 +1,24 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.architecture.core.design.system.theme.black +import io.architecture.model.Route +import io.architecture.model.Trace + +@Composable +actual fun MapComposable( + padding: PaddingValues, + nodeTraces: Sequence, + displayRoute: Route?, + onNodeClick: (String) -> Unit, +) { + Box(modifier = Modifier.background(black)) { + MapReplacement(Modifier.padding(6.dp), nodeTraces, onNodeClick) + } +} \ No newline at end of file diff --git a/feature/map/src/jsMain/kotlin/io/architecture/feature/common/map/MapComposable.js.kt b/feature/map/src/jsMain/kotlin/io/architecture/feature/common/map/MapComposable.js.kt new file mode 100644 index 0000000..611d9ed --- /dev/null +++ b/feature/map/src/jsMain/kotlin/io/architecture/feature/common/map/MapComposable.js.kt @@ -0,0 +1,22 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.architecture.core.design.system.theme.black +import io.architecture.model.Route +import io.architecture.model.Trace + +@Composable +actual fun MapComposable( + padding: PaddingValues, + nodeTraces: Sequence, + displayRoute: Route?, + onNodeClick: (String) -> Unit, +) { + Box(modifier = Modifier.background(black)) { + MapReplacement(Modifier, nodeTraces, onNodeClick) + } +} \ No newline at end of file diff --git a/feature/map/src/jvmMain/kotlin/io/architecture/feature/common/map/MapComposable.jvm.kt b/feature/map/src/jvmMain/kotlin/io/architecture/feature/common/map/MapComposable.jvm.kt new file mode 100644 index 0000000..a8cfc7b --- /dev/null +++ b/feature/map/src/jvmMain/kotlin/io/architecture/feature/common/map/MapComposable.jvm.kt @@ -0,0 +1,24 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.architecture.core.design.system.theme.black +import io.architecture.model.Route +import io.architecture.model.Trace + +@Composable +actual fun MapComposable( + padding: PaddingValues, + nodeTraces: Sequence, + displayRoute: Route?, + onNodeClick: (String) -> Unit, +) { + Box(modifier = Modifier.background(black)) { + MapReplacement(Modifier.padding(6.dp),nodeTraces, onNodeClick) + } +} \ No newline at end of file diff --git a/feature/map/src/main/AndroidManifest.xml b/feature/map/src/main/AndroidManifest.xml deleted file mode 100644 index a5918e6..0000000 --- a/feature/map/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/feature/map/src/main/java/io/architecture/map/FeatureModule.kt b/feature/map/src/main/java/io/architecture/map/FeatureModule.kt deleted file mode 100644 index 7b21748..0000000 --- a/feature/map/src/main/java/io/architecture/map/FeatureModule.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.architecture.map - -import org.koin.androidx.viewmodel.dsl.viewModelOf -import org.koin.dsl.module - -val featureMapModule = module { - viewModelOf(::MapViewModel) -} \ No newline at end of file diff --git a/feature/map/src/main/java/io/architecture/map/StatusBar.kt b/feature/map/src/main/java/io/architecture/map/StatusBar.kt deleted file mode 100644 index 3c46d0e..0000000 --- a/feature/map/src/main/java/io/architecture/map/StatusBar.kt +++ /dev/null @@ -1,83 +0,0 @@ -package io.architecture.map - -import androidx.compose.animation.animateColor -import androidx.compose.animation.core.LinearEasing -import androidx.compose.animation.core.RepeatMode -import androidx.compose.animation.core.infiniteRepeatable -import androidx.compose.animation.core.rememberInfiniteTransition -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp -import com.google.accompanist.systemuicontroller.rememberSystemUiController -import io.architecture.core.design.system.theme.black -import io.architecture.core.design.system.theme.teal_700 -import io.architecture.core.design.system.theme.teal_700_dark -import io.architecture.core.design.system.theme.teal_red -import io.architecture.core.design.system.theme.white -import io.architecture.model.Connection - -@Composable -fun StatusBar(modifier: Modifier, connection: Connection, nodesCount: Int) { - val systemUiController = rememberSystemUiController() - val infiniteTransition = rememberInfiniteTransition(label = "infinite") - - val color by infiniteTransition.animateColor( - initialValue = teal_700, - targetValue = teal_700_dark, - animationSpec = infiniteRepeatable( - animation = tween(1500, easing = LinearEasing), - repeatMode = RepeatMode.Reverse - ), - label = "color" - ) - - val bgColor = when (connection.state) { - Connection.State.UNDEFINED -> black - Connection.State.OPENED -> teal_700 - Connection.State.CLOSED -> teal_red - Connection.State.CLOSING -> teal_700 - Connection.State.FAILED -> teal_red - Connection.State.MESSAGE_RECEIVED -> teal_700 - else -> { - black - } - } - - - val colorOnState = if (connection.state != Connection.State.OPENED) bgColor else color - systemUiController.setStatusBarColor(colorOnState) - Row( - modifier = modifier - .drawBehind { - drawRect(colorOnState) - }, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center - ) { - val stateTraces = when (connection.state) { - Connection.State.OPENED -> "opened" - Connection.State.MESSAGE_RECEIVED -> "active" - Connection.State.CLOSING -> "closing..." - Connection.State.CLOSED -> "closed" - Connection.State.FAILED -> "FAILED!" - Connection.State.UNDEFINED -> "initializing..." - } - - val statusText = "Nodes: $nodesCount | Connection: $stateTraces | " + - "RTT: ${connection.rtt.value} ms" - Text( - text = statusText, - color = white, - fontSize = 9.sp, - fontWeight = FontWeight.Bold - ) - } -} \ No newline at end of file diff --git a/feature/map/src/wasmJsMain/kotlin/io/architecture/feature/common/map/MapComposable.wasmJs.kt b/feature/map/src/wasmJsMain/kotlin/io/architecture/feature/common/map/MapComposable.wasmJs.kt new file mode 100644 index 0000000..7c9a9ae --- /dev/null +++ b/feature/map/src/wasmJsMain/kotlin/io/architecture/feature/common/map/MapComposable.wasmJs.kt @@ -0,0 +1,24 @@ +package io.architecture.feature.common.map + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.architecture.core.design.system.theme.black +import io.architecture.model.Route +import io.architecture.model.Trace + +@Composable +actual fun MapComposable( + padding: PaddingValues, + nodeTraces: Sequence, + displayRoute: Route?, + onNodeClick: (String) -> Unit, +) { + Box(modifier = Modifier.background(black)) { + MapReplacement(Modifier.padding(6.dp), nodeTraces, onNodeClick) + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index ec58d92..ef11286 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,6 @@ # Project-wide Gradle settings. +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. @@ -6,35 +8,45 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects org.gradle.parallel=true +# Enable caching between builds. +org.gradle.caching=true +# Not encouraged by Gradle and can produce weird results. Wait for isolated projects instead. +org.gradle.configureondemand=false # Enable configuration caching between builds. org.gradle.configuration-cache=true # This option is set because of https://github.com/google/play-services-plugins/issues/246 # to generate the Configuration Cache regardless of incompatible tasks. -# See https://github.com/android/nowinandroid/issues/1022 before using it. org.gradle.configuration-cache.problems=warn # Disable build features that are enabled by default, # https://developer.android.com/build/releases/gradle-plugin#default-changes android.defaults.buildfeatures.resvalues=false android.defaults.buildfeatures.shaders=false +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true + +#Compose +org.jetbrains.compose.experimental.wasm.enabled=true +org.jetbrains.compose.experimental.jscanvas.enabled=true + +#MPP +kotlin.mpp.stability.nowarn=true +kotlin.mpp.androidSourceSetLayoutVersion=2 +kotlin.mpp.enableCInteropCommonization=true # TODO TOKEN EXPOSE MAPBOX_DOWNLOADS_TOKEN=sk.eyJ1Ijoidml0YWxpeXN0b3lhbm92IiwiYSI6ImNscno0cXQyOTFuZXgyam82ZjA5NXFhdTAifQ.aEWDAnLIYfLJuwq5fyUKlg diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0a647f2..4b65e62 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,20 +5,32 @@ tragetSdk = "34" compileSdk = "34" kotlinCompilerExtensionVersion = "1.5.7" -jvmTarget = "1.8" +jvmTarget = "17" # Plugins -composePlugin = "1.5.12" +# [1.6.0-rc03] IOS build fails because of org.jetbrains.compose.annotation-internal:annotation dependency #4277 +# See more: https://github.com/JetBrains/compose-multiplatform/issues/4277 +# compiles IOS +composePlugin = "1.6.0-beta02" +# compiles IOS, but not WASM +#composePlugin = "1.6.0-rc03" +androidTools = "31.2.0" geojsonVersion = "0.2.1" kotlinxSerializationJsonVersion = "1.6.3" kotlinxSerializationProtobufVersion = "1.6.3" -kotlinxCoroutineAndroid = "1.7.3" +serializationVersion = "1.6.3" +kotlinxCoroutineAndroid = "1.8.0" kotlinxCoroutineCore = "1.8.0" +kotlinxDatetimeVersion = "0.5.0" +buildKonfig = "0.15.1" # ktor-server ktor = "2.3.8" logback = "1.5.0" +skikoJsWasmRuntimeVersion = "0.7.96" +skikoVersion = "0.7.96" + # Dependencies androidxActivityCompose = "1.8.2" androidxAppcompat = "1.6.1" @@ -49,7 +61,8 @@ animationCoreAndroidVersion = "1.6.1" foundationLayoutAndroidVersion = "1.6.1" material3AndroidVersion = "1.2.0" uiGraphicsAndroidVersion = "1.6.1" -ktorVersion = "2.3.8" +ktorVersion = "3.0.0-wasm2" +#ktorVersion = "2.3.8" gson = "2.10.1" lifecycleAndroidVersion = "0.1.12" loggingInterceptorVersion = "4.12.0" @@ -60,7 +73,7 @@ okhttpVersion = "4.12.0" modulegraphMermaid = "0.5.0" ksp = "1.9.21-1.0.16" -koinCore = "3.5.3" +koinCore = "3.6.0-wasm-alpha2" koinAnnotations = "1.3.1" [libraries] @@ -93,18 +106,18 @@ koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koinC koin-core-coroutine = { group = "io.insert-koin", name = "koin-core-coroutines", version.ref = "koinCore" } koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koinCore" } koin-compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koinCore" } -koin-annotations = { group = "io.insert-koin", name = "koin-annotations", version.ref = "koinAnnotations" } + +koin-mp-compose = { group = "io.insert-koin", name = "koin-compose", version.ref = "koinCore" } koin-ksp-compiler = { group = "io.insert-koin", name = "koin-ksp-compiler", version.ref = "koinAnnotations" } koin-test = { group = "io.insert-koin", name = "koin-test", version.ref = "koinCore" } koin-android-test = { group = "io.insert-koin", name = "koin-android-test", version.ref = "koinCore" } - - # Jetpack Compose compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" } compose-ui = { module = "androidx.compose.ui:ui" } compose-uiTooling = { module = "androidx.compose.ui:ui-tooling" } compose-uiToolingPreview = { module = "androidx.compose.ui:ui-tooling-preview" } +compose-uiToolingData = { module = "androidx.compose.ui:ui-tooling-data" } androidx-animation-core-android = { group = "androidx.compose.animation", name = "animation-core-android", version.ref = "animationCoreAndroidVersion" } androidx-foundation-layout-android = { group = "androidx.compose.foundation", name = "foundation-layout-android", version.ref = "foundationLayoutAndroidVersion" } androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3AndroidVersion" } @@ -118,13 +131,22 @@ kotlinx-coroutine-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines kotlinx-coroutine-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutineCore" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJsonVersion" } kotlinx-serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlinxSerializationProtobufVersion" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetimeVersion" } +kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serializationVersion" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktorVersion" } +ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorVersion" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktorVersion" } +ktor-serialization-kotlinx-protobuf = { module = "io.ktor:ktor-serialization-kotlinx-protobuf", version.ref = "ktorVersion" } +# See more https://ktor.io/docs/http-client-engines.html#limitations ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktorVersion" } -ktor-client-logging-jvm = { module = "io.ktor:ktor-client-logging-jvm", version.ref = "ktorVersion" } +ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktorVersion" } +ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktorVersion" } +ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktorVersion" } ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktorVersion" } -ktor-client-serialization-jvm = { module = "io.ktor:ktor-client-serialization-jvm", version.ref = "ktorVersion" } -ktor-serialization-kotlinx-protobuf = { module = "io.ktor:ktor-serialization-kotlinx-protobuf", version.ref = "ktorVersion" } + +skiko = { module = "org.jetbrains.skiko:skiko", version.ref = "skikoVersion" } +skiko-js-wasm-runtime = { module = "org.jetbrains.skiko:skiko-js-wasm-runtime", version.ref = "skikoJsWasmRuntimeVersion" } # Mapbox SDK android = { module = "com.mapbox.maps:android", version.ref = "mapBox" } @@ -132,7 +154,7 @@ maps-compose = { module = "com.mapbox.extension:maps-compose", version.ref = "ma maps-style = { module = "com.mapbox.extension:maps-style", version.ref = "mapsStyleVersion" } # Tinder scarlet & OkHTTP -lifecycle-android = { module = "com.tinder.scarlet:lifecycle-android", version.ref = "lifecycleAndroidVersion" } +scarlet-lifecycle-android = { module = "com.tinder.scarlet:lifecycle-android", version.ref = "lifecycleAndroidVersion" } message-adapter-gson = { module = "com.tinder.scarlet:message-adapter-gson", version.ref = "sarletMessageAdapterVersion" } message-adapter-protobuf = { module = "com.tinder.scarlet:message-adapter-protobuf", version.ref = "sarletMessageAdapterVersion" } scarlet = { module = "com.tinder.scarlet:scarlet", version.ref = "scarletVersion" } @@ -156,6 +178,13 @@ ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "kto ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" } ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" } +# Dependencies of the included build-logic +android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" } +android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } +kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } +ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } +room-gradlePlugin = { group = "androidx.room", name = "room-gradle-plugin", version.ref = "roomKtxVersion" } + [bundles] [plugins] @@ -167,6 +196,14 @@ kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-serialize = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } modulegraph = { id = "dev.iurysouza.modulegraph", version.ref = "modulegraphMermaid" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +buildKonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildKonfig" } +kotlinCocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" } + +# Plugins of build-logic +convention-android-library = { id = "io.architecture.android.library", version = "unspecified" } +convention-multiplatform-target-default = { id = "io.architecture.multiplatform.target.preset.default", version = "unspecified" } + + # Common kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock new file mode 100644 index 0000000..89522cf --- /dev/null +++ b/kotlin-js-store/yarn.lock @@ -0,0 +1,3185 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.22" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz#72a621e5de59f5f1ef792d0793a82ee20f645e4c" + integrity sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@js-joda/core@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" + integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@mapbox/geojson-rewind@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz#591a5d71a9cd1da1a0bf3420b3bea31b0fc7946a" + integrity sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA== + dependencies: + get-stream "^6.0.1" + minimist "^1.2.6" + +"@mapbox/jsonlint-lines-primitives@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234" + integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ== + +"@mapbox/mapbox-gl-supported@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz#c15367178d8bfe4765e6b47b542fe821ce259c7b" + integrity sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ== + +"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" + integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ== + +"@mapbox/tiny-sdf@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz#9a1d33e5018093e88f6a4df2343e886056287282" + integrity sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA== + +"@mapbox/unitbezier@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz#d32deb66c7177e9e9dfc3bbd697083e2e657ff01" + integrity sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw== + +"@mapbox/vector-tile@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666" + integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw== + dependencies: + "@mapbox/point-geometry" "~0.1.0" + +"@mapbox/whoots-js@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" + integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== + +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.17" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b" + integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.56.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.2.tgz#1c72a9b794aa26a8b94ad26d5b9aa51c8a6384bb" + integrity sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.43" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54" + integrity sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/http-proxy@^1.17.8": + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/mime@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@>=10.0.0": + version "20.11.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.20.tgz#f0a2aee575215149a62784210ad88b3a34843659" + integrity sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg== + dependencies: + undici-types "~5.26.4" + +"@types/qs@*": + version "6.9.11" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" + integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.1": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" + integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== + +"@webpack-cli/info@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" + integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== + +"@webpack-cli/serve@^2.0.3": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" + integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.7.1, acorn@^8.8.2: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@^1.19.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02" + integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw== + dependencies: + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.23.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + dependencies: + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001587: + version "1.0.30001589" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz#7ad6dba4c9bf6561aec8291976402339dc157dfb" + integrity sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^3.5.1, chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.3.tgz#1e8799f3ccc5874fdd55461af51137fcc5befbcd" + integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.19" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +csscolorparser@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" + integrity sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + +date-format@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" + integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.4, debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-data-property@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dns-packet@^5.2.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +earcut@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" + integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.668: + version "1.4.680" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.680.tgz#18a30d3f557993eda2d5b1e21a06c4d51875392f" + integrity sha512-4nToZ5jlPO14W82NkF32wyjhYqQByVaDmLy4J2/tYcAbJfgO2TKJC780Az1V13gzq4l73CJ0yuyalpXvxXXD9A== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +engine.io-parser@~5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.2.tgz#37b48e2d23116919a3453738c5720455e64e1c49" + integrity sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw== + +engine.io@~6.5.2: + version "6.5.4" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.5.4.tgz#6822debf324e781add2254e912f8568508850cdc" + integrity sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.11.0" + +enhanced-resolve@^5.13.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + +envinfo@^7.7.3: + version "7.11.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.1.tgz#2ffef77591057081b0129a8fd8cf6118da1b94e1" + integrity sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg== + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-module-lexer@^1.2.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" + integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== + +escalade@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.7: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + +follow-redirects@^1.0.0: + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== + +format-util@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-monkey@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" + integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +geojson-vt@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.2.1.tgz#f8adb614d2c1d3f6ee7c4265cad4bbf3ad60c8b7" + integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +gl-matrix@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" + integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +grid-index@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7" + integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.1.tgz#26f48f039de2c0f8d3356c223fb8d50253519faa" + integrity sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA== + dependencies: + function-bind "^1.1.2" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" + integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.12: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz#eb9c95024f2d6dfbb3748d3415ac9b381906b9a9" + integrity sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q== + dependencies: + which "^1.2.1" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +karma-sourcemap-loader@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== + dependencies: + graceful-fs "^4.2.10" + +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.2.tgz#a983f874cee6f35990c4b2dcc3d274653714de8e" + integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kdbush@^4.0.1, kdbush@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39" + integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA== + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +launch-editor@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" + integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.8.1" + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.4.1: + version "6.9.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.9.1.tgz#aba5a3ff4e7872ae34f8b4c533706753709e38b6" + integrity sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + flatted "^3.2.7" + rfdc "^1.3.0" + streamroller "^3.1.5" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +mapbox-gl@2.15.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-2.15.0.tgz#9439828d0bae1e7b464ae08b30cb2e65a7e2256d" + integrity sha512-fjv+aYrd5TIHiL7wRa+W7KjtUqKWziJMZUkK5hm8TvJ3OLeNPx4NmW/DgfYhd/jHej8wWL+QJBDbdMMAKvNC0A== + dependencies: + "@mapbox/geojson-rewind" "^0.5.2" + "@mapbox/jsonlint-lines-primitives" "^2.0.2" + "@mapbox/mapbox-gl-supported" "^2.0.1" + "@mapbox/point-geometry" "^0.1.0" + "@mapbox/tiny-sdf" "^2.0.6" + "@mapbox/unitbezier" "^0.0.1" + "@mapbox/vector-tile" "^1.3.1" + "@mapbox/whoots-js" "^3.1.0" + csscolorparser "~1.0.3" + earcut "^2.2.4" + geojson-vt "^3.2.1" + gl-matrix "^3.4.3" + grid-index "^1.1.0" + kdbush "^4.0.1" + murmurhash-js "^1.0.0" + pbf "^3.2.1" + potpack "^2.0.0" + quickselect "^2.0.0" + rw "^1.3.3" + supercluster "^8.0.0" + tinyqueue "^2.0.3" + vt-pbf "^3.1.3" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.3, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +murmurhash-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" + integrity sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +pbf@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.2.1.tgz#b4c1b9e72af966cd82c6531691115cc0409ffe2a" + integrity sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ== + dependencies: + ieee754 "^1.1.12" + resolve-protobuf-schema "^2.1.0" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz#7cbed92abd312b94aaea85b68226d3dec39a14e6" + integrity sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz#32cfab55e84887c079a19bbb215e721d683ef134" + integrity sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.15" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" + integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.19: + version "8.4.35" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7" + integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +potpack@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/potpack/-/potpack-2.0.0.tgz#61f4dd2dc4b3d5e996e3698c0ec9426d0e169104" + integrity sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +protocol-buffers-schema@^3.3.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03" + integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +quickselect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-protobuf-schema@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758" + integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ== + dependencies: + protocol-buffers-schema "^3.3.1" + +resolve@^1.20.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +rfdc@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" + integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rw@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.1, schema-utils@^3.1.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + +semver@^7.3.8: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425" + integrity sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g== + dependencies: + define-data-property "^1.1.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.1" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + +side-channel@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.5.tgz#9a84546599b48909fb6af1211708d23b1946221b" + integrity sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +socket.io-adapter@~2.5.2: + version "2.5.4" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz#4fdb1358667f6d68f25343353bd99bd11ee41006" + integrity sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg== + dependencies: + debug "~4.3.4" + ws "~8.11.0" + +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@^4.4.1: + version "4.7.4" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.7.4.tgz#2401a2d7101e4bdc64da80b140d5d8b6a8c7738b" + integrity sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + cors "~2.8.5" + debug "~4.3.2" + engine.io "~6.5.2" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.1.tgz#72f00d05f5d1f90f80974eda781cbd7107c125f2" + integrity sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA== + dependencies: + abab "^2.0.6" + iconv-lite "^0.6.3" + source-map-js "^1.0.2" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +streamroller@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.5.tgz#1263182329a45def1ffaef58d31b15d13d2ee7ff" + integrity sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + fs-extra "^8.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.2.tgz#eaebca714d9e462c19aa1e3599057bc363924899" + integrity sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw== + +supercluster@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-8.0.1.tgz#9946ba123538e9e9ab15de472531f604e7372df5" + integrity sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ== + dependencies: + kdbush "^4.0.2" + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.3.7: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.20" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" + +terser@^5.26.0: + version "5.27.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.27.2.tgz#577a362515ff5635f98ba149643793a3973ba77e" + integrity sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tinyqueue@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08" + integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA== + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + +ua-parser-js@^0.7.30: + version "0.7.37" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz#e464e66dac2d33a7a1251d7d7a99d6157ec27832" + integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + +vt-pbf@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" + integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== + dependencies: + "@mapbox/point-geometry" "0.1.0" + "@mapbox/vector-tile" "^1.3.1" + pbf "^3.2.1" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +webpack-cli@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.0.tgz#abc4b1f44b50250f2632d8b8b536cfe2f6257891" + integrity sha512-a7KRJnCxejFoDpYTOwzm5o21ZXMaNqtRlvS183XzGDUPRdVEzJNImcQokqYZ8BNTnk9DkKiuWxw75+DCCoZ26w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^2.1.0" + "@webpack-cli/info" "^2.0.1" + "@webpack-cli/serve" "^2.0.3" + colorette "^2.0.14" + commander "^10.0.1" + cross-spawn "^7.0.3" + envinfo "^7.7.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^3.1.1" + rechoir "^0.8.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.15.0: + version "4.15.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz#87ba9006eca53c551607ea0d663f4ae88be7af21" + integrity sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.13.0" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^5.7.3: + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@5.82.0: + version "5.82.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.82.0.tgz#3c0d074dec79401db026b4ba0fb23d6333f88e7d" + integrity sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.13.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + +ws@^8.13.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/mapbox.properties b/mapbox.properties new file mode 100644 index 0000000..9d2e119 --- /dev/null +++ b/mapbox.properties @@ -0,0 +1 @@ +MAPBOX_ACCESS_TOKEN=pk.eyJ1Ijoidml0YWxpeXN0b3lhbm92IiwiYSI6ImNscno0am9sNDFzM3gyanRla3RzOHlldmIifQ.y1u16gHUgyf1sOLNYNAdPQ \ No newline at end of file diff --git a/microbenchmark/.gitignore b/microbenchmark/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/microbenchmark/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/microbenchmark/build.gradle.kts b/microbenchmark/build.gradle.kts index 4df26d9..0d08e87 100644 --- a/microbenchmark/build.gradle.kts +++ b/microbenchmark/build.gradle.kts @@ -10,8 +10,8 @@ android { compileSdk = libs.versions.compileSdk.get().toInt() compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { diff --git a/settings.gradle.kts b/settings.gradle.kts index c23a4cf..96a43c8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,19 +2,21 @@ rootProject.name = "node_traces_streaming" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { + includeBuild("build-logic") repositories { + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") google() - mavenCentral() gradlePluginPortal() + mavenCentral() } } dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() - + // https://youtrack.jetbrains.com/issue/KTOR-5587/Ktor-client-for-Kotlin-Wasm#focus=Comments-27-8735419.0-0 + maven("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental") // Mapbox Maven repository maven { url = uri("https://api.mapbox.com/downloads/v2/releases/maven") @@ -24,11 +26,26 @@ dependencyResolutionManagement { credentials.password = providers.gradleProperty("MAPBOX_DOWNLOADS_TOKEN").get() authentication.create("basic") } - + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } } + include(":ktor-server-app") -include(":compose-app") +// See more: https://docs.gradle.org/current/userguide/composite_builds.html +// and Declaring dependencies substituted by an included build: +// https://docs.gradle.org/current/userguide/composite_builds.html#included_build_declaring_substitutions +includeBuild("compose-mapbox-library") { + dependencySubstitution { + substitute(module("ca.derekellis.mapbox:compose-mapbox-library")).using(project(":")) + } +} +includeBuild(".") + +include(":compose-android-app") +include(":compose-desktop-app") +include(":compose-ios-app:shared") +include(":compose-web-js-wasm-app") +include(":compose-web-wasm-app") include(":core:common") include(":core:model") @@ -47,5 +64,4 @@ include(":core:runtime:logging") include(":core:runtime:metrics") include(":core:ui") -include(":feature:map") - +include(":feature:map") \ No newline at end of file