feat(device): add visibility/luftdata/narodmon settings, device model icons, SDK refactor

- Add SetDeviceVisibilityUseCase, SetLuftdataUseCase, SetNarodmonUseCase

- Introduce DeviceModel enum (Basic, Mobile, Solar, Radiation, Custom)

- Add device-type drawables (active/inactive icons for each model)

- Refactor Device SDK: repository, DAO, database, local/remote data sources

- Update DeviceSettingsScreen, ManageViewModel, theme colors

- Add/update string resources (default, ru, be)

Made-with: Cursor
This commit is contained in:
2026-03-06 20:01:24 +01:00
parent 7815f151f1
commit 0519936531
41 changed files with 1251 additions and 138 deletions

View File

@@ -1,25 +1,33 @@
package org.db3.airmq.features.device
import android.R as AndroidR
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Switch
@@ -27,24 +35,44 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import kotlinx.coroutines.flow.collectLatest
import org.db3.airmq.R
import org.db3.airmq.sdk.device.domain.DeviceModel
import org.db3.airmq.features.common.AirMQButton
import org.db3.airmq.ui.theme.AirMQTheme
import org.db3.airmq.features.common.AirMQButtonStyle
import org.db3.airmq.sdk.device.domain.OnlineStatus
import org.db3.airmq.ui.theme.LegacyBackground
import org.db3.airmq.ui.theme.LegacyBlack12
import androidx.core.net.toUri
private const val INFO_URL = "https://docs.google.com/document/d/1JC41nHE5foYhS6beDFTA5a8dQqX3IQoqHJYZbPRtmuM/edit"
private fun roundLocation(d: Double): String =
"%.5f".format(d).replace(',', '.')
private fun DeviceModel.iconRes(): Int = when (this) {
DeviceModel.Basic -> R.drawable.ic_device_basic_active_10
DeviceModel.Mobile -> R.drawable.ic_device_mobile_active_10
DeviceModel.Solar -> R.drawable.ic_device_solar_active_10
DeviceModel.Radiation -> R.drawable.ic_device_radiation_active_10
DeviceModel.Custom -> R.drawable.ic_device_custom_active_10
}
@Composable
fun DeviceSettingsScreen(
@@ -52,11 +80,15 @@ fun DeviceSettingsScreen(
onOpenLocation: () -> Unit,
onShowOnMap: () -> Unit,
onNavigateBack: () -> Unit,
viewModel: DeviceSettingsViewModel = hiltViewModel()
viewModel: DeviceSettingsViewModel = hiltViewModel(
creationCallback = { factory: DeviceSettingsViewModel.Factory ->
factory.create(deviceId)
}
)
) {
val uiState by viewModel.uiState.collectAsState()
val snackbarHostState = remember { SnackbarHostState() }
val toastDoneText = stringResource(R.string.toast_done)
val context = LocalContext.current
LaunchedEffect(viewModel) {
viewModel.actions.collectLatest { action ->
@@ -64,21 +96,23 @@ fun DeviceSettingsScreen(
is DeviceSettingsScreenContract.Action.ShowError -> {
snackbarHostState.showSnackbar(action.message)
}
is DeviceSettingsScreenContract.Action.ShowSuccess -> {
snackbarHostState.showSnackbar(toastDoneText)
}
is DeviceSettingsScreenContract.Action.ShowSuccess -> { /* no snackbar for success */ }
is DeviceSettingsScreenContract.Action.OpenLocation -> onOpenLocation()
is DeviceSettingsScreenContract.Action.ShowOnMap -> onShowOnMap()
is DeviceSettingsScreenContract.Action.OpenInfoUrl -> {
context.startActivity(Intent(Intent.ACTION_VIEW, INFO_URL.toUri()))
}
}
}
}
Scaffold(
modifier = Modifier.fillMaxSize(),
modifier = Modifier.fillMaxWidth(),
topBar = {
Row(
modifier = Modifier
.fillMaxWidth()
.statusBarsPadding()
.background(LegacyBackground)
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
@@ -90,26 +124,42 @@ fun DeviceSettingsScreen(
)
}
Text(
text = stringResource(R.string.title_device),
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(start = 8.dp)
text = stringResource(R.string.title_device_config),
style = MaterialTheme.typography.titleLarge.copy(
fontSize = 24.sp,
fontWeight = FontWeight.Medium
),
modifier = Modifier
.weight(1f)
.padding(start = 8.dp),
textAlign = androidx.compose.ui.text.style.TextAlign.Center
)
Spacer(modifier = Modifier.size(48.dp))
}
},
snackbarHost = { SnackbarHost(snackbarHostState) }
snackbarHost = {
SnackbarHost(
hostState = snackbarHostState,
snackbar = { data ->
Snackbar(
snackbarData = data,
containerColor = MaterialTheme.colorScheme.inverseSurface,
contentColor = MaterialTheme.colorScheme.inverseOnSurface
)
}
)
}
) { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.fillMaxWidth()
.padding(innerPadding)
) {
when {
uiState.isLoading -> {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center)
)
uiState.device == null && uiState.isLoading -> {
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
}
uiState.device == null -> {
uiState.device == null && !uiState.isLoading -> {
Text(
text = stringResource(R.string.text_nothing_to_show),
modifier = Modifier
@@ -118,26 +168,48 @@ fun DeviceSettingsScreen(
)
}
else -> {
DeviceSettingsContent(
state = uiState,
onEvent = viewModel::onEvent,
deviceName = uiState.device?.name ?: ""
)
Box(modifier = Modifier.fillMaxWidth()) {
DeviceSettingsContent(
state = uiState,
onEvent = viewModel::onEvent
)
if (uiState.isLoading) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.3f)),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
}
}
}
}
}
}
private val PreviewHeaderColor = Color(0xFF1F5DA5)
private val PreviewGreyColor = Color(0x61000000)
private val PreviewBlack54 = Color(0x8A000000)
private val PreviewOrange = Color(0xFFFF6F00)
@Composable
private fun DeviceSettingsContent(
state: DeviceSettingsScreenContract.State,
onEvent: (DeviceSettingsScreenContract.Event) -> Unit,
deviceName: String
labelColorOverride: Color? = null,
greyColorOverride: Color? = null,
iconResOverride: Int? = null
) {
val device = state.device!!
var showRenameDialog by remember { mutableStateOf(false) }
var renameText by remember(deviceName) { mutableStateOf(deviceName) }
var showConfigComingSoonDialog by remember { mutableStateOf(false) }
var renameText by remember(device.name) { mutableStateOf(device.name) }
val headerColor = labelColorOverride ?: colorResource(R.color.headerColor)
val onSurfaceVariant = MaterialTheme.colorScheme.onSurfaceVariant
val greyColor = greyColorOverride ?: colorResource(R.color.black38)
if (showRenameDialog) {
AlertDialog(
@@ -178,9 +250,23 @@ private fun DeviceSettingsContent(
}
)
}
if (showConfigComingSoonDialog) {
AlertDialog(
onDismissRequest = { showConfigComingSoonDialog = false },
title = { Text(stringResource(R.string.coming_soon)) },
text = { Text(stringResource(R.string.coming_soon)) },
confirmButton = {
androidx.compose.material3.TextButton(onClick = { showConfigComingSoonDialog = false }) {
Text(stringResource(R.string.button_ok))
}
}
)
}
val scrollState = rememberScrollState()
val statusIcon = when (device.toOnlineStatus()) {
OnlineStatus.Online -> R.drawable.device_chip_online
val statusIcon = when {
state.isConnected -> R.drawable.device_chip_online
else -> R.drawable.device_chip_offline
}
@@ -189,115 +275,458 @@ private fun DeviceSettingsContent(
.fillMaxWidth()
.verticalScroll(scrollState)
.background(LegacyBackground)
.padding(16.dp)
) {
HorizontalDivider(color = LegacyBlack12)
Row(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth()
.height(72.dp)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(R.drawable.ic_chip),
painter = painterResource(
iconResOverride ?: device.model.iconRes()
),
contentDescription = null,
modifier = Modifier.size(48.dp)
modifier = Modifier.size(40.dp)
)
Spacer(modifier = Modifier.size(16.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = device.name,
style = MaterialTheme.typography.headlineSmall
style = MaterialTheme.typography.bodyLarge.copy(fontSize = 16.sp)
)
Text(
text = device.model,
style = MaterialTheme.typography.bodyMedium,
color = Color.Gray
text = device.model.displayName,
style = MaterialTheme.typography.bodyMedium.copy(fontSize = 14.sp),
color = greyColor
)
}
Icon(
painter = painterResource(statusIcon),
contentDescription = device.toOnlineStatus().toString(),
modifier = Modifier.size(24.dp)
)
}
if (state.isPendingSync) {
Text(
text = stringResource(R.string.text_pending_sync),
style = MaterialTheme.typography.bodySmall,
color = Color.Gray,
modifier = Modifier.padding(top = 8.dp)
text = if (state.isConnected) stringResource(R.string.text_device_connected) else "",
style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp),
color = greyColor
)
if (!state.isConnected) {
Icon(
painter = painterResource(statusIcon),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
}
HorizontalDivider(color = LegacyBlack12)
Spacer(modifier = Modifier.height(24.dp))
AirMQButton(
text = stringResource(R.string.button_rename),
ConfigRow(
label = stringResource(R.string.text_device_name),
value = device.name,
onClick = { showRenameDialog = true },
style = AirMQButtonStyle.Outlined,
modifier = Modifier.fillMaxWidth()
trailingIcon = R.drawable.ic_edit,
iconTint = (labelColorOverride?.let { PreviewBlack54 } ?: colorResource(R.color.black54)),
labelColor = headerColor
)
Spacer(modifier = Modifier.height(12.dp))
ConfigRowReadOnly(
label = stringResource(R.string.text_device_id),
value = device.id,
labelColor = headerColor
)
if (device.hasLocation()) {
Text(
text = stringResource(
ConfigRowReadOnly(
label = stringResource(R.string.text_device_ip),
value = device.deviceAddress,
labelColor = headerColor
)
ConfigRowWithIndicator(
label = stringResource(R.string.text_device_config_version),
value = device.configVersion,
showIndicator = state.configVersionNeedsUpdate,
indicatorColor = labelColorOverride?.let { PreviewOrange } ?: colorResource(R.color.colorOrange),
onClick = { if (state.configVersionNeedsUpdate) showConfigComingSoonDialog = true },
trailingIcon = if (state.configVersionNeedsUpdate) {
R.drawable.ic_upload
} else null,
iconTint = labelColorOverride?.let { PreviewBlack54 } ?: colorResource(R.color.black54),
labelColor = headerColor,
indicatorDrawableRes = null
)
ConfigRowReadOnly(
label = stringResource(R.string.text_device_wifi),
value = state.wifiSsid,
labelColor = headerColor
)
HorizontalDivider(color = LegacyBlack12)
ConfigRowWithIndicator(
label = stringResource(R.string.text_device_location),
value = if (device.hasLocation()) {
stringResource(
R.string.text_device_location_set,
device.latitude!!,
device.longitude!!
),
style = MaterialTheme.typography.bodyMedium
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
AirMQButton(
text = stringResource(R.string.title_location),
onClick = { onEvent(DeviceSettingsScreenContract.Event.OpenLocationClicked) },
style = AirMQButtonStyle.Outlined,
modifier = Modifier.weight(1f)
roundLocation(device.latitude!!),
roundLocation(device.longitude!!)
)
AirMQButton(
text = stringResource(R.string.button_view_on_map),
onClick = { onEvent(DeviceSettingsScreenContract.Event.ShowOnMapClicked) },
style = AirMQButtonStyle.Outlined,
modifier = Modifier.weight(1f)
)
}
} else {
AirMQButton(
text = stringResource(R.string.button_register),
onClick = { onEvent(DeviceSettingsScreenContract.Event.OpenLocationClicked) },
style = AirMQButtonStyle.Outlined,
modifier = Modifier.fillMaxWidth()
)
}
} else {
stringResource(R.string.text_device_location_unset)
},
showIndicator = !device.hasLocation(),
indicatorColor = labelColorOverride?.let { PreviewOrange } ?: colorResource(R.color.colorOrange),
onClick = { onEvent(DeviceSettingsScreenContract.Event.OpenLocationClicked) },
trailingIcon = if (device.hasLocation()) null else R.drawable.ic_edit,
iconTint = labelColorOverride?.let { PreviewBlack54 } ?: colorResource(R.color.black54),
labelColor = headerColor,
indicatorDrawableRes = null
)
Spacer(modifier = Modifier.height(12.dp))
ToggleRow(
title = stringResource(R.string.text_device_narodmon_title),
subtitle = stringResource(R.string.text_device_narodmon),
checked = device.isNarodmonOn,
onCheckedChange = { onEvent(DeviceSettingsScreenContract.Event.NarodmonToggled(it)) },
onInfoClick = { onEvent(DeviceSettingsScreenContract.Event.NarodmonInfoClicked) },
labelColor = headerColor,
infoIconTint = labelColorOverride?.let { PreviewBlack54 } ?: colorResource(R.color.black54),
infoIconResOverride = null
)
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = stringResource(R.string.text_data_sharing),
style = MaterialTheme.typography.bodyLarge
)
Switch(
checked = device.dataSharingEnabled,
onCheckedChange = { onEvent(DeviceSettingsScreenContract.Event.DataSharingToggled(it)) }
)
}
ToggleRow(
title = stringResource(R.string.text_device_luftdata_title),
subtitle = stringResource(R.string.text_device_luftdata),
checked = device.isLuftdataOn,
onCheckedChange = { onEvent(DeviceSettingsScreenContract.Event.LuftdataToggled(it)) },
onInfoClick = { onEvent(DeviceSettingsScreenContract.Event.LuftdataInfoClicked) },
labelColor = headerColor,
infoIconTint = labelColorOverride?.let { PreviewBlack54 } ?: colorResource(R.color.black54),
infoIconResOverride = null
)
Spacer(modifier = Modifier.height(12.dp))
VisibilityRow(
label = stringResource(R.string.text_device_visibility),
visibilityText = when {
!device.hasLocation() -> stringResource(R.string.text_device_visibility_not_registered)
device.isPublic -> stringResource(R.string.text_device_visibility_visible)
else -> stringResource(R.string.text_device_visibility_private)
},
publishButtonText = if (device.isPublic) {
stringResource(R.string.button_hide)
} else {
stringResource(R.string.button_publish)
},
isPublishButtonEnabled = device.hasLocation(),
onPublishClick = {
if (device.isPublic) {
onEvent(DeviceSettingsScreenContract.Event.VisibilityHideClicked)
} else {
onEvent(DeviceSettingsScreenContract.Event.VisibilityPublishClicked)
}
},
labelColor = greyColor
)
Spacer(modifier = Modifier.height(20.dp))
AirMQButton(
text = stringResource(R.string.button_firmware_update),
onClick = { onEvent(DeviceSettingsScreenContract.Event.FirmwareUpdateClicked) },
style = AirMQButtonStyle.Gradient,
modifier = Modifier.fillMaxWidth()
text = stringResource(R.string.button_view_on_map),
onClick = { onEvent(DeviceSettingsScreenContract.Event.ShowOnMapClicked) },
style = AirMQButtonStyle.Contained,
enabled = device.hasLocation(),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 80.dp)
)
Spacer(modifier = Modifier.height(20.dp))
}
}
@Composable
private fun VisibilityRow(
label: String,
visibilityText: String,
publishButtonText: String,
isPublishButtonEnabled: Boolean,
onPublishClick: () -> Unit,
labelColor: Color
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = label,
style = MaterialTheme.typography.bodyMedium.copy(fontSize = 14.sp),
color = labelColor
)
Text(
text = visibilityText,
style = MaterialTheme.typography.bodyLarge.copy(fontSize = 16.sp)
)
}
AirMQButton(
text = publishButtonText,
onClick = onPublishClick,
enabled = isPublishButtonEnabled,
style = AirMQButtonStyle.Text,
modifier = Modifier.width(170.dp)
)
}
}
@Composable
private fun ConfigRow(
label: String,
value: String,
onClick: () -> Unit,
trailingIcon: Int,
iconTint: Color,
labelColor: Color
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.clickable(onClick = onClick)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = label,
style = MaterialTheme.typography.labelMedium.copy(fontSize = 12.sp, fontWeight = FontWeight.Medium),
color = labelColor
)
Text(
text = value,
style = MaterialTheme.typography.bodyMedium.copy(fontSize = 14.sp)
)
}
Icon(
painter = painterResource(trailingIcon),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = iconTint
)
}
}
@Composable
private fun ConfigRowReadOnly(
label: String,
value: String,
labelColor: Color
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(
text = label,
style = MaterialTheme.typography.labelMedium.copy(fontSize = 12.sp, fontWeight = FontWeight.Medium),
color = labelColor
)
Text(
text = value,
style = MaterialTheme.typography.bodyMedium.copy(fontSize = 14.sp)
)
}
}
}
@Composable
private fun ConfigRowWithIndicator(
label: String,
value: String,
showIndicator: Boolean,
indicatorColor: Color,
onClick: () -> Unit,
trailingIcon: Int?,
iconTint: Color,
labelColor: Color,
indicatorDrawableRes: Int? = null
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.clickable(onClick = onClick)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column(modifier = Modifier.weight(1f)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = label,
style = MaterialTheme.typography.labelMedium.copy(fontSize = 12.sp, fontWeight = FontWeight.Medium),
color = labelColor
)
if (showIndicator) {
Spacer(modifier = Modifier.size(5.dp))
Icon(
painter = painterResource(indicatorDrawableRes ?: R.drawable.circle_indicator),
contentDescription = null,
modifier = Modifier.size(10.dp),
tint = indicatorColor
)
}
}
Text(
text = value,
style = MaterialTheme.typography.bodyMedium.copy(fontSize = 14.sp)
)
}
if (trailingIcon != null) {
Icon(
painter = painterResource(trailingIcon),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = iconTint
)
}
}
}
@Composable
private fun ToggleRow(
title: String,
subtitle: String,
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
onInfoClick: () -> Unit,
labelColor: Color,
infoIconTint: Color,
infoIconResOverride: Int? = null
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.clickable { onCheckedChange(!checked) }
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.weight(1f)
) {
Column {
Text(
text = title,
style = MaterialTheme.typography.labelMedium.copy(fontSize = 12.sp, fontWeight = FontWeight.Medium),
color = labelColor
)
Text(
text = subtitle,
style = MaterialTheme.typography.bodyMedium.copy(fontSize = 14.sp)
)
}
IconButton(
onClick = onInfoClick,
modifier = Modifier
.size(32.dp)
.padding(8.dp)
) {
Icon(
painter = painterResource(infoIconResOverride ?: R.drawable.ic_pref_info),
contentDescription = null,
tint = infoIconTint
)
}
}
Switch(
checked = checked,
onCheckedChange = onCheckedChange
)
}
}
@Preview(showBackground = true, name = "Device config no location")
@Composable
private fun PreviewDeviceSettingsContentDefault() {
AirMQTheme {
DeviceSettingsContent(
state = DeviceSettingsScreenContract.previewState(),
onEvent = {},
labelColorOverride = PreviewHeaderColor,
greyColorOverride = PreviewGreyColor,
iconResOverride = AndroidR.drawable.ic_menu_mylocation
)
}
}
@Preview(showBackground = true, name = "Device config with location")
@Composable
private fun PreviewDeviceSettingsContentWithLocation() {
AirMQTheme {
DeviceSettingsContent(
state = DeviceSettingsScreenContract.previewState(
device = DeviceSettingsScreenContract.previewDevice(hasLocation = true, isPublic = false)
),
onEvent = {},
labelColorOverride = PreviewHeaderColor,
greyColorOverride = PreviewGreyColor,
iconResOverride = AndroidR.drawable.ic_menu_mylocation
)
}
}
@Preview(showBackground = true, name = "Device config public visibility")
@Composable
private fun PreviewDeviceSettingsContentPublicVisibility() {
AirMQTheme {
DeviceSettingsContent(
state = DeviceSettingsScreenContract.previewState(
device = DeviceSettingsScreenContract.previewDevice(hasLocation = true, isPublic = true)
),
onEvent = {},
labelColorOverride = PreviewHeaderColor,
greyColorOverride = PreviewGreyColor,
iconResOverride = AndroidR.drawable.ic_menu_mylocation
)
}
}
@Preview(showBackground = true, name = "Device config config needs update")
@Composable
private fun PreviewDeviceSettingsContentConfigNeedsUpdate() {
AirMQTheme {
DeviceSettingsContent(
state = DeviceSettingsScreenContract.previewState(
configVersionNeedsUpdate = true
),
onEvent = {},
labelColorOverride = PreviewHeaderColor,
greyColorOverride = PreviewGreyColor,
iconResOverride = AndroidR.drawable.ic_menu_mylocation
)
}
}
@Preview(showBackground = true, name = "Device config Narodmon/Luftdata on")
@Composable
private fun PreviewDeviceSettingsContentTogglesOn() {
AirMQTheme {
DeviceSettingsContent(
state = DeviceSettingsScreenContract.previewState(
device = DeviceSettingsScreenContract.previewDevice(
isNarodmonOn = true,
isLuftdataOn = true
)
),
onEvent = {},
labelColorOverride = PreviewHeaderColor,
greyColorOverride = PreviewGreyColor,
iconResOverride = AndroidR.drawable.ic_menu_mylocation
)
}
}

View File

@@ -1,14 +1,65 @@
package org.db3.airmq.features.device
import org.db3.airmq.sdk.device.domain.Device
import org.db3.airmq.sdk.device.domain.DeviceModel
import org.db3.airmq.sdk.device.domain.OnlineFreshness
object DeviceSettingsScreenContract {
fun previewState(
device: Device? = previewDevice(),
isLoading: Boolean = false,
isPendingSync: Boolean = false,
configVersionNeedsUpdate: Boolean = false,
isConnected: Boolean = true,
wifiSsid: String = "Захарова 42"
): State = State(
device = device,
isLoading = isLoading,
isPendingSync = isPendingSync,
configVersionNeedsUpdate = configVersionNeedsUpdate,
isConnected = isConnected,
wifiSsid = wifiSsid
)
fun previewDevice(
id: String = "12312",
name: String = "Захарова 42",
model: DeviceModel = DeviceModel.Mobile,
deviceAddress: String = "127.0.0.1",
configVersion: String = "42",
isNarodmonOn: Boolean = false,
isLuftdataOn: Boolean = false,
hasLocation: Boolean = false,
isPublic: Boolean = false
): Device = Device(
id = id,
name = name,
model = model,
firmwareVersion = "1.0",
deviceAddress = deviceAddress,
configVersion = configVersion,
isNarodmonOn = isNarodmonOn,
isLuftdataOn = isLuftdataOn,
locationId = null,
latitude = if (hasLocation) 53.9 else null,
longitude = if (hasLocation) 27.5 else null,
isPublic = isPublic,
city = null,
dataSharingEnabled = false,
isOnline = true,
onlineFreshness = OnlineFreshness.Fresh,
ownerId = null
)
data class State(
val device: Device? = null,
val isLoading: Boolean = false,
val errorMessage: String? = null,
val isPendingSync: Boolean = false
val isPendingSync: Boolean = false,
val configVersionNeedsUpdate: Boolean = false,
val isConnected: Boolean = false,
val wifiSsid: String = ""
)
sealed interface Action {
@@ -16,15 +67,23 @@ object DeviceSettingsScreenContract {
data object ShowSuccess : Action
data object OpenLocation : Action
data object ShowOnMap : Action
data object OpenInfoUrl : Action
}
sealed interface Event {
data class RenameSubmitted(val name: String) : Event
data object RenameRowClicked : Event
data object ConfigUpdateClicked : Event
data class NarodmonToggled(val enabled: Boolean) : Event
data class LuftdataToggled(val enabled: Boolean) : Event
data object NarodmonInfoClicked : Event
data object LuftdataInfoClicked : Event
data class LocationSet(val latitude: Double, val longitude: Double) : Event
data object LocationRemoved : Event
data class DataSharingToggled(val enabled: Boolean) : Event
data object FirmwareUpdateClicked : Event
data object OpenLocationClicked : Event
data object ShowOnMapClicked : Event
data object VisibilityPublishClicked : Event
data object VisibilityHideClicked : Event
}
}

View File

@@ -1,9 +1,12 @@
package org.db3.airmq.features.device
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
@@ -16,23 +19,32 @@ import kotlinx.coroutines.launch
import org.db3.airmq.features.device.usecases.GetDeviceUseCase
import org.db3.airmq.features.device.usecases.ObservePendingSyncUseCase
import org.db3.airmq.features.device.usecases.RenameDeviceUseCase
import org.db3.airmq.features.device.usecases.SetDataSharingUseCase
import org.db3.airmq.features.device.usecases.SetDeviceLocationUseCase
import org.db3.airmq.features.device.usecases.SetDeviceVisibilityUseCase
import org.db3.airmq.features.device.usecases.SetLuftdataUseCase
import org.db3.airmq.features.device.usecases.SetNarodmonUseCase
import org.db3.airmq.features.device.usecases.TriggerFirmwareUpdateUseCase
import javax.inject.Inject
import org.db3.airmq.sdk.device.domain.Device
import org.db3.airmq.sdk.device.domain.DeviceModel
import org.db3.airmq.sdk.device.domain.OnlineFreshness
@HiltViewModel
class DeviceSettingsViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
@HiltViewModel(assistedFactory = DeviceSettingsViewModel.Factory::class)
class DeviceSettingsViewModel @AssistedInject constructor(
@Assisted private val deviceId: String,
private val getDeviceUseCase: GetDeviceUseCase,
private val renameDeviceUseCase: RenameDeviceUseCase,
private val setDeviceLocationUseCase: SetDeviceLocationUseCase,
private val setDataSharingUseCase: SetDataSharingUseCase,
private val setNarodmonUseCase: SetNarodmonUseCase,
private val setLuftdataUseCase: SetLuftdataUseCase,
private val setDeviceVisibilityUseCase: SetDeviceVisibilityUseCase,
private val triggerFirmwareUpdateUseCase: TriggerFirmwareUpdateUseCase,
private val observePendingSyncUseCase: ObservePendingSyncUseCase
) : ViewModel() {
private val deviceId: String = checkNotNull(savedStateHandle.get<String>("deviceId"))
@AssistedFactory
interface Factory {
fun create(deviceId: String): DeviceSettingsViewModel
}
private val _uiState = MutableStateFlow(DeviceSettingsScreenContract.State())
val uiState: StateFlow<DeviceSettingsScreenContract.State> = _uiState.asStateFlow()
@@ -48,22 +60,60 @@ class DeviceSettingsViewModel @Inject constructor(
) { device, hasPending ->
device to hasPending
}.collect { (device, hasPending) ->
val displayDevice = device ?: stubDevice()
val configVersionNeedsUpdate = deriveConfigVersionNeedsUpdate(displayDevice)
val isConnected = true // Stub: always connected for UI testing
_uiState.update {
it.copy(
device = device,
isPendingSync = hasPending
device = displayDevice,
isPendingSync = hasPending,
configVersionNeedsUpdate = configVersionNeedsUpdate,
isConnected = isConnected,
wifiSsid = if (device == null) "Захарова 42" else it.wifiSsid.takeIf { s -> s.isNotEmpty() } ?: ""
)
}
}
}
}
private fun stubDevice(): Device = Device(
id = "12312",
name = "Захарова 42",
model = DeviceModel.Mobile,
firmwareVersion = "1.0",
deviceAddress = "127.0.0.1",
configVersion = "42",
isNarodmonOn = false,
isLuftdataOn = false,
locationId = null,
latitude = null,
longitude = null,
isPublic = false,
city = null,
dataSharingEnabled = false,
isOnline = true,
onlineFreshness = OnlineFreshness.Fresh,
ownerId = null
)
private fun deriveConfigVersionNeedsUpdate(device: Device): Boolean {
// Stub: compare configVersion to expected (e.g. 42); for testing assume up-to-date
return false
}
fun onEvent(event: DeviceSettingsScreenContract.Event) {
when (event) {
is DeviceSettingsScreenContract.Event.RenameSubmitted -> renameDevice(event.name)
is DeviceSettingsScreenContract.Event.RenameRowClicked -> { /* UI opens dialog */ }
is DeviceSettingsScreenContract.Event.ConfigUpdateClicked -> configUpdateStub()
is DeviceSettingsScreenContract.Event.NarodmonToggled -> setNarodmon(event.enabled)
is DeviceSettingsScreenContract.Event.LuftdataToggled -> setLuftdata(event.enabled)
is DeviceSettingsScreenContract.Event.NarodmonInfoClicked,
is DeviceSettingsScreenContract.Event.LuftdataInfoClicked -> _actions.tryEmit(
DeviceSettingsScreenContract.Action.OpenInfoUrl
)
is DeviceSettingsScreenContract.Event.LocationSet -> setLocation(event.latitude, event.longitude)
is DeviceSettingsScreenContract.Event.LocationRemoved -> removeLocation()
is DeviceSettingsScreenContract.Event.DataSharingToggled -> setDataSharing(event.enabled)
is DeviceSettingsScreenContract.Event.FirmwareUpdateClicked -> triggerFirmwareUpdate()
is DeviceSettingsScreenContract.Event.OpenLocationClicked -> _actions.tryEmit(
DeviceSettingsScreenContract.Action.OpenLocation
@@ -71,12 +121,24 @@ class DeviceSettingsViewModel @Inject constructor(
is DeviceSettingsScreenContract.Event.ShowOnMapClicked -> _actions.tryEmit(
DeviceSettingsScreenContract.Action.ShowOnMap
)
is DeviceSettingsScreenContract.Event.VisibilityPublishClicked -> setVisibility(true)
is DeviceSettingsScreenContract.Event.VisibilityHideClicked -> setVisibility(false)
}
}
private fun configUpdateStub() {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, errorMessage = null) }
delay(800)
_uiState.update { it.copy(isLoading = false) }
_actions.tryEmit(DeviceSettingsScreenContract.Action.ShowSuccess)
}
}
private fun renameDevice(name: String) {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, errorMessage = null) }
delay(500) // Stub simulation
val result = renameDeviceUseCase(deviceId, name)
_uiState.update { it.copy(isLoading = false) }
if (result.isSuccess) {
@@ -91,6 +153,42 @@ class DeviceSettingsViewModel @Inject constructor(
}
}
private fun setNarodmon(enabled: Boolean) {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, errorMessage = null) }
delay(300)
val result = setNarodmonUseCase(deviceId, enabled)
_uiState.update { it.copy(isLoading = false) }
if (result.isSuccess) {
_actions.tryEmit(DeviceSettingsScreenContract.Action.ShowSuccess)
} else {
_actions.tryEmit(
DeviceSettingsScreenContract.Action.ShowError(
result.exceptionOrNull()?.message ?: "Failed to update Narodmon"
)
)
}
}
}
private fun setLuftdata(enabled: Boolean) {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, errorMessage = null) }
delay(300)
val result = setLuftdataUseCase(deviceId, enabled)
_uiState.update { it.copy(isLoading = false) }
if (result.isSuccess) {
_actions.tryEmit(DeviceSettingsScreenContract.Action.ShowSuccess)
} else {
_actions.tryEmit(
DeviceSettingsScreenContract.Action.ShowError(
result.exceptionOrNull()?.message ?: "Failed to update Sensor.community"
)
)
}
}
}
private fun setLocation(latitude: Double, longitude: Double) {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, errorMessage = null) }
@@ -125,17 +223,16 @@ class DeviceSettingsViewModel @Inject constructor(
}
}
private fun setDataSharing(enabled: Boolean) {
private fun setVisibility(isPublic: Boolean) {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, errorMessage = null) }
val result = setDataSharingUseCase(deviceId, enabled)
delay(300)
val result = setDeviceVisibilityUseCase(deviceId, isPublic)
_uiState.update { it.copy(isLoading = false) }
if (result.isSuccess) {
_actions.tryEmit(DeviceSettingsScreenContract.Action.ShowSuccess)
} else {
if (result.isFailure) {
_actions.tryEmit(
DeviceSettingsScreenContract.Action.ShowError(
result.exceptionOrNull()?.message ?: "Failed to update data sharing"
result.exceptionOrNull()?.message ?: "Failed to update visibility"
)
)
}

View File

@@ -0,0 +1,15 @@
package org.db3.airmq.features.device.usecases
import org.db3.airmq.sdk.device.domain.DeviceRepository
import javax.inject.Inject
/**
* Use case to set device visibility (publish/hide location on map).
* Only effective when device has location.
*/
class SetDeviceVisibilityUseCase @Inject constructor(
private val repository: DeviceRepository
) {
suspend operator fun invoke(deviceId: String, isPublic: Boolean): Result<Unit> =
repository.setVisibility(deviceId, isPublic)
}

View File

@@ -0,0 +1,14 @@
package org.db3.airmq.features.device.usecases
import org.db3.airmq.sdk.device.domain.DeviceRepository
import javax.inject.Inject
/**
* Use case to enable or disable Sensor.community (Luftdata) data sharing for a device.
*/
class SetLuftdataUseCase @Inject constructor(
private val repository: DeviceRepository
) {
suspend operator fun invoke(deviceId: String, enabled: Boolean): Result<Unit> =
repository.setLuftdata(deviceId, enabled)
}

View File

@@ -0,0 +1,14 @@
package org.db3.airmq.features.device.usecases
import org.db3.airmq.sdk.device.domain.DeviceRepository
import javax.inject.Inject
/**
* Use case to enable or disable Narodmon.ru data sharing for a device.
*/
class SetNarodmonUseCase @Inject constructor(
private val repository: DeviceRepository
) {
suspend operator fun invoke(deviceId: String, enabled: Boolean): Result<Unit> =
repository.setNarodmon(deviceId, enabled)
}

View File

@@ -108,7 +108,7 @@ class ManageViewModel @Inject constructor(
return DeviceItem(
id = id,
name = name,
extra = model.ifEmpty { "mobile" },
extra = model.displayName,
status = statusText,
hasLocation = hasLocation()
)

View File

@@ -13,6 +13,8 @@ val LegacyOnBackground = Color(0xFF000000)
val LegacyOnSurface = Color(0xFF000000)
val LegacyOutline = Color(0x61000000)
val LegacyOutlineLight = Color(0x3B000000)
val LegacyBlack12 = Color(0x1F000000)
val LegacyBlack38 = Color(0x61000000)
val LegacyNavSelected = Color(0xFFFFFFFF)
val LegacyNavUnselected = Color(0x8AFFFFFF)
val LegacyNavContainer = Color(0xFF295989)

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="10dp"
android:height="10dp"
android:viewportWidth="10"
android:viewportHeight="10">
<path
android:fillColor="@color/sensorOrange"
android:pathData="M5,5m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0"/>
</vector>

View File

@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.28C1,11.28 0,12.28 0,25.58c0,13.29 1,14.29 14.29,14.29c13.3,0 14.3,-1 14.3,-14.29C28.59,12.28 27.59,11.28 14.29,11.28zM24.56,18.44c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.37 25.35,17.65 24.56,18.44z"
android:strokeAlpha="0.54"
android:fillAlpha="0.54"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.85,18.81v0.05c0,0.03 -0.01,0.05 -0.01,0.08c0,0.02 -0.01,0.04 -0.02,0.07c-0.17,0.76 -0.94,1.23 -1.7,1.05c-0.07,-0.01 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.92,-0.76 -0.9,-1.35v-0.08c0,-0.01 0,-0.01 0,-0.01c0.01,-0.05 0.02,-0.1 0.02,-0.15c0.31,-2.26 0.03,-4.5 -0.73,-6.54c-0.12,-0.32 -0.25,-0.64 -0.4,-0.96c-0.06,-0.13 -0.12,-0.26 -0.19,-0.38c-0.04,-0.1 -0.09,-0.19 -0.14,-0.28c-0.05,-0.1 -0.1,-0.2 -0.16,-0.29c-0.01,-0.03 -0.02,-0.05 -0.03,-0.07c-0.05,-0.07 -0.09,-0.15 -0.14,-0.23c-0.04,-0.08 -0.1,-0.17 -0.15,-0.25s-0.1,-0.16 -0.15,-0.24C34.91,9.08 34.85,9 34.8,8.92c-0.33,-0.48 -0.68,-0.94 -1.07,-1.37c-0.06,-0.07 -0.12,-0.14 -0.19,-0.21c-0.14,-0.15 -0.29,-0.3 -0.44,-0.45c-0.05,-0.06 -0.11,-0.12 -0.17,-0.17c-0.07,-0.07 -0.14,-0.13 -0.21,-0.2c-0.1,-0.09 -0.2,-0.17 -0.29,-0.26C32.32,6.17 32.22,6.09 32.11,6C32,5.91 31.9,5.83 31.79,5.75c-0.86,-0.66 -1.81,-1.22 -2.83,-1.66c-0.12,-0.06 -0.25,-0.11 -0.38,-0.16c-0.12,-0.05 -0.25,-0.1 -0.38,-0.15c-0.11,-0.04 -0.23,-0.08 -0.34,-0.11c-0.02,-0.01 -0.03,-0.02 -0.05,-0.02c-1.36,-0.46 -2.81,-0.7 -4.28,-0.7c-0.79,0 -1.58,0.07 -2.37,0.21c-0.02,0 -0.05,0.01 -0.07,0.01c-0.68,0.1 -1.36,-0.31 -1.56,-0.99l-0.02,-0.07c-0.19,-0.74 0.25,-1.5 1,-1.71c0.03,0 0.06,-0.01 0.09,-0.02c0.03,0 0.06,-0.01 0.08,-0.01c2.77,-0.49 5.53,-0.24 8.06,0.61c0.03,0 0.05,0.01 0.07,0.02c0.13,0.04 0.26,0.09 0.38,0.13c0.13,0.05 0.27,0.1 0.4,0.16c0.03,0.01 0.07,0.02 0.1,0.04c1.98,0.8 3.79,1.98 5.32,3.47l0.37,0.37c0.11,0.11 0.21,0.22 0.32,0.34c0.01,0.01 0.03,0.03 0.04,0.05c0.07,0.07 0.14,0.15 0.2,0.22c0.05,0.06 0.1,0.11 0.15,0.17c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.14,0.19 0.21,0.28C36.87,6.94 37,7.12 37.12,7.3c0.02,0.02 0.03,0.05 0.05,0.07c0.05,0.09 0.11,0.17 0.16,0.26c0.13,0.19 0.25,0.39 0.37,0.59c0.06,0.1 0.12,0.2 0.18,0.3c0.08,0.15 0.16,0.3 0.24,0.45c0.05,0.09 0.1,0.19 0.15,0.29c0.01,0.01 0.01,0.02 0.02,0.03c0.07,0.15 0.14,0.3 0.21,0.45c0,0.01 0.01,0.02 0.01,0.03c0.14,0.3 0.27,0.62 0.39,0.93c0.01,0.01 0.01,0.02 0.01,0.03c0.01,0.01 0.01,0.01 0.01,0.02c0.01,0.02 0.02,0.05 0.03,0.07C39.88,13.31 40.23,16.04 39.85,18.81z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
<path
android:fillColor="#FF000000"
android:pathData="M34.12,17.63v0.07c-0.01,0.06 -0.02,0.13 -0.03,0.19c-0.18,0.77 -0.95,1.24 -1.71,1.06c-0.06,-0.02 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.91,-0.76 -0.9,-1.35c0.01,-0.06 0.01,-0.12 0.02,-0.18c0.12,-1.83 -0.39,-3.6 -1.38,-5.05c-0.23,-0.35 -0.49,-0.67 -0.77,-0.97l-0.18,-0.18c-0.09,-0.1 -0.19,-0.18 -0.28,-0.27c-0.07,-0.07 -0.15,-0.13 -0.22,-0.19c-0.06,-0.06 -0.13,-0.11 -0.2,-0.16c-0.04,-0.03 -0.08,-0.07 -0.12,-0.1c-0.11,-0.09 -0.23,-0.17 -0.35,-0.25c-0.06,-0.04 -0.12,-0.08 -0.18,-0.12c-0.01,0 -0.01,0 -0.01,0c-0.19,-0.12 -0.38,-0.24 -0.58,-0.34c-0.06,-0.03 -0.13,-0.07 -0.19,-0.1c-0.01,0 -0.02,-0.01 -0.03,-0.01c-0.13,-0.06 -0.25,-0.12 -0.38,-0.17c-0.01,-0.01 -0.02,-0.01 -0.02,-0.01c-1.25,-0.53 -2.63,-0.74 -4.03,-0.58c-0.69,0.1 -1.35,-0.33 -1.54,-1.02c-0.21,-0.76 0.23,-1.54 0.99,-1.75c0.03,-0.01 0.07,-0.01 0.1,-0.02c0.08,-0.01 0.15,-0.02 0.22,-0.02c1.77,-0.2 3.51,0.05 5.1,0.68c0.01,0 0.01,0 0.03,0.01c0.18,0.07 0.36,0.14 0.54,0.22c1.02,0.47 1.97,1.1 2.81,1.87c0.15,0.14 0.3,0.28 0.44,0.43c0.07,0.07 0.14,0.14 0.2,0.21c0.24,0.26 0.46,0.53 0.68,0.81c0.08,0.11 0.16,0.22 0.24,0.34c0.04,0.05 0.08,0.11 0.12,0.17s0.08,0.11 0.12,0.17c0.03,0.06 0.07,0.12 0.11,0.18c0.03,0.05 0.06,0.11 0.09,0.16c0.1,0.16 0.19,0.33 0.28,0.5c0.05,0.09 0.09,0.17 0.13,0.26c0,0 0,0 0.01,0.01c0.04,0.09 0.09,0.19 0.13,0.29c0.01,0.02 0.02,0.04 0.03,0.06c0.01,0.03 0.02,0.06 0.04,0.09C33.94,14.09 34.26,15.84 34.12,17.63z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.41C1,11.41 0,12.41 0,25.71C0,39 1,40 14.29,40c13.3,0 14.3,-1 14.3,-14.29C28.59,12.41 27.59,11.41 14.29,11.41zM24.56,18.57c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.5 25.35,17.78 24.56,18.57z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.28C1,11.28 0,12.28 0,25.58c0,13.29 1,14.29 14.29,14.29c13.3,0 14.3,-1 14.3,-14.29C28.59,12.28 27.59,11.28 14.29,11.28zM18.79,27.57c0,0.21 -0.02,0.4 -0.04,0.59l1.27,0.99c0.11,0.09 0.14,0.25 0.07,0.38l-1.2,2.08c-0.07,0.13 -0.23,0.19 -0.37,0.13l-1.49,-0.6c-0.31,0.24 -0.65,0.44 -1.02,0.59l-0.22,1.59c-0.02,0.14 -0.15,0.25 -0.3,0.25h-2.4c-0.15,0 -0.27,-0.11 -0.29,-0.25l-0.23,-1.59c-0.37,-0.15 -0.7,-0.35 -1.01,-0.59l-1.5,0.6c-0.13,0.05 -0.29,0 -0.36,-0.13l-1.2,-2.08c-0.08,-0.13 -0.05,-0.29 0.07,-0.38l1.26,-0.99c-0.02,-0.19 -0.04,-0.39 -0.04,-0.59c0,-0.2 0.02,-0.39 0.04,-0.59l-1.26,-0.99c-0.12,-0.09 -0.15,-0.25 -0.07,-0.38l1.2,-2.08c0.07,-0.13 0.22,-0.18 0.36,-0.13l1.5,0.6c0.31,-0.23 0.64,-0.44 1.01,-0.59l0.23,-1.59c0.02,-0.14 0.14,-0.25 0.29,-0.25h2.4c0.15,0 0.28,0.11 0.3,0.25l0.22,1.59c0.37,0.15 0.71,0.35 1.02,0.59l1.49,-0.6c0.13,-0.05 0.3,0 0.37,0.13l1.2,2.08c0.07,0.13 0.04,0.29 -0.07,0.38l-1.27,0.99C18.77,27.18 18.79,27.37 18.79,27.57zM24.56,18.44c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.37 25.35,17.65 24.56,18.44zM14.29,25.47c-1.16,0 -2.1,0.94 -2.1,2.1c0,1.16 0.94,2.1 2.1,2.1s2.1,-0.94 2.1,-2.1C16.39,26.41 15.45,25.47 14.29,25.47z"
android:strokeAlpha="0.54"
android:fillAlpha="0.54"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.84,18.81v0.05c0,0.03 -0.01,0.05 -0.01,0.08c0,0.02 -0.01,0.04 -0.02,0.07c-0.17,0.76 -0.94,1.23 -1.7,1.05c-0.07,-0.01 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.92,-0.76 -0.9,-1.35v-0.08c0,-0.01 0,-0.01 0,-0.01c0.01,-0.05 0.02,-0.1 0.02,-0.15c0.31,-2.26 0.03,-4.5 -0.73,-6.54c-0.12,-0.32 -0.25,-0.64 -0.4,-0.96c-0.06,-0.13 -0.12,-0.26 -0.19,-0.38c-0.04,-0.1 -0.09,-0.19 -0.14,-0.28c-0.05,-0.1 -0.1,-0.2 -0.16,-0.29c-0.01,-0.03 -0.02,-0.05 -0.03,-0.07c-0.05,-0.07 -0.09,-0.15 -0.14,-0.23c-0.04,-0.08 -0.1,-0.17 -0.15,-0.25S35,9.25 34.95,9.17c-0.05,-0.08 -0.11,-0.16 -0.16,-0.24c-0.33,-0.48 -0.68,-0.94 -1.07,-1.37c-0.06,-0.07 -0.12,-0.14 -0.19,-0.21c-0.14,-0.15 -0.29,-0.3 -0.44,-0.45c-0.05,-0.06 -0.11,-0.12 -0.17,-0.17c-0.07,-0.07 -0.14,-0.13 -0.21,-0.2c-0.1,-0.09 -0.2,-0.17 -0.29,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.25c-0.86,-0.66 -1.81,-1.22 -2.83,-1.66c-0.12,-0.06 -0.25,-0.11 -0.38,-0.16c-0.12,-0.05 -0.25,-0.1 -0.38,-0.15c-0.11,-0.04 -0.23,-0.08 -0.34,-0.11c-0.02,-0.01 -0.03,-0.02 -0.05,-0.02c-1.36,-0.46 -2.81,-0.7 -4.28,-0.7c-0.79,0 -1.58,0.07 -2.37,0.21c-0.02,0 -0.05,0.01 -0.07,0.01c-0.68,0.1 -1.36,-0.31 -1.56,-0.99L19.5,2.12c-0.19,-0.74 0.25,-1.5 1,-1.71c0.03,0 0.06,-0.01 0.09,-0.02c0.03,0 0.06,-0.01 0.08,-0.01c2.77,-0.49 5.53,-0.24 8.06,0.61c0.03,0 0.05,0.01 0.07,0.02c0.13,0.04 0.26,0.09 0.38,0.13c0.13,0.05 0.27,0.1 0.4,0.16c0.03,0.01 0.07,0.02 0.1,0.04c1.98,0.8 3.79,1.98 5.32,3.47l0.37,0.37c0.11,0.11 0.21,0.22 0.32,0.34c0.01,0.01 0.03,0.03 0.04,0.05c0.07,0.07 0.14,0.15 0.2,0.22c0.05,0.06 0.1,0.11 0.15,0.17c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.14,0.19 0.21,0.28c0.13,0.17 0.26,0.35 0.38,0.53c0.02,0.02 0.03,0.05 0.05,0.07c0.05,0.09 0.11,0.17 0.16,0.26c0.13,0.19 0.25,0.39 0.37,0.59c0.06,0.1 0.12,0.2 0.18,0.3c0.08,0.15 0.16,0.3 0.24,0.45c0.05,0.09 0.1,0.19 0.15,0.29c0.01,0.01 0.01,0.02 0.02,0.03c0.07,0.15 0.14,0.3 0.21,0.45c0,0.01 0.01,0.02 0.01,0.03c0.14,0.3 0.27,0.62 0.39,0.93c0.01,0.01 0.01,0.02 0.01,0.03c0.01,0.01 0.01,0.01 0.01,0.02c0.01,0.02 0.02,0.05 0.03,0.07C39.87,13.31 40.22,16.04 39.84,18.81z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
<path
android:fillColor="#FF000000"
android:pathData="M34.11,17.63v0.07c-0.01,0.06 -0.02,0.13 -0.03,0.19c-0.18,0.77 -0.95,1.24 -1.71,1.06c-0.06,-0.02 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.91,-0.76 -0.9,-1.35c0.01,-0.06 0.01,-0.12 0.02,-0.18c0.12,-1.83 -0.39,-3.6 -1.38,-5.05c-0.23,-0.35 -0.49,-0.67 -0.77,-0.97l-0.18,-0.18c-0.09,-0.1 -0.19,-0.18 -0.28,-0.27c-0.07,-0.07 -0.15,-0.13 -0.22,-0.19c-0.06,-0.06 -0.13,-0.11 -0.2,-0.16c-0.04,-0.03 -0.08,-0.07 -0.12,-0.1c-0.11,-0.09 -0.23,-0.17 -0.35,-0.25c-0.06,-0.04 -0.12,-0.08 -0.18,-0.12c-0.01,0 -0.01,0 -0.01,0c-0.19,-0.12 -0.38,-0.24 -0.58,-0.34c-0.06,-0.03 -0.13,-0.07 -0.19,-0.1c-0.01,0 -0.02,-0.01 -0.03,-0.01c-0.13,-0.06 -0.25,-0.12 -0.38,-0.17c-0.01,-0.01 -0.02,-0.01 -0.02,-0.01c-1.25,-0.53 -2.63,-0.74 -4.03,-0.58c-0.69,0.1 -1.35,-0.33 -1.54,-1.02c-0.21,-0.76 0.23,-1.54 0.99,-1.75c0.03,-0.01 0.07,-0.01 0.1,-0.02c0.08,-0.01 0.15,-0.02 0.22,-0.02c1.77,-0.2 3.51,0.05 5.1,0.68c0.01,0 0.01,0 0.03,0.01c0.18,0.07 0.36,0.14 0.54,0.22c1.02,0.47 1.97,1.1 2.81,1.87c0.15,0.14 0.3,0.28 0.44,0.43c0.07,0.07 0.14,0.14 0.2,0.21c0.24,0.26 0.46,0.53 0.68,0.81c0.08,0.11 0.16,0.22 0.24,0.34c0.04,0.05 0.08,0.11 0.12,0.17s0.08,0.11 0.12,0.17c0.03,0.06 0.07,0.12 0.11,0.18c0.03,0.05 0.06,0.11 0.09,0.16c0.1,0.16 0.19,0.33 0.28,0.5c0.05,0.09 0.09,0.17 0.13,0.26c0,0 0,0 0.01,0.01c0.04,0.09 0.09,0.19 0.13,0.29c0.01,0.02 0.02,0.04 0.03,0.06c0.01,0.03 0.02,0.06 0.04,0.09C33.93,14.09 34.25,15.84 34.11,17.63z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.41C1,11.41 0,12.41 0,25.71C0,39 1,40 14.29,40c13.3,0 14.3,-1 14.3,-14.29C28.59,12.41 27.59,11.41 14.29,11.41zM18.79,27.7c0,0.21 -0.02,0.4 -0.04,0.59l1.27,0.99c0.11,0.09 0.14,0.25 0.07,0.38l-1.2,2.08c-0.07,0.13 -0.23,0.19 -0.37,0.13l-1.49,-0.6c-0.31,0.24 -0.65,0.44 -1.02,0.59l-0.22,1.59c-0.02,0.14 -0.15,0.25 -0.3,0.25h-2.4c-0.15,0 -0.27,-0.11 -0.29,-0.25l-0.23,-1.59c-0.37,-0.15 -0.7,-0.35 -1.01,-0.59l-1.5,0.6c-0.13,0.05 -0.29,0 -0.36,-0.13l-1.2,-2.08c-0.08,-0.13 -0.05,-0.29 0.07,-0.38l1.26,-0.99C9.81,28.1 9.79,27.9 9.79,27.7c0,-0.2 0.02,-0.39 0.04,-0.59l-1.26,-0.99c-0.12,-0.09 -0.15,-0.25 -0.07,-0.38l1.2,-2.08c0.07,-0.13 0.22,-0.18 0.36,-0.13l1.5,0.6c0.31,-0.23 0.64,-0.44 1.01,-0.59l0.23,-1.59c0.02,-0.14 0.14,-0.25 0.29,-0.25h2.4c0.15,0 0.28,0.11 0.3,0.25l0.22,1.59c0.37,0.15 0.71,0.35 1.02,0.59l1.49,-0.6c0.13,-0.05 0.3,0 0.37,0.13l1.2,2.08c0.07,0.13 0.04,0.29 -0.07,0.38l-1.27,0.99C18.77,27.31 18.79,27.5 18.79,27.7zM24.56,18.57c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.5 25.35,17.78 24.56,18.57zM14.29,25.6c-1.16,0 -2.1,0.94 -2.1,2.1c0,1.16 0.94,2.1 2.1,2.1s2.1,-0.94 2.1,-2.1C16.39,26.54 15.45,25.6 14.29,25.6z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40"
tools:ignore="UnusedResources">
<path
android:fillColor="#FF000000"
android:pathData="M14.3,11.31c-13.26,0 -14.25,1 -14.25,14.26c0,13.26 1,14.25 14.25,14.25c13.27,0 14.26,-1 14.26,-14.25C28.57,12.3 27.57,11.31 14.3,11.31zM22.17,29.73c-0.35,1.15 -1.37,1.95 -2.48,2.06c-1.02,0.1 -1.78,-0.41 -1.99,-0.56c-0.2,0.18 -0.49,0.41 -0.85,0.65c-0.09,0.06 -0.33,0.2 -0.61,0.33c-0.87,0.39 -1.69,0.44 -1.91,0.45c-0.5,0.02 -1.22,-0.03 -2.03,-0.34c-0.68,-0.26 -1.17,-0.62 -1.48,-0.88c-0.17,0.11 -0.43,0.25 -0.78,0.35c-0.31,0.1 -0.95,0.29 -1.69,0.08c-0.6,-0.17 -0.98,-0.53 -1.14,-0.68c-0.17,-0.16 -0.82,-0.81 -0.89,-1.84c-0.04,-0.67 0.2,-1.17 0.28,-1.36c0.23,-0.46 0.53,-0.77 0.72,-0.94c0.18,-0.14 0.43,-0.34 0.82,-0.46c0.41,-0.11 0.76,-0.07 0.94,-0.03c0.1,-0.45 0.32,-1.22 0.89,-2c0.67,-0.93 1.47,-1.39 1.72,-1.53c1.88,-1.02 3.74,-0.45 3.97,-0.38c0.02,0.01 0.05,0.02 0.08,0.03c0.36,0.12 1.58,0.57 2.47,1.78c0.08,0.12 0.22,0.31 0.36,0.57c-0.22,-0.01 -0.76,0.02 -1.3,0.37c-0.4,0.26 -0.62,0.58 -0.73,0.77c-0.32,-0.17 -1.21,-0.59 -2.26,-0.37c-0.31,0.07 -0.87,0.19 -1.33,0.67c-0.43,0.44 -0.55,0.94 -0.57,1.06c-0.13,0.61 0.05,1.1 0.13,1.28c0.01,0.02 0.02,0.04 0.02,0.05c-0.02,-0.14 -0.03,-0.37 0.03,-0.63c0.01,-0.1 0.08,-0.38 0.29,-0.68c0.41,-0.58 1.06,-0.75 1.27,-0.8c0.14,-0.03 0.58,-0.14 1.13,-0.02c0.87,0.17 1.41,0.72 1.6,0.94c0.09,-0.22 0.32,-0.68 0.81,-1.08c0.14,-0.11 0.59,-0.45 1.24,-0.57c1.23,-0.21 2.16,0.49 2.25,0.56C22.04,27.27 22.53,28.52 22.17,29.73zM24.55,18.45c-0.78,0.79 -2.06,0.79 -2.85,0c-0.79,-0.79 -0.79,-2.06 0,-2.85c0.79,-0.79 2.07,-0.79 2.85,0C25.34,16.38 25.34,17.66 24.55,18.45z"
android:strokeAlpha="0.54"
android:fillAlpha="0.54"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.8,18.81v0.05c0,0.03 -0.01,0.05 -0.01,0.08c0,0.02 -0.01,0.04 -0.02,0.07c-0.17,0.76 -0.94,1.23 -1.7,1.05c-0.07,-0.01 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.92,-0.76 -0.9,-1.35v-0.08c0,-0.01 0,-0.01 0,-0.01c0.01,-0.05 0.02,-0.1 0.02,-0.15c0.31,-2.25 0.03,-4.49 -0.73,-6.52c-0.12,-0.32 -0.25,-0.64 -0.4,-0.96c-0.06,-0.13 -0.12,-0.26 -0.19,-0.38c-0.04,-0.1 -0.09,-0.19 -0.14,-0.28c-0.05,-0.1 -0.1,-0.2 -0.16,-0.29c-0.01,-0.03 -0.02,-0.05 -0.03,-0.07c-0.05,-0.07 -0.09,-0.15 -0.14,-0.23c-0.04,-0.08 -0.1,-0.17 -0.15,-0.25s-0.1,-0.16 -0.15,-0.24c-0.05,-0.08 -0.11,-0.16 -0.16,-0.24c-0.33,-0.48 -0.68,-0.94 -1.07,-1.37c-0.06,-0.07 -0.12,-0.14 -0.19,-0.21c-0.14,-0.15 -0.29,-0.3 -0.44,-0.45c-0.05,-0.06 -0.11,-0.12 -0.17,-0.17c-0.07,-0.07 -0.14,-0.13 -0.21,-0.2c-0.1,-0.09 -0.2,-0.17 -0.29,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.25c-0.86,-0.66 -1.81,-1.22 -2.82,-1.66c-0.12,-0.06 -0.25,-0.11 -0.38,-0.16c-0.12,-0.05 -0.25,-0.1 -0.38,-0.15c-0.11,-0.04 -0.23,-0.08 -0.34,-0.11c-0.02,-0.01 -0.03,-0.02 -0.05,-0.02C26.43,3.24 24.99,3 23.52,3c-0.79,0 -1.58,0.07 -2.36,0.21c-0.02,0 -0.05,0.01 -0.07,0.01c-0.68,0.1 -1.36,-0.31 -1.56,-0.99l-0.02,-0.07c-0.19,-0.74 0.25,-1.5 1,-1.71c0.03,0 0.06,-0.01 0.09,-0.02c0.03,0 0.06,-0.01 0.08,-0.01c2.76,-0.49 5.52,-0.24 8.04,0.61c0.03,0 0.05,0.01 0.07,0.02c0.13,0.04 0.26,0.09 0.38,0.13c0.13,0.05 0.27,0.1 0.4,0.16c0.03,0.01 0.07,0.02 0.1,0.04c1.98,0.8 3.78,1.98 5.31,3.46l0.37,0.37c0.11,0.11 0.21,0.22 0.32,0.34c0.01,0.01 0.03,0.03 0.04,0.05c0.07,0.07 0.14,0.15 0.2,0.22c0.05,0.06 0.1,0.11 0.15,0.17c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.14,0.19 0.21,0.28c0.13,0.17 0.26,0.35 0.38,0.53c0.02,0.02 0.03,0.05 0.05,0.07c0.05,0.09 0.11,0.17 0.16,0.26c0.13,0.19 0.25,0.39 0.37,0.59c0.06,0.1 0.12,0.2 0.18,0.3c0.08,0.15 0.16,0.3 0.24,0.45c0.05,0.09 0.1,0.19 0.15,0.29c0.01,0.01 0.01,0.02 0.02,0.03c0.07,0.15 0.14,0.3 0.21,0.45c0,0.01 0.01,0.02 0.01,0.03c0.14,0.3 0.27,0.62 0.39,0.93c0.01,0.01 0.01,0.02 0.01,0.03c0.01,0.01 0.01,0.01 0.01,0.02c0.01,0.02 0.02,0.05 0.03,0.07C39.83,13.32 40.18,16.04 39.8,18.81z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
<path
android:fillColor="#FF000000"
android:pathData="M34.08,17.63v0.07c-0.01,0.06 -0.02,0.13 -0.03,0.19c-0.18,0.77 -0.95,1.24 -1.71,1.06c-0.06,-0.02 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.91,-0.76 -0.9,-1.35c0.01,-0.06 0.01,-0.12 0.02,-0.18c0.12,-1.83 -0.39,-3.59 -1.38,-5.04c-0.23,-0.35 -0.49,-0.67 -0.77,-0.97l-0.18,-0.18c-0.09,-0.1 -0.19,-0.18 -0.28,-0.27c-0.07,-0.07 -0.15,-0.13 -0.22,-0.19c-0.06,-0.06 -0.13,-0.11 -0.2,-0.16c-0.04,-0.03 -0.08,-0.07 -0.12,-0.1c-0.11,-0.09 -0.23,-0.17 -0.35,-0.25c-0.06,-0.04 -0.12,-0.08 -0.18,-0.12c-0.01,0 -0.01,0 -0.01,0c-0.19,-0.12 -0.38,-0.24 -0.58,-0.34c-0.06,-0.03 -0.13,-0.07 -0.19,-0.1c-0.01,0 -0.02,-0.01 -0.03,-0.01c-0.13,-0.06 -0.25,-0.12 -0.38,-0.17c-0.01,-0.01 -0.02,-0.01 -0.02,-0.01c-1.25,-0.53 -2.62,-0.74 -4.02,-0.58c-0.69,0.1 -1.35,-0.33 -1.54,-1.02c-0.21,-0.76 0.23,-1.54 0.99,-1.75c0.03,-0.01 0.07,-0.01 0.1,-0.02c0.08,-0.01 0.15,-0.02 0.22,-0.02c1.77,-0.2 3.5,0.05 5.09,0.68c0.01,0 0.01,0 0.03,0.01c0.18,0.07 0.36,0.14 0.54,0.22c1.02,0.47 1.97,1.1 2.8,1.87c0.15,0.14 0.3,0.28 0.44,0.43c0.07,0.07 0.14,0.14 0.2,0.21c0.24,0.26 0.46,0.53 0.68,0.81c0.08,0.11 0.16,0.22 0.24,0.34c0.04,0.05 0.08,0.11 0.12,0.17c0.04,0.06 0.08,0.11 0.12,0.17c0.03,0.06 0.07,0.12 0.11,0.18c0.03,0.05 0.06,0.11 0.09,0.16c0.1,0.16 0.19,0.33 0.28,0.5c0.05,0.09 0.09,0.17 0.13,0.26c0,0 0,0 0.01,0.01c0.04,0.09 0.09,0.19 0.13,0.29c0.01,0.02 0.02,0.04 0.03,0.06c0.01,0.03 0.02,0.06 0.04,0.09C33.9,14.1 34.22,15.84 34.08,17.63z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40"
tools:ignore="UnusedResources">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.41C1,11.41 0,12.41 0,25.71C0,39 1,40 14.29,40c13.3,0 14.3,-1 14.3,-14.29C28.59,12.41 27.59,11.41 14.29,11.41zM22.18,29.88c-0.35,1.15 -1.37,1.95 -2.49,2.07c-1.02,0.1 -1.78,-0.41 -2,-0.56c-0.2,0.18 -0.49,0.41 -0.85,0.65c-0.09,0.06 -0.33,0.2 -0.61,0.33c-0.87,0.39 -1.69,0.44 -1.91,0.45c-0.5,0.02 -1.22,-0.03 -2.04,-0.34c-0.68,-0.26 -1.17,-0.62 -1.48,-0.88c-0.17,0.11 -0.43,0.25 -0.78,0.35c-0.31,0.1 -0.95,0.29 -1.69,0.08c-0.6,-0.17 -0.98,-0.53 -1.14,-0.68c-0.17,-0.16 -0.82,-0.81 -0.89,-1.84c-0.04,-0.67 0.2,-1.17 0.28,-1.36c0.23,-0.46 0.53,-0.77 0.72,-0.94c0.18,-0.14 0.43,-0.34 0.82,-0.46c0.41,-0.11 0.76,-0.07 0.94,-0.03c0.1,-0.45 0.32,-1.22 0.89,-2.01c0.67,-0.93 1.47,-1.39 1.72,-1.53c1.88,-1.02 3.75,-0.45 3.98,-0.38c0.02,0.01 0.05,0.02 0.08,0.03c0.36,0.12 1.58,0.57 2.48,1.78c0.08,0.12 0.22,0.31 0.36,0.57c-0.22,-0.01 -0.76,0.02 -1.3,0.37c-0.4,0.26 -0.62,0.58 -0.73,0.77c-0.32,-0.17 -1.21,-0.59 -2.27,-0.37c-0.31,0.07 -0.87,0.19 -1.33,0.67c-0.43,0.44 -0.55,0.94 -0.57,1.06c-0.13,0.61 0.05,1.1 0.13,1.28c0.01,0.02 0.02,0.04 0.02,0.05c-0.02,-0.14 -0.03,-0.37 0.03,-0.63c0.01,-0.1 0.08,-0.38 0.29,-0.68c0.41,-0.58 1.06,-0.75 1.27,-0.8c0.14,-0.03 0.58,-0.14 1.13,-0.02c0.87,0.17 1.41,0.72 1.6,0.94c0.09,-0.22 0.32,-0.68 0.81,-1.08c0.14,-0.11 0.59,-0.45 1.24,-0.57c1.23,-0.21 2.17,0.49 2.26,0.56C22.05,27.41 22.54,28.67 22.18,29.88zM24.56,18.57c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.5 25.35,17.78 24.56,18.57z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.28C1,11.28 0,12.28 0,25.58c0,13.29 1,14.29 14.29,14.29c13.3,0 14.3,-1 14.3,-14.29C28.59,12.28 27.59,11.28 14.29,11.28zM22.3,28.53c0,0.82 -0.66,1.49 -1.49,1.49h-0.75v0.3c0,0.82 -0.65,1.49 -1.49,1.49H7.79c-0.82,0 -1.49,-0.67 -1.49,-1.49v-5.48c0,-0.83 0.67,-1.49 1.49,-1.49h10.78c0.84,0 1.49,0.66 1.49,1.49v0.46h0.75c0.83,0 1.49,0.67 1.49,1.49V28.53zM24.56,18.44c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86s2.08,-0.79 2.86,0C25.35,16.37 25.35,17.65 24.56,18.44zM17.99,24.84H13.1c-0.33,0 -0.6,0.27 -0.6,0.6v4.28c0,0.33 0.27,0.6 0.6,0.6h4.89c0.23,0 0.41,-0.12 0.5,-0.3c0.06,-0.09 0.08,-0.19 0.08,-0.3v-4.28c0,-0.05 0,-0.09 -0.02,-0.14C18.5,25.03 18.28,24.84 17.99,24.84z"
android:strokeAlpha="0.54"
android:fillAlpha="0.54"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.85,18.81v0.05c0,0.03 -0.01,0.05 -0.01,0.08c0,0.02 -0.01,0.04 -0.02,0.07c-0.17,0.76 -0.94,1.23 -1.7,1.05c-0.07,-0.01 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.92,-0.76 -0.9,-1.35v-0.08c0,-0.01 0,-0.01 0,-0.01c0.01,-0.05 0.02,-0.1 0.02,-0.15c0.31,-2.26 0.03,-4.5 -0.73,-6.54c-0.12,-0.32 -0.25,-0.64 -0.4,-0.96c-0.06,-0.13 -0.12,-0.26 -0.19,-0.38c-0.04,-0.1 -0.09,-0.19 -0.14,-0.28c-0.05,-0.1 -0.1,-0.2 -0.16,-0.29c-0.01,-0.03 -0.02,-0.05 -0.03,-0.07c-0.05,-0.07 -0.09,-0.15 -0.14,-0.23c-0.04,-0.08 -0.1,-0.17 -0.15,-0.25s-0.1,-0.16 -0.15,-0.24c-0.05,-0.08 -0.11,-0.16 -0.16,-0.24c-0.33,-0.48 -0.68,-0.94 -1.07,-1.37c-0.06,-0.07 -0.12,-0.14 -0.19,-0.21C33.4,7.2 33.25,7.05 33.1,6.9c-0.05,-0.06 -0.11,-0.12 -0.17,-0.17c-0.07,-0.07 -0.14,-0.13 -0.21,-0.2c-0.1,-0.09 -0.2,-0.17 -0.29,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.26C32,5.92 31.9,5.84 31.79,5.76c-0.86,-0.66 -1.81,-1.22 -2.83,-1.66c-0.12,-0.06 -0.25,-0.11 -0.38,-0.16c-0.12,-0.05 -0.25,-0.1 -0.38,-0.15c-0.11,-0.04 -0.23,-0.08 -0.34,-0.11c-0.02,-0.01 -0.03,-0.02 -0.05,-0.02c-1.36,-0.46 -2.81,-0.7 -4.28,-0.7c-0.79,0 -1.58,0.07 -2.37,0.21c-0.02,0 -0.05,0.01 -0.07,0.01c-0.68,0.1 -1.36,-0.31 -1.56,-0.99l-0.02,-0.07c-0.19,-0.74 0.25,-1.5 1,-1.71c0.03,0 0.06,-0.01 0.09,-0.02c0.03,0 0.06,-0.01 0.08,-0.01c2.77,-0.49 5.53,-0.24 8.06,0.61c0.03,0 0.05,0.01 0.07,0.02c0.13,0.04 0.26,0.09 0.38,0.13c0.13,0.05 0.27,0.1 0.4,0.16c0.03,0.01 0.07,0.02 0.1,0.04c1.98,0.8 3.79,1.98 5.32,3.47l0.37,0.37c0.11,0.11 0.21,0.22 0.32,0.34c0.01,0.01 0.03,0.03 0.04,0.05c0.07,0.07 0.14,0.15 0.2,0.22c0.05,0.06 0.1,0.11 0.15,0.17c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.14,0.19 0.21,0.28c0.13,0.17 0.26,0.35 0.38,0.53c0.02,0.02 0.03,0.05 0.05,0.07c0.05,0.09 0.11,0.17 0.16,0.26c0.13,0.19 0.25,0.39 0.37,0.59c0.06,0.1 0.12,0.2 0.18,0.3c0.08,0.15 0.16,0.3 0.24,0.45c0.05,0.09 0.1,0.19 0.15,0.29c0.01,0.01 0.01,0.02 0.02,0.03c0.07,0.15 0.14,0.3 0.21,0.45c0,0.01 0.01,0.02 0.01,0.03c0.14,0.3 0.27,0.62 0.39,0.93c0.01,0.01 0.01,0.02 0.01,0.03c0.01,0.01 0.01,0.01 0.01,0.02c0.01,0.02 0.02,0.05 0.03,0.07C39.88,13.31 40.23,16.04 39.85,18.81z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
<path
android:fillColor="#FF000000"
android:pathData="M34.12,17.63v0.07c-0.01,0.06 -0.02,0.13 -0.03,0.19c-0.18,0.77 -0.95,1.24 -1.71,1.06c-0.06,-0.02 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.91,-0.76 -0.9,-1.35c0.01,-0.06 0.01,-0.12 0.02,-0.18c0.12,-1.83 -0.39,-3.6 -1.38,-5.05c-0.23,-0.35 -0.49,-0.67 -0.77,-0.97l-0.18,-0.18c-0.09,-0.1 -0.19,-0.18 -0.28,-0.27c-0.07,-0.07 -0.15,-0.13 -0.22,-0.19c-0.06,-0.06 -0.13,-0.11 -0.2,-0.16c-0.04,-0.03 -0.08,-0.07 -0.12,-0.1c-0.11,-0.09 -0.23,-0.17 -0.35,-0.25c-0.06,-0.04 -0.12,-0.08 -0.18,-0.12c-0.01,0 -0.01,0 -0.01,0c-0.19,-0.12 -0.38,-0.24 -0.58,-0.34c-0.06,-0.03 -0.13,-0.07 -0.19,-0.1c-0.01,0 -0.02,-0.01 -0.03,-0.01c-0.13,-0.06 -0.25,-0.12 -0.38,-0.17c-0.01,-0.01 -0.02,-0.01 -0.02,-0.01c-1.25,-0.53 -2.63,-0.74 -4.03,-0.58c-0.69,0.1 -1.35,-0.33 -1.54,-1.02c-0.21,-0.76 0.23,-1.54 0.99,-1.75c0.03,-0.01 0.07,-0.01 0.1,-0.02c0.08,-0.01 0.15,-0.02 0.22,-0.02c1.77,-0.2 3.51,0.05 5.1,0.68c0.01,0 0.01,0 0.03,0.01c0.18,0.07 0.36,0.14 0.54,0.22c1.02,0.47 1.97,1.1 2.81,1.87c0.15,0.14 0.3,0.28 0.44,0.43c0.07,0.07 0.14,0.14 0.2,0.21c0.24,0.26 0.46,0.53 0.68,0.81c0.08,0.11 0.16,0.22 0.24,0.34c0.04,0.05 0.08,0.11 0.12,0.17s0.08,0.11 0.12,0.17c0.03,0.06 0.07,0.12 0.11,0.18c0.03,0.05 0.06,0.11 0.09,0.16c0.1,0.16 0.19,0.33 0.28,0.5c0.05,0.09 0.09,0.17 0.13,0.26c0,0 0,0 0.01,0.01c0.04,0.09 0.09,0.19 0.13,0.29c0.01,0.02 0.02,0.04 0.03,0.06c0.01,0.03 0.02,0.06 0.04,0.09C33.94,14.09 34.26,15.84 34.12,17.63z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.41C1,11.41 0,12.41 0,25.71C0,39 1,40 14.29,40c13.3,0 14.3,-1 14.3,-14.29C28.59,12.41 27.59,11.41 14.29,11.41zM22.3,28.66c0,0.82 -0.66,1.49 -1.49,1.49h-0.75v0.3c0,0.82 -0.65,1.49 -1.49,1.49H7.79c-0.82,0 -1.49,-0.67 -1.49,-1.49v-5.48c0,-0.83 0.67,-1.49 1.49,-1.49h10.78c0.84,0 1.49,0.66 1.49,1.49v0.46h0.75c0.83,0 1.49,0.67 1.49,1.49V28.66zM24.56,18.57c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86s2.08,-0.79 2.86,0C25.35,16.5 25.35,17.78 24.56,18.57zM17.99,24.97H13.1c-0.33,0 -0.6,0.27 -0.6,0.6v4.28c0,0.33 0.27,0.6 0.6,0.6h4.89c0.23,0 0.41,-0.12 0.5,-0.3c0.06,-0.09 0.08,-0.19 0.08,-0.3v-4.28c0,-0.05 0,-0.09 -0.02,-0.14C18.5,25.16 18.28,24.97 17.99,24.97z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.28C1,11.28 0,12.28 0,25.58c0,13.29 1,14.29 14.29,14.29c13.3,0 14.3,-1 14.3,-14.29C28.59,12.28 27.59,11.28 14.29,11.28zM13.55,25.71c0.22,-0.14 0.48,-0.21 0.75,-0.21s0.53,0.07 0.74,0.21c0.46,0.25 0.76,0.74 0.76,1.3s-0.3,1.04 -0.76,1.29c-0.21,0.14 -0.47,0.21 -0.74,0.21s-0.53,-0.07 -0.75,-0.21c-0.45,-0.25 -0.76,-0.73 -0.76,-1.29S13.1,25.96 13.55,25.71zM7.3,26.49c0.16,-2.2 1.33,-4.11 3.05,-5.28c0.23,-0.16 0.55,-0.07 0.69,0.17l1.99,3.44c-0.75,0.44 -1.26,1.26 -1.26,2.19H7.79C7.51,27.01 7.28,26.77 7.3,26.49zM17.35,33.32c-0.92,0.45 -1.96,0.7 -3.05,0.7c-1.1,0 -2.14,-0.25 -3.06,-0.7c-0.26,-0.12 -0.34,-0.44 -0.2,-0.69l1.99,-3.44c0.37,0.22 0.81,0.34 1.27,0.34c0.46,0 0.89,-0.12 1.26,-0.34l1.99,3.44C17.69,32.88 17.61,33.2 17.35,33.32zM20.8,27.01h-3.98c0,-0.93 -0.51,-1.76 -1.26,-2.19l1.99,-3.44c0.14,-0.24 0.46,-0.33 0.69,-0.17c1.72,1.17 2.89,3.08 3.05,5.28C21.31,26.77 21.08,27.01 20.8,27.01zM24.56,18.44c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.37 25.35,17.65 24.56,18.44z"
android:strokeAlpha="0.54"
android:fillAlpha="0.54"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.85,18.81v0.05c0,0.03 -0.01,0.05 -0.01,0.08c0,0.02 -0.01,0.04 -0.02,0.07c-0.17,0.76 -0.94,1.23 -1.7,1.05c-0.07,-0.01 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.92,-0.76 -0.9,-1.35v-0.08c0,-0.01 0,-0.01 0,-0.01c0.01,-0.05 0.02,-0.1 0.02,-0.15c0.31,-2.26 0.03,-4.5 -0.73,-6.54c-0.12,-0.32 -0.25,-0.64 -0.4,-0.96c-0.06,-0.13 -0.12,-0.26 -0.19,-0.38c-0.04,-0.1 -0.09,-0.19 -0.14,-0.28c-0.05,-0.1 -0.1,-0.2 -0.16,-0.29c-0.01,-0.03 -0.02,-0.05 -0.03,-0.07c-0.05,-0.07 -0.09,-0.15 -0.14,-0.23c-0.04,-0.08 -0.1,-0.17 -0.15,-0.25c-0.05,-0.08 -0.1,-0.16 -0.15,-0.24c-0.05,-0.08 -0.11,-0.16 -0.16,-0.24c-0.33,-0.48 -0.68,-0.94 -1.07,-1.37c-0.06,-0.07 -0.12,-0.14 -0.19,-0.21C33.4,7.2 33.25,7.05 33.1,6.9c-0.05,-0.06 -0.11,-0.12 -0.17,-0.17c-0.07,-0.07 -0.14,-0.13 -0.21,-0.2c-0.1,-0.09 -0.2,-0.17 -0.29,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.26C32,5.92 31.9,5.84 31.79,5.76c-0.86,-0.66 -1.81,-1.22 -2.83,-1.66c-0.12,-0.06 -0.25,-0.11 -0.38,-0.16c-0.12,-0.05 -0.25,-0.1 -0.38,-0.15c-0.11,-0.04 -0.23,-0.08 -0.34,-0.11c-0.02,-0.01 -0.03,-0.02 -0.05,-0.02c-1.36,-0.46 -2.81,-0.7 -4.28,-0.7c-0.79,0 -1.58,0.07 -2.37,0.21c-0.02,0 -0.05,0.01 -0.07,0.01c-0.68,0.1 -1.36,-0.31 -1.56,-0.99l-0.02,-0.07c-0.19,-0.74 0.25,-1.5 1,-1.71c0.03,0 0.06,-0.01 0.09,-0.02c0.03,0 0.06,-0.01 0.08,-0.01c2.77,-0.49 5.53,-0.24 8.06,0.61c0.03,0 0.05,0.01 0.07,0.02c0.13,0.04 0.26,0.09 0.38,0.13c0.13,0.05 0.27,0.1 0.4,0.16c0.03,0.01 0.07,0.02 0.1,0.04c1.98,0.8 3.79,1.98 5.32,3.47l0.37,0.37c0.11,0.11 0.21,0.22 0.32,0.34c0.01,0.01 0.03,0.03 0.04,0.05c0.07,0.07 0.14,0.15 0.2,0.22c0.05,0.06 0.1,0.11 0.15,0.17c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.14,0.19 0.21,0.28c0.13,0.17 0.26,0.35 0.38,0.53c0.02,0.02 0.03,0.05 0.05,0.07c0.05,0.09 0.11,0.17 0.16,0.26c0.13,0.19 0.25,0.39 0.37,0.59c0.06,0.1 0.12,0.2 0.18,0.3c0.08,0.15 0.16,0.3 0.24,0.45c0.05,0.09 0.1,0.19 0.15,0.29c0.01,0.01 0.01,0.02 0.02,0.03c0.07,0.15 0.14,0.3 0.21,0.45c0,0.01 0.01,0.02 0.01,0.03c0.14,0.3 0.27,0.62 0.39,0.93c0.01,0.01 0.01,0.02 0.01,0.03c0.01,0.01 0.01,0.01 0.01,0.02c0.01,0.02 0.02,0.05 0.03,0.07C39.88,13.31 40.23,16.04 39.85,18.81z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"
tools:ignore="VectorPath" />
<path
android:fillColor="#FF000000"
android:pathData="M34.12,17.63v0.07c-0.01,0.06 -0.02,0.13 -0.03,0.19c-0.18,0.77 -0.95,1.24 -1.71,1.06c-0.06,-0.02 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.91,-0.76 -0.9,-1.35c0.01,-0.06 0.01,-0.12 0.02,-0.18c0.12,-1.83 -0.39,-3.6 -1.38,-5.05c-0.23,-0.35 -0.49,-0.67 -0.77,-0.97l-0.18,-0.18c-0.09,-0.1 -0.19,-0.18 -0.28,-0.27c-0.07,-0.07 -0.15,-0.13 -0.22,-0.19c-0.06,-0.06 -0.13,-0.11 -0.2,-0.16c-0.04,-0.03 -0.08,-0.07 -0.12,-0.1c-0.11,-0.09 -0.23,-0.17 -0.35,-0.25c-0.06,-0.04 -0.12,-0.08 -0.18,-0.12c-0.01,0 -0.01,0 -0.01,0c-0.19,-0.12 -0.38,-0.24 -0.58,-0.34c-0.06,-0.03 -0.13,-0.07 -0.19,-0.1c-0.01,0 -0.02,-0.01 -0.03,-0.01c-0.13,-0.06 -0.25,-0.12 -0.38,-0.17c-0.01,-0.01 -0.02,-0.01 -0.02,-0.01c-1.25,-0.53 -2.63,-0.74 -4.03,-0.58c-0.69,0.1 -1.35,-0.33 -1.54,-1.02c-0.21,-0.76 0.23,-1.54 0.99,-1.75c0.03,-0.01 0.07,-0.01 0.1,-0.02c0.08,-0.01 0.15,-0.02 0.22,-0.02c1.77,-0.2 3.51,0.05 5.1,0.68c0.01,0 0.01,0 0.03,0.01c0.18,0.07 0.36,0.14 0.54,0.22c1.02,0.47 1.97,1.1 2.81,1.87c0.15,0.14 0.3,0.28 0.44,0.43c0.07,0.07 0.14,0.14 0.2,0.21c0.24,0.26 0.46,0.53 0.68,0.81c0.08,0.11 0.16,0.22 0.24,0.34c0.04,0.05 0.08,0.11 0.12,0.17s0.08,0.11 0.12,0.17c0.03,0.06 0.07,0.12 0.11,0.18c0.03,0.05 0.06,0.11 0.09,0.16c0.1,0.16 0.19,0.33 0.28,0.5c0.05,0.09 0.09,0.17 0.13,0.26c0,0 0,0 0.01,0.01c0.04,0.09 0.09,0.19 0.13,0.29c0.01,0.02 0.02,0.04 0.03,0.06c0.01,0.03 0.02,0.06 0.04,0.09C33.94,14.09 34.26,15.84 34.12,17.63z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.28C1,11.28 0,12.28 0,25.58c0,13.29 1,14.29 14.29,14.29c13.3,0 14.3,-1 14.3,-14.29C28.59,12.28 27.59,11.28 14.29,11.28zM13.55,25.71c0.22,-0.14 0.48,-0.21 0.75,-0.21s0.53,0.07 0.74,0.21c0.46,0.25 0.76,0.74 0.76,1.3s-0.3,1.04 -0.76,1.29c-0.21,0.14 -0.47,0.21 -0.74,0.21s-0.53,-0.07 -0.75,-0.21c-0.45,-0.25 -0.76,-0.73 -0.76,-1.29S13.1,25.96 13.55,25.71zM7.3,26.49c0.16,-2.2 1.33,-4.11 3.05,-5.28c0.23,-0.16 0.55,-0.07 0.69,0.17l1.99,3.44c-0.75,0.44 -1.26,1.26 -1.26,2.19H7.79C7.51,27.01 7.28,26.77 7.3,26.49zM17.35,33.32c-0.92,0.45 -1.96,0.7 -3.05,0.7c-1.1,0 -2.14,-0.25 -3.06,-0.7c-0.26,-0.12 -0.34,-0.44 -0.2,-0.69l1.99,-3.44c0.37,0.22 0.81,0.34 1.27,0.34c0.46,0 0.89,-0.12 1.26,-0.34l1.99,3.44C17.69,32.88 17.61,33.2 17.35,33.32zM20.8,27.01h-3.98c0,-0.93 -0.51,-1.76 -1.26,-2.19l1.99,-3.44c0.14,-0.24 0.46,-0.33 0.69,-0.17c1.72,1.17 2.89,3.08 3.05,5.28C21.31,26.77 21.08,27.01 20.8,27.01zM24.56,18.44c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.37 25.35,17.65 24.56,18.44z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.32,11.32C1.09,11.32 0.1,12.32 0.1,25.55c0,13.22 0.99,14.22 14.22,14.22c13.23,0 14.23,-0.99 14.23,-14.22C28.55,12.32 27.55,11.32 14.32,11.32zM13.65,20.79c0,-0.38 0.3,-0.68 0.68,-0.68h0.01c0.38,0 0.68,0.3 0.68,0.68v1.33c0,0.37 -0.3,0.67 -0.69,0.67c-0.38,0 -0.68,-0.3 -0.68,-0.68V20.79zM9.07,22.29L9.07,22.29c0.27,-0.27 0.7,-0.27 0.96,-0.01l0.95,0.95c0.13,0.13 0.2,0.3 0.2,0.48c0,0.17 -0.07,0.34 -0.21,0.48c-0.27,0.27 -0.69,0.27 -0.96,0l-0.94,-0.95C8.81,22.98 8.81,22.56 9.07,22.29zM6.87,27.54L6.87,27.54c0,-0.38 0.3,-0.68 0.67,-0.68h1.37c0.38,0 0.68,0.3 0.68,0.68v0.01c0,0.37 -0.3,0.67 -0.68,0.66H7.53C7.16,28.21 6.87,27.91 6.87,27.54zM10.97,31.85L10,32.82c-0.26,0.27 -0.69,0.27 -0.95,0H9.04c-0.26,-0.27 -0.26,-0.69 0,-0.96l0.98,-0.97c0.26,-0.27 0.69,-0.27 0.96,0v0.01C11.24,31.16 11.24,31.59 10.97,31.85zM15,34.3c0,0.38 -0.3,0.68 -0.68,0.68c-0.38,0 -0.68,-0.3 -0.68,-0.68v-1.32c0,-0.38 0.3,-0.68 0.68,-0.68c0.38,0 0.68,0.3 0.68,0.68V34.3zM14.33,30.37c-1.56,0 -2.83,-1.26 -2.83,-2.83c0,-1.56 1.26,-2.84 2.83,-2.84s2.84,1.27 2.84,2.84C17.16,29.1 15.89,30.37 14.33,30.37zM17.68,23.22l0.97,-0.97c0.27,-0.26 0.69,-0.26 0.96,0v0.01c0.27,0.26 0.27,0.69 0,0.95l-0.97,0.97c-0.26,0.27 -0.69,0.27 -0.95,0h-0.01C17.42,23.91 17.42,23.49 17.68,23.22zM19.58,32.8c-0.27,0.27 -0.69,0.27 -0.96,0l-0.94,-0.94c-0.14,-0.14 -0.2,-0.31 -0.2,-0.48c0,-0.17 0.06,-0.34 0.2,-0.48c0.27,-0.27 0.69,-0.27 0.96,0l0.94,0.94C19.85,32.11 19.85,32.53 19.58,32.8zM21.79,27.54c0,0.37 -0.3,0.67 -0.68,0.67h-1.36c-0.37,0 -0.67,-0.3 -0.67,-0.67v-0.01c0,-0.37 0.3,-0.67 0.67,-0.67h1.36C21.49,26.87 21.79,27.16 21.79,27.54L21.79,27.54zM24.54,18.45c-0.78,0.79 -2.06,0.79 -2.85,0c-0.79,-0.79 -0.79,-2.06 0,-2.85c0.79,-0.79 2.07,-0.79 2.85,0C25.32,16.39 25.32,17.66 24.54,18.45z"
android:strokeAlpha="0.54"
android:fillAlpha="0.54"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.75,18.81v0.05c0,0.03 -0.01,0.05 -0.01,0.08c0,0.02 -0.01,0.04 -0.02,0.07c-0.17,0.76 -0.94,1.22 -1.69,1.04c-0.07,-0.01 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.92,-0.76 -0.9,-1.34v-0.08c0,-0.01 0,-0.01 0,-0.01c0.01,-0.05 0.02,-0.1 0.02,-0.15c0.31,-2.25 0.03,-4.48 -0.73,-6.51c-0.12,-0.32 -0.25,-0.64 -0.4,-0.96c-0.06,-0.13 -0.12,-0.26 -0.19,-0.38c-0.04,-0.1 -0.09,-0.19 -0.14,-0.28c-0.05,-0.1 -0.1,-0.2 -0.16,-0.29c-0.01,-0.03 -0.02,-0.05 -0.03,-0.07c-0.05,-0.07 -0.09,-0.15 -0.14,-0.23c-0.04,-0.08 -0.1,-0.17 -0.15,-0.25c-0.05,-0.08 -0.1,-0.16 -0.15,-0.24c-0.05,-0.08 -0.11,-0.16 -0.16,-0.24c-0.33,-0.48 -0.68,-0.94 -1.06,-1.36c-0.06,-0.07 -0.12,-0.14 -0.19,-0.21c-0.14,-0.15 -0.29,-0.3 -0.44,-0.45c-0.05,-0.06 -0.11,-0.12 -0.17,-0.17c-0.07,-0.07 -0.14,-0.13 -0.21,-0.2c-0.1,-0.09 -0.2,-0.17 -0.29,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.26c-0.11,-0.09 -0.21,-0.17 -0.32,-0.25c-0.86,-0.66 -1.8,-1.21 -2.82,-1.65c-0.12,-0.06 -0.25,-0.11 -0.38,-0.16c-0.12,-0.05 -0.25,-0.1 -0.38,-0.15c-0.11,-0.04 -0.23,-0.08 -0.34,-0.11c-0.02,-0.01 -0.03,-0.02 -0.05,-0.02c-1.35,-0.46 -2.8,-0.7 -4.26,-0.7c-0.79,0 -1.57,0.07 -2.36,0.21c-0.02,0 -0.05,0.01 -0.07,0.01c-0.68,0.1 -1.35,-0.31 -1.55,-0.99l-0.02,-0.07c-0.19,-0.74 0.25,-1.49 0.99,-1.7c0.03,0 0.06,-0.01 0.09,-0.02c0.03,0 0.06,-0.01 0.08,-0.01c2.76,-0.49 5.5,-0.24 8.02,0.61c0.03,0 0.05,0.01 0.07,0.02c0.13,0.04 0.26,0.09 0.38,0.13c0.13,0.05 0.27,0.1 0.4,0.16c0.03,0.01 0.07,0.02 0.1,0.04c1.97,0.8 3.77,1.97 5.29,3.45l0.37,0.37c0.11,0.11 0.21,0.22 0.32,0.34c0.01,0.01 0.03,0.03 0.04,0.05c0.07,0.07 0.14,0.15 0.2,0.22c0.05,0.06 0.1,0.11 0.15,0.17c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.15,0.18 0.22,0.27c0.07,0.09 0.14,0.19 0.21,0.28c0.13,0.17 0.26,0.35 0.38,0.53c0.02,0.02 0.03,0.05 0.05,0.07c0.05,0.09 0.11,0.17 0.16,0.26c0.13,0.19 0.25,0.39 0.37,0.59c0.06,0.1 0.12,0.2 0.18,0.3c0.08,0.15 0.16,0.3 0.24,0.45c0.05,0.09 0.1,0.19 0.15,0.29c0.01,0.01 0.01,0.02 0.02,0.03c0.07,0.15 0.14,0.3 0.21,0.45c0,0.01 0.01,0.02 0.01,0.03c0.14,0.3 0.27,0.62 0.39,0.93c0.01,0.01 0.01,0.02 0.01,0.03c0.01,0.01 0.01,0.01 0.01,0.02c0.01,0.02 0.02,0.05 0.03,0.07C39.78,13.34 40.13,16.06 39.75,18.81z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
<path
android:fillColor="#FF000000"
android:pathData="M34.05,17.64v0.07c-0.01,0.06 -0.02,0.13 -0.03,0.19c-0.18,0.77 -0.95,1.23 -1.7,1.05c-0.06,-0.02 -0.13,-0.04 -0.19,-0.06c-0.56,-0.22 -0.91,-0.76 -0.9,-1.34c0.01,-0.06 0.01,-0.12 0.02,-0.18c0.12,-1.82 -0.39,-3.58 -1.37,-5.02c-0.23,-0.35 -0.49,-0.67 -0.77,-0.97l-0.18,-0.18c-0.09,-0.1 -0.19,-0.18 -0.28,-0.27c-0.07,-0.07 -0.15,-0.13 -0.22,-0.19c-0.06,-0.06 -0.13,-0.11 -0.2,-0.16c-0.04,-0.03 -0.08,-0.07 -0.12,-0.1c-0.11,-0.09 -0.23,-0.17 -0.35,-0.25c-0.06,-0.04 -0.12,-0.08 -0.18,-0.12c-0.01,0 -0.01,0 -0.01,0C27.39,10 27.2,9.88 27,9.78c-0.06,-0.03 -0.13,-0.07 -0.19,-0.1c-0.01,0 -0.02,-0.01 -0.03,-0.01c-0.13,-0.06 -0.25,-0.12 -0.38,-0.17c-0.01,-0.01 -0.02,-0.01 -0.02,-0.01c-1.24,-0.53 -2.62,-0.74 -4.01,-0.58c-0.69,0.1 -1.34,-0.33 -1.53,-1.01c-0.21,-0.76 0.23,-1.53 0.99,-1.74c0.03,-0.01 0.07,-0.01 0.1,-0.02c0.08,-0.01 0.15,-0.02 0.22,-0.02c1.76,-0.2 3.49,0.05 5.07,0.68c0.01,0 0.01,0 0.03,0.01c0.18,0.07 0.36,0.14 0.54,0.22c1.01,0.47 1.96,1.09 2.8,1.86c0.15,0.14 0.3,0.28 0.44,0.43c0.07,0.07 0.14,0.14 0.2,0.21c0.24,0.26 0.46,0.53 0.68,0.81c0.08,0.11 0.16,0.22 0.24,0.34c0.04,0.05 0.08,0.11 0.12,0.17c0.04,0.06 0.08,0.11 0.12,0.17c0.03,0.06 0.07,0.12 0.11,0.18c0.03,0.05 0.06,0.11 0.09,0.16c0.1,0.16 0.19,0.33 0.28,0.5c0.05,0.09 0.09,0.17 0.13,0.26c0,0 0,0 0.01,0.01c0.04,0.09 0.09,0.19 0.13,0.29c0.01,0.02 0.02,0.04 0.03,0.06c0.01,0.03 0.02,0.06 0.04,0.09C33.87,14.12 34.19,15.86 34.05,17.64z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="#FF000000"
android:pathData="M14.29,11.41C1,11.41 0,12.41 0,25.71C0,39 1,40 14.29,40c13.3,0 14.3,-1 14.3,-14.29C28.59,12.41 27.59,11.41 14.29,11.41zM13.62,20.92c0,-0.38 0.3,-0.68 0.68,-0.68h0.01c0.38,0 0.68,0.3 0.68,0.68v1.34c0,0.37 -0.3,0.67 -0.69,0.67c-0.38,0 -0.68,-0.3 -0.68,-0.68V20.92zM9.02,22.43l0.01,-0.01c0.26,-0.26 0.69,-0.26 0.95,0l0.95,0.95c0.13,0.13 0.2,0.3 0.2,0.48c0,0.17 -0.07,0.34 -0.21,0.48c-0.27,0.27 -0.69,0.27 -0.96,0l-0.94,-0.95C8.75,23.12 8.75,22.7 9.02,22.43zM6.8,27.71V27.7c0,-0.37 0.3,-0.67 0.67,-0.67h1.38c0.38,0 0.68,0.3 0.68,0.68v0.01c0,0.37 -0.3,0.67 -0.68,0.66H7.47C7.1,28.38 6.8,28.08 6.8,27.71zM10.92,32.04l-0.97,0.97c-0.26,0.27 -0.69,0.27 -0.95,0H8.99c-0.26,-0.27 -0.26,-0.69 0,-0.96l0.98,-0.97c0.26,-0.27 0.69,-0.27 0.96,0v0.01C11.2,31.35 11.2,31.78 10.92,32.04zM14.98,34.5c0,0.38 -0.3,0.68 -0.68,0.68s-0.68,-0.3 -0.68,-0.68v-1.33c0,-0.38 0.3,-0.68 0.68,-0.68s0.68,0.3 0.68,0.68V34.5zM14.3,30.55c-1.57,0 -2.84,-1.27 -2.84,-2.84s1.27,-2.85 2.84,-2.85s2.85,1.28 2.85,2.85S15.87,30.55 14.3,30.55zM17.67,23.37l0.97,-0.97c0.27,-0.26 0.69,-0.26 0.96,0v0.01c0.27,0.26 0.27,0.69 0,0.95l-0.97,0.97c-0.26,0.27 -0.69,0.27 -0.95,0h-0.01C17.41,24.06 17.41,23.64 17.67,23.37zM19.58,32.99c-0.27,0.27 -0.69,0.27 -0.96,0l-0.94,-0.94c-0.14,-0.14 -0.2,-0.31 -0.2,-0.48c0,-0.17 0.06,-0.34 0.2,-0.48c0.27,-0.27 0.69,-0.27 0.96,0l0.94,0.94C19.85,32.3 19.85,32.72 19.58,32.99zM21.8,27.71c0,0.37 -0.3,0.67 -0.68,0.67h-1.37c-0.37,0 -0.67,-0.3 -0.67,-0.67V27.7c0,-0.37 0.3,-0.67 0.67,-0.67h1.37c0.38,0 0.68,0.3 0.68,0.67V27.71zM24.56,18.57c-0.78,0.79 -2.07,0.79 -2.86,0c-0.79,-0.79 -0.79,-2.07 0,-2.86c0.79,-0.79 2.08,-0.79 2.86,0C25.35,16.5 25.35,17.78 24.56,18.57z"
android:strokeAlpha="0.22"
android:fillAlpha="0.22"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M3,17.46v3.04c0,0.28 0.22,0.5 0.5,0.5h3.04c0.13,0 0.26,-0.05 0.35,-0.15L17.81,9.94l-3.75,-3.75L3.15,17.1c-0.1,0.1 -0.15,0.22 -0.15,0.36zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M6.84,14.04L6.84,14.04c0.47,0.47 1.21,0.47 1.68,0l2.28,-2.28l0,11.04c0,0.66 0.54,1.2 1.2,1.2l0,0c0.66,0 1.2,-0.54 1.2,-1.2l0,-11.04l2.28,2.28c0.47,0.47 1.21,0.47 1.68,0l0,0c0.47,-0.47 0.47,-1.21 0,-1.68l-4.31,-4.31c-0.47,-0.47 -1.22,-0.47 -1.69,0l-4.32,4.31C6.37,12.83 6.37,13.57 6.84,14.04zM20.4,2.4l0,4.8c0,0.66 0.54,1.2 1.2,1.2l0,0c0.66,0 1.2,-0.54 1.2,-1.2l0,-4.8c0,-1.32 -1.08,-2.4 -2.4,-2.4L3.6,0C2.28,0 1.2,1.08 1.2,2.4l0,4.8c0,0.66 0.54,1.2 1.2,1.2l0,0c0.66,0 1.2,-0.54 1.2,-1.2l0,-4.8L20.4,2.4z"/>
</vector>

View File

@@ -101,6 +101,7 @@
<string name="text_device_firmware">Версія прашыўкі</string>
<string name="text_device_location">Месцазнаходжанне</string>
<string name="text_device_location_unset">Прылада не зарэгістравана</string>
<string name="text_device_connected">падлучана</string>
<string name="text_device_visibility">Бачнасць</string>
<string name="text_device_visibility_visible">Апублікавана</string>
<string name="text_device_visibility_private">Схавана</string>

View File

@@ -101,6 +101,7 @@
<string name="text_device_firmware">Версия прошивки</string>
<string name="text_device_location">Местоположение</string>
<string name="text_device_location_unset">Устройство не зарегистрировано</string>
<string name="text_device_connected">подключено</string>
<string name="text_device_visibility">Видимость</string>
<string name="text_device_visibility_visible">Опубликовано</string>
<string name="text_device_visibility_private">Скрыто</string>

View File

@@ -11,9 +11,13 @@
<color name="sensorGreen">#FF00C853</color>
<color name="sensorYellow">#FFFFD54F</color>
<color name="sensorOrange">#FFFF9800</color>
<color name="colorGreen">#FF00C853</color>
<color name="colorOrange">#FFFF6F00</color>
<color name="sensorRed">#FFF44336</color>
<color name="sensorPink">#FFEC407A</color>
<color name="sensorPurple">#FF8E24AA</color>
<color name="black38">#61000000</color>
<color name="black54">#8A000000</color>
<color name="headerColor">#1F5DA5</color>
<color name="windowBackground">#FAFAFA</color>
</resources>

View File

@@ -158,6 +158,7 @@
<string name="text_device_location">Location</string>
<string name="text_device_location_unset">Device is not registered</string>
<string name="text_device_location_set" translatable="false">%s, %s</string>
<string name="text_device_connected">connected</string>
<string name="text_device_visibility">Visibility</string>
<string name="text_device_visibility_visible">Public</string>
<string name="text_device_visibility_private">Private</string>