1 Commits

Author SHA1 Message Date
Renovate Bot
7e3173f4cc Update dependency @turf/turf to v7.3.4 2026-02-13 02:01:13 +00:00
20 changed files with 2775 additions and 4702 deletions

View File

@@ -32,6 +32,7 @@ jobs:
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch keystore.asc > app/keystore.properties gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch keystore.asc > app/keystore.properties
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch key.asc > app/key.jks gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch key.asc > app/key.jks
- uses: gradle/wrapper-validation-action@v3
- name: create and checkout branch - name: create and checkout branch
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
@@ -42,17 +43,15 @@ jobs:
- name: set up JDK - name: set up JDK
uses: actions/setup-java@v5 uses: actions/setup-java@v5
with: with:
java-version: 21 java-version: 17
distribution: "temurin" distribution: "temurin"
cache: 'gradle'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v6
- name: Build APK - name: Build APK
run: ./gradlew assembleSignedRelease run: ./gradlew assembleSignedRelease
- name: Release - name: Release
uses: softprops/action-gh-release@v3 uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
with: with:
files: | files: |

View File

@@ -1,38 +1,27 @@
def getCommitCount() {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', '--count', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim().toInteger()
} catch (ignored) {
return 1
}
}
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.21' id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.compose' version '2.3.21' id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.10'
id 'com.mikepenz.aboutlibraries.plugin' version '14.2.0' id 'org.jetbrains.kotlin.plugin.compose' version '2.3.10'
id 'com.mikepenz.aboutlibraries.plugin' version '13.2.1'
} }
android { android {
namespace 'net.helcel.beans' namespace 'net.helcel.beans'
compileSdk = 37 compileSdk 36
defaultConfig { defaultConfig {
buildConfigField("String", "APP_NAME", "\"Beans\"") buildConfigField("String", "APP_NAME", "\"Beans\"")
manifestPlaceholders["APP_NAME"] = "Beans" manifestPlaceholders["APP_NAME"] = "Beans"
applicationId 'net.helcel.beans' applicationId 'net.helcel.beans'
minSdk = 28 minSdk 28
targetSdk = 37 targetSdk 36
versionName "1.2" versionCode 4
versionCode getCommitCount() versionName "1.1a"
} }
signingConfigs { signingConfigs {
register("release") { create("release") {
try { try {
def keystorePropertiesFile = rootProject.file("app/keystore.properties") def keystorePropertiesFile = rootProject.file("app/keystore.properties")
def keystoreProperties = new Properties() def keystoreProperties = new Properties()
@@ -47,18 +36,20 @@ android {
} }
} }
} }
buildTypes { buildTypes {
debug { debug {
debuggable true debuggable true
} }
release { release {
minifyEnabled true minifyEnabled true
shrinkResources true shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
signedRelease { signedRelease {
minifyEnabled true minifyEnabled true
shrinkResources true shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig = signingConfigs.getByName("release") signingConfig = signingConfigs.getByName("release")
} }
@@ -87,6 +78,10 @@ android {
kotlinCompilerExtensionVersion = "2.2.20" kotlinCompilerExtensionVersion = "2.2.20"
} }
kotlin {
jvmToolchain(21)
}
lint { lint {
disable 'UsingMaterialAndMaterial3Libraries' disable 'UsingMaterialAndMaterial3Libraries'
} }
@@ -96,33 +91,34 @@ aboutLibraries {
library { library {
exclusionPatterns = [~"androidx.*", ~"com.google.android.*", ~"org.jetbrains.*"] exclusionPatterns = [~"androidx.*", ~"com.google.android.*", ~"org.jetbrains.*"]
} }
excludeFields = ["generated"]
} }
dependencies { dependencies {
implementation 'androidx.compose.material3:material3:1.4.0' implementation 'androidx.compose.material3:material3:1.4.0'
implementation "androidx.compose.material:material:1.11.2" implementation "androidx.compose.material:material:1.10.3"
implementation 'androidx.compose.material:material-icons-extended:1.7.8' implementation 'androidx.compose.material:material-icons-extended:1.7.8'
implementation 'androidx.navigation:navigation-compose:2.9.8' implementation 'androidx.navigation:navigation-compose:2.9.7'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.1.5' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.1.5'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0'
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui'
implementation "androidx.activity:activity-ktx:1.13.0" implementation "androidx.activity:activity-ktx:1.12.4"
implementation 'androidx.compose.ui:ui-tooling-preview' implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'com.google.android.material:material:1.14.0' implementation 'com.google.android.material:material:1.13.0'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0'
implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.caverock:androidsvg-aar:1.4'
implementation 'com.github.chrisbanes:PhotoView:2.3.0' implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.mikepenz:aboutlibraries:14.2.0' implementation 'com.mikepenz:aboutlibraries:13.2.1'
implementation 'com.mikepenz:aboutlibraries-compose-m3:14.2.0' implementation 'com.mikepenz:aboutlibraries-compose-m3:13.2.1'
implementation 'com.mikepenz:aboutlibraries-core:14.2.0' implementation 'com.mikepenz:aboutlibraries-core:13.2.1'
implementation platform('androidx.compose:compose-bom:2026.05.01') implementation platform('androidx.compose:compose-bom:2026.01.01')
debugImplementation 'androidx.compose.ui:ui-tooling:1.11.2' debugImplementation 'androidx.compose.ui:ui-tooling:1.10.2'
} }

View File

@@ -8,7 +8,8 @@
android:hardwareAccelerated="false" android:hardwareAccelerated="false"
android:icon="@mipmap/ic_launcher_round" android:icon="@mipmap/ic_launcher_round"
android:label="${APP_NAME}" android:label="${APP_NAME}"
android:supportsRtl="true"> android:supportsRtl="true"
tools:replace="android:allowBackup">
<activity <activity
android:name=".activity.MainScreen" android:name=".activity.MainScreen"
android:exported="true"> android:exported="true">

View File

@@ -16,6 +16,7 @@ import androidx.compose.material.Scaffold
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.TopAppBar import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.DateRange
import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Percent import androidx.compose.material.icons.filled.Percent
import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Settings

View File

@@ -152,17 +152,11 @@ fun SettingsMainScreen(onExit: ()->Unit = {}) {
fun SettingsScreen(navController: NavHostController = settingsNav()) { fun SettingsScreen(navController: NavHostController = settingsNav()) {
val context = LocalContext.current val context = LocalContext.current
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val keyTheme = stringResource(R.string.key_theme)
val defaultTheme = stringResource(R.string.system)
val keyProjection = stringResource(R.string.key_projection)
val keyGroup = stringResource(R.string.key_group)
val offString = stringResource(R.string.off)
var showEdit by remember { mutableStateOf(false) } var showEdit by remember { mutableStateOf(false) }
var theme by remember { mutableStateOf(prefs.getString(keyTheme, defaultTheme)!!) } var theme by remember { mutableStateOf(prefs.getString(context.getString(R.string.key_theme), context.getString(R.string.system))!!) }
var projection by remember { mutableStateOf(prefs.getString(keyProjection, "default")!!) } var projection by remember { mutableStateOf(prefs.getString(context.getString(R.string.key_projection), "default")!!) }
var groups by remember { mutableStateOf(prefs.getString(keyGroup,offString)!!) } var groups by remember { mutableStateOf(prefs.getString(context.getString(R.string.key_group), context.getString(R.string.off))!!) }
if(showEdit) if(showEdit)
EditPlaceDialog(true) { EditPlaceDialog(true) {
@@ -185,7 +179,7 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
) )
MultiPreference(arrayOf(stringResource(R.string.system),stringResource(R.string.light),stringResource(R.string.dark)), theme) { newTheme -> MultiPreference(arrayOf(stringResource(R.string.system),stringResource(R.string.light),stringResource(R.string.dark)), theme) { newTheme ->
theme = newTheme theme = newTheme
prefs.edit { putString(keyTheme, newTheme) } prefs.edit { putString(context.getString(R.string.key_theme), newTheme) }
} }
HorizontalDivider() HorizontalDivider()
} }
@@ -198,7 +192,7 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
) )
MultiPreference(arrayOf(stringResource(R.string.mercator), stringResource(R.string.azimuthalequidistant)), projection) { newProj -> MultiPreference(arrayOf(stringResource(R.string.mercator), stringResource(R.string.azimuthalequidistant)), projection) { newProj ->
projection = newProj projection = newProj
prefs.edit { putString(keyProjection, newProj) } prefs.edit { putString(context.getString(R.string.key_projection), newProj) }
Settings.refreshProjection() Settings.refreshProjection()
} }
HorizontalDivider() HorizontalDivider()
@@ -225,11 +219,11 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
arrayOf(stringResource(R.string.on), stringResource(R.string.off)), arrayOf(stringResource(R.string.on), stringResource(R.string.off)),
groups groups
) { key -> ) { key ->
if (key == offString) { if (key == context.getString(R.string.off)) {
showDialog=true showDialog=true
} }
groups = key groups = key
prefs.edit { putString(keyGroup, key) } prefs.edit { putString(context.getString(R.string.key_group), key) }
} }
HorizontalDivider() HorizontalDivider()
} }
@@ -289,13 +283,9 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
@Composable @Composable
fun RegionalScreen() { fun RegionalScreen() {
val context = LocalContext.current val context = LocalContext.current
val keyRegional = stringResource(R.string.key_regional)
val offString = stringResource(R.string.off)
val onString = stringResource(R.string.on)
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
var selected by remember { mutableStateOf(prefs.getString(keyRegional, offString)!!)} var selected by remember { mutableStateOf(prefs.getString(context.getString(R.string.key_regional),context.getString(R.string.off))!!)}
var regional by remember{ mutableStateOf(prefs.getString(keyRegional, offString)!!)} var regional by remember{ mutableStateOf(prefs.getString(context.getString(R.string.key_regional), context.getString(R.string.off))!!)}
var showDialog by remember{mutableStateOf(false)} var showDialog by remember{mutableStateOf(false)}
var showLoad by remember{mutableStateOf(false)} var showLoad by remember{mutableStateOf(false)}
@@ -315,7 +305,7 @@ fun RegionalScreen() {
regional= selected regional= selected
prefs.edit { prefs.edit {
putString( putString(
keyRegional, context.getString(R.string.key_regional),
regional regional
) )
} }
@@ -342,12 +332,12 @@ fun RegionalScreen() {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
MultiPreference(arrayOf(stringResource(R.string.on),stringResource(R.string.off)),regional) { key -> MultiPreference(arrayOf(stringResource(R.string.on),stringResource(R.string.off)),regional) { key ->
when (key) { when (key) {
offString -> { showDialog=true context.getString(R.string.off) -> { showDialog=true
selected=key selected=key
} }
onString -> { context.getString(R.string.on) -> {
regional = key regional = key
prefs.edit { putString(keyRegional, key) } prefs.edit { putString(context.getString(R.string.key_regional), key) }
showLoad=true showLoad=true
scope.launch { scope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
@@ -364,7 +354,7 @@ fun RegionalScreen() {
@Composable @Composable
fun MultiPreference(list: Array<String>, selected: String, onSelected: (String) -> Unit) { fun MultiPreference(list: Array<String>, selected: String, onSelected: (String) -> Unit) {
Column(Modifier.padding(2.dp)) { Column(Modifier.padding(2.dp)) {
list.forEach { value -> list.map { value ->
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier modifier = Modifier

View File

@@ -115,6 +115,7 @@ fun StatsList(activeMode: LocType, countMode: Boolean) {
@Composable @Composable
fun StatsRow(group: Groups.Group, activeMode: LocType, countMode: Boolean) { fun StatsRow(group: Groups.Group, activeMode: LocType, countMode: Boolean) {
val context = LocalContext.current
val visited = remember(group, activeMode) { val visited = remember(group, activeMode) {
Data.visits.getVisitedByValue(group.key) Data.visits.getVisitedByValue(group.key)
@@ -123,18 +124,18 @@ fun StatsRow(group: Groups.Group, activeMode: LocType, countMode: Boolean) {
val count = when (activeMode) { val count = when (activeMode) {
LocType.WORLD -> World.WWW.children.filter { it.code in visited }.size LocType.WORLD -> World.WWW.children.filter { it.code in visited }.size
LocType.COUNTRY -> World.WWW.children.flatMap { it.children.filter { c -> c.code in visited } }.size LocType.COUNTRY -> World.WWW.children.flatMap { it.children.filter { c -> c.code in visited } }.size
LocType.STATE -> World.WWW.children.flatMap { a->a.children.flatMap { b->b.children.filter { c->c.code in visited } } }.size LocType.STATE -> World.WWW.children.flatMap { itc->itc.children.flatMap { it.children.filter { it.code in visited } } }.size
else -> 0 else -> 0
} }
val area = when (activeMode) { val area = when (activeMode) {
LocType.WORLD -> World.WWW.children.filter { it.code in visited }.sumOf { it.area } LocType.WORLD -> World.WWW.children.filter { it.code in visited }.sumOf { it.area }
LocType.COUNTRY -> World.WWW.children.flatMap { it.children.filter { c -> c.code in visited } }.sumOf { it.area } LocType.COUNTRY -> World.WWW.children.flatMap { it.children.filter { c -> c.code in visited } }.sumOf { it.area }
LocType.STATE -> World.WWW.children.flatMap { a->a.children.flatMap { b->b.children.filter { c->c.code in visited } } }.sumOf { it.area } LocType.STATE -> World.WWW.children.flatMap { it.children.flatMap { it.children.filter { it.code in visited } } }.sumOf { it.area }
else -> 0 else -> 0
} }
val displayValue = if (countMode) count.toString() else stringResource(R.string.number_with_unit, area, "km²") val displayValue = if (countMode) count.toString() else context.getString(R.string.number_with_unit, area, "km²")
val backgroundColor = group.color.color val backgroundColor = group.color.color
val textColor = getContrastColor(backgroundColor) val textColor = getContrastColor(backgroundColor)

View File

@@ -58,7 +58,7 @@ fun syncVisited(loc: GeoLoc?=World.WWW){
loc?.children?.forEach { tt -> loc?.children?.forEach { tt ->
tt.children.forEach {itc-> tt.children.forEach {itc->
if(Data.visits.getVisited(itc) in listOf(AUTO_GROUP,NO_GROUP)) { if(Data.visits.getVisited(itc) in listOf(AUTO_GROUP,NO_GROUP)) {
if(itc.children.any { c -> Data.visits.getVisited(c) != NO_GROUP }) if(itc.children.any { itcc -> Data.visits.getVisited(itcc) != NO_GROUP })
Data.visits.setVisited(itc, AUTO_GROUP) Data.visits.setVisited(itc, AUTO_GROUP)
else else
Data.visits.setVisited(itc, NO_GROUP) Data.visits.setVisited(itc, NO_GROUP)
@@ -111,20 +111,21 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
Column { Column {
val currentTab = tabs.getOrNull(selectedTab) ?: return@Column val currentTab = tabs.getOrNull(selectedTab) ?: return@Column
TabRow( TabRow(
selectedTabIndex = min(tabs.lastIndex, selectedTab), selectedTabIndex = min(tabs.lastIndex, selectedTab),
) { ) {
tabs.forEachIndexed { index, tab -> tabs.forEachIndexed { index, tab ->
Tab( Tab(
selected = selectedTab == index, selected = selectedTab == index,
onClick = { onClick = {
while (tabs.size > index + 1) while (tabs.size > index + 1)
tabs.removeAt(tabs.lastIndex) tabs.removeAt(tabs.lastIndex)
}, },
text = { Text(tab.fullName) } text = { Text(tab.fullName) }
) )
}
} }
}
LazyColumn( LazyColumn(
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()

View File

@@ -7,7 +7,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.mikepenz.aboutlibraries.ui.compose.DefaultChipColors import com.mikepenz.aboutlibraries.ui.compose.DefaultChipColors
import com.mikepenz.aboutlibraries.ui.compose.DefaultLibraryColors import com.mikepenz.aboutlibraries.ui.compose.DefaultLibraryColors
import com.mikepenz.aboutlibraries.ui.compose.android.produceLibraries import com.mikepenz.aboutlibraries.ui.compose.android.rememberLibraries
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import net.helcel.beans.R import net.helcel.beans.R
import net.helcel.beans.activity.SysTheme import net.helcel.beans.activity.SysTheme
@@ -16,14 +16,14 @@ import net.helcel.beans.activity.SysTheme
@Preview @Preview
@Composable @Composable
fun LicenseScreen() { fun LicenseScreen() {
val libraries = produceLibraries(R.raw.aboutlibraries) val libraries = rememberLibraries(R.raw.aboutlibraries)
SysTheme { SysTheme {
LibrariesContainer( LibrariesContainer(
libraries = libraries.value, libraries = libraries.value,
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
colors = DefaultLibraryColors( colors = DefaultLibraryColors(
libraryBackgroundColor = MaterialTheme.colors.background, backgroundColor = MaterialTheme.colors.background,
libraryContentColor = MaterialTheme.colors.onBackground, contentColor = MaterialTheme.colors.onBackground,
licenseChipColors = DefaultChipColors( licenseChipColors = DefaultChipColors(
containerColor = MaterialTheme.colors.primary, containerColor = MaterialTheme.colors.primary,
contentColor = MaterialTheme.colors.onPrimary, contentColor = MaterialTheme.colors.onPrimary,
@@ -37,8 +37,6 @@ fun LicenseScreen() {
contentColor = MaterialTheme.colors.onSecondary, contentColor = MaterialTheme.colors.onSecondary,
), ),
dialogConfirmButtonColor = MaterialTheme.colors.primary, dialogConfirmButtonColor = MaterialTheme.colors.primary,
dialogBackgroundColor = MaterialTheme.colors.onPrimary,
dialogContentColor = MaterialTheme.colors.primary,
) )
) )
} }

View File

@@ -2,7 +2,6 @@ package net.helcel.beans.countries
import net.helcel.beans.countries.Country.* import net.helcel.beans.countries.Country.*
@Suppress("RedundantSuppression", "SpellCheckingInspection", "unused")
enum class Group(override val fullName: String, override val children: Set<GeoLoc>) : GeoLoc { enum class Group(override val fullName: String, override val children: Set<GeoLoc>) : GeoLoc {
EEE( EEE(

View File

@@ -24,53 +24,53 @@ const val AUTO_GROUP = -1
@Serializable @Serializable
class Groups(val id: Int, private val groups: HashMap<Int, Group>) { class Groups(val id: Int, private val grps: HashMap<Int, Group>) {
@kotlinx.serialization.Transient @kotlinx.serialization.Transient
private val _groupsFlow = MutableStateFlow<List<Group>>(groups.values.toList()) private val _groupsFlow = MutableStateFlow<List<Group>>(grps.values.toList())
@kotlinx.serialization.Transient @kotlinx.serialization.Transient
val groupsFlow: StateFlow<List<Group>> = _groupsFlow.asStateFlow() val groupsFlow: StateFlow<List<Group>> = _groupsFlow.asStateFlow()
fun setGroup(key: Int, name: String, col: ColorDrawable) { fun setGroup(key: Int, name: String, col: ColorDrawable) {
groups[key] = Group(key, name, col) grps[key] = Group(key, name, col)
_groupsFlow.value = groups.values.toList() _groupsFlow.value = grps.values.toList()
} }
fun deleteGroup(key: Int) { fun deleteGroup(key: Int) {
groups.remove(key) grps.remove(key)
_groupsFlow.value = groups.values.toList() _groupsFlow.value = grps.values.toList()
} }
fun getGroupFromKey(key: Int): Group { fun getGroupFromKey(key: Int): Group {
return groups.getOrDefault(key, EmptyGroup()) return grps.getOrDefault(key, EmptyGroup())
} }
fun genKey(): Int { fun genKey(): Int {
val key = rnd.nextInt() val key = rnd.nextInt()
if (groups.containsKey(key) || key in listOf(NO_GROUP, DEFAULT_GROUP, AUTO_GROUP)) return genKey() if (grps.containsKey(key) || key in listOf(NO_GROUP, DEFAULT_GROUP, AUTO_GROUP)) return genKey()
return key return key
} }
fun size(): Int { fun size(): Int {
return groups.size return grps.size
} }
fun getUniqueEntry(): Group? { fun getUniqueEntry(): Group? {
assert(size() == 1) assert(size() == 1)
return if (groups.size == 1) { return if (grps.size == 1) {
groups[groups.keys.first()] grps[grps.keys.first()]
} else { } else {
null null
} }
} }
fun getGroupFromPos(pos: Int): Pair<Int, Group> { fun getGroupFromPos(pos: Int): Pair<Int, Group> {
if(groups.keys.isEmpty()) return Pair(NO_GROUP,Group(NO_GROUP,"-")) if(grps.keys.isEmpty()) return Pair(NO_GROUP,Group(NO_GROUP,"-"))
val key = groups.keys.toList()[pos] val key = grps.keys.toList()[pos]
return Pair(key, getGroupFromKey(key)) return Pair(key, getGroupFromKey(key))
} }
fun findGroupPos(key: Int): Int { fun findGroupPos(key: Int): Int {
return groups.keys.toList().indexOf(key) return grps.keys.toList().indexOf(key)
} }
class EmptyGroup : Group(0, "") class EmptyGroup : Group(0, "")

View File

@@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>

View File

@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '9.2.1' apply false id 'com.android.application' version '9.0.0' apply false
id 'com.android.library' version '9.2.1' apply false id 'com.android.library' version '9.0.0' apply false
id 'org.jetbrains.kotlin.android' version '2.3.21' apply false id 'org.jetbrains.kotlin.android' version '2.3.10' apply false
} }

View File

@@ -1,9 +1,24 @@
# Project-wide Gradle settings. # Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# 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
# 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 android.useAndroidX=true
android.enableJetifier=false android.enableJetifier=false
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official kotlin.code.style=official
android.nonTransitiveRClass=true # Enables namespacing of each library's R class so that its R class includes only the
android.uniquePackageNames=false # resources declared in the library itself and none from the library's dependencies,
android.dependency.useConstraints=false # thereby reducing the size of the R class for that library
android.r8.strictFullModeForKeepRules=false android.nonTransitiveRClass=true

Binary file not shown.

View File

@@ -1,10 +1,8 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f distributionSha256Sum=b266d5ff6b90eada6dc3b20cb090e3731302e553a27c5d3e4df1f0d76beaff06
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
networkTimeout=10000 networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

2
gradlew vendored
View File

@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.

31
gradlew.bat vendored
View File

@@ -23,8 +23,8 @@
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables, and ensure extensions are enabled @rem Set local scope for the variables with windows NT shell
setlocal EnableExtensions if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
"%COMSPEC%" /c exit 1 goto fail
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,7 +65,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
"%COMSPEC%" /c exit 1 goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
@@ -73,10 +73,21 @@ echo location of your Java installation. 1>&2
@rem Execute Gradle @rem Execute Gradle
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:exitWithErrorLevel :end
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts @rem End local scope for the variables with windows NT shell
"%COMSPEC%" /c exit %ERRORLEVEL% if %ERRORLEVEL% equ 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!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,9 +1,9 @@
{ {
"dependencies": { "dependencies": {
"@turf/area": "^7.3.5", "@turf/area": "^7.0.0",
"@turf/turf": "^7.3.5", "@turf/turf": "^7.0.0",
"jsdom": "^29.1.1", "jsdom": "^28.0.0",
"mapshaper": "^0.7.19" "mapshaper": "^0.6.79"
}, },
"type": "module" "type": "module"
} }

View File

@@ -6,9 +6,6 @@ pluginManagement {
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
} }
} }
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {

7205
yarn.lock

File diff suppressed because it is too large Load Diff