Commit f1a3899d authored by clairehurst's avatar clairehurst 🌱 Committed by Pier Angelo Vendrame
Browse files

TB 44031 [android]: 2025 YEC

# Conflicts:
#	mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
parent 3ed7a537
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -161,8 +161,10 @@ import org.mozilla.fenix.wallpapers.Wallpaper
import org.mozilla.fenix.GleanMetrics.TabStrip as TabStripMetrics

import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.tor.TorCampaignViewModel
import org.mozilla.fenix.tor.TorHomePage
import org.mozilla.fenix.tor.UrlQuickLoadViewModel
import java.util.Locale

@Suppress("TooManyFunctions", "LargeClass")
class HomeFragment : Fragment(), UserInteractionHandler {
@@ -177,6 +179,7 @@ class HomeFragment : Fragment(), UserInteractionHandler {
    internal val binding get() = _binding!!
    private val snackbarBinding = ViewBoundFeatureWrapper<SnackbarBinding>()

    private val torCampaignViewModel: TorCampaignViewModel by activityViewModels()
    private val homeViewModel: HomeScreenViewModel by activityViewModels()
    private val urlQuickLoadViewModel: UrlQuickLoadViewModel by activityViewModels()

@@ -974,6 +977,17 @@ class HomeFragment : Fragment(), UserInteractionHandler {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                TorHomePage(
                    torCampaignViewModel.shouldInitiallyShowPromo,
                    onClicked = {
                        val baseUrl =  "https://www.torproject.org/donate"
                        val locale = Locale.getDefault().getLanguage()
                        val donateUrl = "${baseUrl}/donate-${locale}-yec2025"
                        (requireActivity() as HomeActivity).openToBrowserAndLoad(
                            searchTermOrURL = donateUrl,
                            newTab = true,
                            from = BrowserDirection.FromHome,
                        )
                    },
                    toolBarAtTop = settings().toolbarPosition == ToolbarPosition.TOP
                )
            }
+274 −0
Original line number Diff line number Diff line
package org.mozilla.fenix.tor

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import mozilla.components.ui.colors.PhotonColors
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.R
import java.text.SimpleDateFormat
import java.util.Date


private val alternateLayoutThreshHold = 500.dp

@Composable
fun CampaignBox(shouldShowYec: MutableState<Boolean>, onDonateButtonClicked: () -> Unit) {
    BoxWithConstraints(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
    ) {
        val alternateLayout = this.maxWidth >= alternateLayoutThreshHold

        CampaignLayout(
            alternateLayout,
            maxWidth = this.maxWidth,
            shouldShowYec,
            onDonateButtonClicked = onDonateButtonClicked,
        )
    }
}

@Composable
private fun CampaignLayout(
    alternateLayout: Boolean,
    maxWidth: Dp,
    shouldShowYec: MutableState<Boolean>,
    onDonateButtonClicked: () -> Unit,
) {
    Column(
        modifier = Modifier
            .padding(horizontal = 22.dp)
            .fillMaxWidth(getVariableWidth(maxWidth))
            .wrapContentHeight(),
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        PurpleBox(alternateLayout, shouldShowYec, onDonateButtonClicked = onDonateButtonClicked)
        Spacer(Modifier.size(8.dp))
        Text(
            text = stringResource(R.string.no_donation_required_yec),
            style = TextStyle(
                fontSize = 12.5.sp,
                lineHeight = 18.75.sp,
                fontFamily = FontFamily.SansSerif,
                fontWeight = FontWeight(400),
                color = PhotonColors.LightGrey05,
                textAlign = TextAlign.Center,
            ),
        )
    }
}

private fun getVariableWidth(width: Dp): Float =
    (alternateLayoutThreshHold / width).coerceIn(0.80f, 1.0f)

@Composable
private fun PurpleBox(
    alternateLayout: Boolean,
    shouldShowYec: MutableState<Boolean>,
    onDonateButtonClicked: () -> Unit,
) {
    Box(
        modifier = Modifier.background(
            colorResource(R.color.yec_background), shape = RoundedCornerShape(8.dp),
        ),
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight(),
            horizontalArrangement = Arrangement.End,
        ) {
            ExitIcon(shouldShowYec)
        }
        DynamicCampaignContent(alternateLayout, onDonateButtonClicked = onDonateButtonClicked)
    }
}

@Composable
private fun ExitIcon(shouldShowYec: MutableState<Boolean>) {
    IconButton(
        modifier = Modifier.padding(8.dp),
        onClick = {
            shouldShowYec.value = false
        },
    ) {
        Icon(
            painter = painterResource(id = R.drawable.ic_close),
            tint = PhotonColors.White,
            contentDescription = stringResource(R.string.close_yec_button_description),
        )
    }
}


@Composable
private fun DynamicCampaignContent(
    alternateLayout: Boolean,
    onDonateButtonClicked: () -> Unit,
) {
    @Composable
    fun Icon(shouldShow: Boolean) {
        if (shouldShow) {
            Image(
                painterResource(R.drawable.globe_chain_burst_yec),
                contentDescription = null,
                alignment = Alignment.Center,
            )
        }
    }
    Row(
        modifier = Modifier
            .padding(16.dp)
            .fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Column(
            modifier = Modifier.fillMaxWidth(if (alternateLayout) 0.75f else 1.0f),
            horizontalAlignment = if (alternateLayout) Alignment.Start else Alignment.CenterHorizontally,
        ) {
            Icon(shouldShow = !alternateLayout)
            TitleText(alternateLayout)
            MainText(onDonateButtonClicked)
            Row(
                horizontalArrangement = if (alternateLayout) Arrangement.Start else Arrangement.Center,
                modifier = Modifier.fillMaxWidth(),
            ) {
                DonateButton(onDonateButtonClicked = onDonateButtonClicked)
            }
        }
        Icon(shouldShow = alternateLayout)
    }
}


@Composable
private fun TitleText(alternateLayout: Boolean) {
    Text(
        text = stringResource(R.string.free_the_internet_yec),
        style = TextStyle(
            fontSize = 56.sp,
            lineHeight = 47.6.sp,
            fontFamily = FontFamily(Font(R.font.jacquard_12)),
            fontWeight = FontWeight(400),
            color = PhotonColors.White,
            textAlign = if (alternateLayout) TextAlign.Start else TextAlign.Center,
        ),
    )
}

@Composable
private fun MainText(onDonateButtonClicked: () -> Unit) {
    Column {
        BasicText(
            text = buildAnnotatedString {
                withStyle(
                    SpanStyle(
                        color = PhotonColors.LightGrey05,
                        fontSize = 14.sp,
                    ),
                ) {
                    append(
                        stringResource(
                            R.string.body1_yec, stringResource(R.string.body1_link_yec),
                        ),
                    )
                    val linkStart: Int = stringResource((R.string.body1_yec)).indexOf("%s")
                    addLink(
                        url = LinkAnnotation.Url(
                            url = stringResource(R.string.body1_link_yec),
                            styles = TextLinkStyles(
                                style = SpanStyle(colorResource(R.color.yec_green)),
                                pressedStyle = SpanStyle(PhotonColors.LightGrey05),
                            ),
                            linkInteractionListener = { onDonateButtonClicked() },
                        ),
                        start = linkStart,
                        end = linkStart + stringResource(R.string.body1_link_yec).length,
                    )
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp),
        )
        Text(
            text = stringResource(R.string.body2_yec),
            modifier = Modifier
                .fillMaxWidth()
                .padding(
                    bottom = 16.dp,
                ),
            color = PhotonColors.LightGrey05,
            fontSize = 14.sp,
            textAlign = TextAlign.Start,
        )
    }
}

@Composable
private fun DonateButton(onDonateButtonClicked: () -> Unit) {
    Button(
        onClick = onDonateButtonClicked,
        colors = ButtonDefaults.buttonColors(
            backgroundColor = colorResource(R.color.yec_green),
        ),
        shape = RoundedCornerShape(4.dp),
        contentPadding = PaddingValues(horizontal = 16.dp, vertical = 9.dp),
    ) {
        Text(
            text = stringResource(R.string.donate_now_yec),
            textAlign = TextAlign.Center,
            fontSize = 16.sp,
            fontWeight = FontWeight.SemiBold,
            color = PhotonColors.DarkGrey80,
        )
        Spacer(
            Modifier.size(4.dp),
        )
        Image(
            painterResource(R.drawable.heart),
            contentDescription = null,
        )
    }
}
+34 −0
Original line number Diff line number Diff line
package org.mozilla.fenix.tor

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.getValue
import org.mozilla.geckoview.BuildConfig

class TorCampaignViewModel : ViewModel() {
    val shouldInitiallyShowPromo: MutableState<Boolean> by lazy {
        mutableStateOf(shouldInitiallyShowPromo())
    }

    fun shouldInitiallyShowPromo(): Boolean {
//        return true // uncomment to test

        val dateFormat = SimpleDateFormat("yyyy-MM-dd-hh-zzz")
        val startDate =
            dateFormat.parse("2025-10-14-15-UTC") // from https://gitlab.torproject.org/tpo/web/team/-/issues/66
        val endDate =
            dateFormat.parse("2026-01-02-00-UTC") // from https://gitlab.torproject.org/tpo/web/team/-/issues/66#note_3257224
        val currentDate = Date()

        if (currentDate.before(startDate) || currentDate.after(endDate)) {
            return false
        }
        if (BuildConfig.BUILD_TYPE == "release") {
            return true
        }
        return false
    }
}
+35 −22
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.paint
@@ -34,8 +37,13 @@ import org.mozilla.fenix.R
@Composable
@FlexibleWindowLightDarkPreview
fun TorHomePage(
    shouldInitiallyShowPromo: MutableState<Boolean> = mutableStateOf(false),
    onClicked: () -> Unit = {},
    toolBarAtTop: Boolean = true,
) {
    val shouldShowPromo = rememberSaveable {
        shouldInitiallyShowPromo
    }
    Column(
        modifier = Modifier
            .fillMaxSize()
@@ -82,6 +90,10 @@ fun TorHomePage(
            )
        }
        Spacer(Modifier.weight(1f))
        if (shouldShowPromo.value) {
            CampaignBox(shouldShowPromo, onDonateButtonClicked = onClicked)
            Spacer(Modifier.weight(1f))
        } else {
            Text(
                // Moved from the commit 5bb3cc6b93346dabd8d46677fae7f86a8f8a4fc2
                // "[android] Modify UI/UX", and the file HomeFragment.
@@ -109,3 +121,4 @@ fun TorHomePage(
        }
        Spacer(modifier = Modifier.size(17.dp))
    }
}
+35 −0
Original line number Diff line number Diff line
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="124dp" android:viewportHeight="124" android:viewportWidth="160" android:width="160dp">
      
    <path android:fillColor="#B6E368" android:pathData="M79.97,86.16C65.19,89.07 56.28,80.34 53.67,75.61L34.02,84.97L55.14,84.24L42.62,106.51L63.16,91.39L61.15,117.92L73.64,93L84.86,111.85L79.98,86.16H79.97Z"/>
      
    <path android:fillColor="#B6E368" android:pathData="M72.38,32.02C87.13,28.91 96.16,37.52 98.83,42.21L118.35,32.58L97.24,33.6L109.46,11.17L89.13,26.57L90.78,0L78.63,25.09L67.15,6.4L72.38,32.02Z"/>
      
    <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:fillType="evenOdd" android:pathData="M82.86,42.77H84.19V44.18H82.79V42.84H80.14V44.18H81.46V45.52H82.79V48.27H84.19V51.09H82.79V48.34H81.4V45.59H80.06V44.18H78.74V42.84H77.34V53.77H84.19V51.09H85.59V53.77H89.58V55.18H92.31V56.59H89.51V55.18H85.6V67.44H89.58V66.1H92.38V67.44H93.71V68.85H92.38V70.26H91.05V71.67H89.65V73.01H88.25V74.35H86.99V75.76H85.6V74.35H86.86V72.94H88.25V71.6H89.65V70.26H90.98V68.85H92.31V67.51H89.58V68.85H85.6V71.67H84.2V74.42H82.8V75.76H85.6V77.17H81.4V74.35H82.8V71.6H84.19V68.85H77.34V77.17H81.4V78.43H71.88V77.17H67.76V75.76H66.43V74.35H65.1V73.01H63.7V71.67H62.38V70.26H63.78V71.6H65.1V72.94H66.5V74.35H67.83V75.76H70.56V74.42H69.16V71.67H67.83V68.85H63.7V67.51H60.98V68.85H59.58V67.44H58.25V55.18H59.65V67.44H60.98V66.1H63.78V67.44H67.83V55.18H63.78V56.59H60.98V55.18H59.65V52.36H60.98V49.61H62.38V48.27H63.78V46.93H65.1V45.59H66.43V44.18H69.23V45.59H66.5V47H65.17V48.34H63.77V49.68H62.37V52.43H61.04V55.18H63.7V53.77H67.83V51.09H69.22V53.77H75.94V42.84H74.68V44.18H73.28V42.84H70.62V44.18H69.22V42.77H70.55V41.43H82.86V42.77V42.77ZM69.22,71.59H70.55V74.34H71.95V77.16H75.94V68.84H69.23V71.59H69.22ZM77.34,67.44H84.19V55.17H77.34V67.44ZM69.22,67.44H75.94V55.17H69.22V67.44Z" android:strokeAlpha="0.8"/>
      
    <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M62.37,70.25H60.98V68.84H62.37V70.25Z" android:strokeAlpha="0.8"/>
      
    <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M95.1,67.44H93.7V55.17H95.1V67.44Z" android:strokeAlpha="0.8"/>
      
    <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M86.99,45.58H88.25V46.92H89.64V48.26H90.97V49.6H92.37V52.35H93.7V55.17H92.3V52.42H90.97V49.67H89.58V48.33H88.25V46.99H86.85V45.58H84.19V44.17H86.99V45.58V45.58Z" android:strokeAlpha="0.8"/>
      
    <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M73.28,45.58H71.95V48.33H70.62V51.08H69.22V48.26H70.55V45.51H71.88V44.17H73.28V45.58Z" android:strokeAlpha="0.8"/>
      
    <path android:fillAlpha="0.8" android:fillColor="#00000000" android:pathData="M84.19,44.18V42.77H82.86V41.43H70.55V42.77H69.22V44.18M84.19,44.18H82.79V42.84H80.14V44.18H81.46V45.52H82.79V48.27H84.19V51.09M84.19,44.18V45.59H86.85V47H88.25V48.34H89.58V49.68H90.97V52.43H92.3V55.18M84.19,44.18H86.99V45.59H88.25V46.93H89.64V48.27H90.97V49.61H92.37V52.35H93.7V55.17M69.22,44.18H66.43V45.59H65.1V46.93H63.77V48.27H62.37V49.61H60.98V52.35H59.65V55.17M69.22,44.18V45.59H66.5V47H65.17V48.34H63.77V49.68H62.37V52.43H61.04V55.18H63.7V53.77H67.82V51.09H69.22M69.22,44.18H70.62V42.84H73.28V44.18M93.7,55.17H95.1V67.44H93.7M93.7,55.17V67.44M84.19,51.08H82.79V48.33H81.4V45.58H80.06V44.17H78.74V42.84H77.34V53.76H84.19V51.08H84.19ZM84.19,51.08H85.59V53.76H89.58V55.17H92.3M93.7,67.44H92.37V66.1H89.58V67.44H85.59V55.17H89.5V56.58H92.3V55.17H93.7M93.7,67.44V68.85H92.37V70.26H91.04V71.67H89.64V73.01H88.25V74.35H86.99V75.76H85.59M85.59,75.75V74.34H86.85V72.93H88.25V71.59H89.64V70.25H90.97V68.84H92.3V67.5H89.58V68.84H85.59V71.66H84.19V74.41H82.79V75.75H85.59V75.75ZM85.59,75.75V77.16H81.39M81.39,77.16V74.34H82.79V71.59H84.19V68.84H77.33V77.16H81.39H81.39ZM81.39,77.16V78.43H71.88V77.16H67.75V75.75H66.43V74.34H65.1V73H63.7V71.66H62.37V70.25M62.37,70.25H63.77V71.59H65.1V72.93H66.5V74.34H67.83V75.75H70.55V74.41H69.16V71.66H67.83V68.85H63.7V67.51H60.97V68.85M62.37,70.25H60.98V68.84H62.37V70.25ZM60.97,68.84H59.57V67.43H58.25V55.17H59.65M59.65,55.17V67.44H60.98V66.1H63.77V67.44H67.83V55.17H63.77V56.58H60.98V55.17H59.65ZM69.22,51.08V53.76H75.93V42.84H74.68V44.17H73.28M69.22,51.08H70.62V48.33H71.95V45.58H73.28V44.17H71.88V45.51H70.55V48.26H69.22V51.08ZM69.22,71.59H70.55V74.34H71.95V77.16H75.94V68.84H69.23V71.59H69.22ZM77.34,67.44H84.19V55.17H77.34V67.44ZM69.22,67.44H75.93V55.17H69.22V67.44Z" android:strokeAlpha="0.8" android:strokeColor="#C272FF" android:strokeWidth="0.23451"/>
      
    <path android:fillColor="#ffffff" android:pathData="M53.84,42.78H56.64L54.84,40.42L58.14,39.7L55.15,36.24L57.62,36.17L57.73,35.5L41.11,29.32C40.64,29.14 40.17,29 39.7,28.88L31.58,7.75C29.81,3.15 25.32,0.06 20.41,0.06C18.94,0.06 17.49,0.33 16.11,0.87L7.65,4.16C1.5,6.55 -1.57,13.54 0.81,19.73L12.4,49.92C14.17,54.53 18.66,57.62 23.56,57.62C24.22,57.62 24.87,57.57 25.51,57.46C26.74,58.58 28.17,59.46 29.77,60.05L46.5,66.27L44.54,62.76H48.38L47.08,59.56H51.23L49.53,56.39L38.61,52.33C42.24,49.92 44.27,45.7 43.94,41.38L56.68,46.11L53.84,42.78ZM49.04,56.96L50.07,58.86H46.04L47.35,62.07H43.36L44.97,64.96L30.01,59.4C26.89,58.24 24.41,55.93 23.03,52.89C21.64,49.86 21.52,46.48 22.67,43.35L24.89,37.34C25.95,34.46 27.98,32.2 30.46,30.8L33.78,39.46C33.55,39.74 33.36,40.07 33.23,40.44L31.01,46.45C30.68,47.35 30.72,48.31 31.11,49.17C31.5,50.04 32.21,50.7 33.1,51.03L49.04,56.96ZM21.23,46.86C21.17,46.76 21.12,46.65 21.08,46.54L9.48,16.35C9.13,15.45 9.36,14.68 9.53,14.31C9.7,13.93 10.11,13.24 11.01,12.89L19.46,9.6C19.78,9.48 20.1,9.42 20.41,9.42C21.32,9.42 22.44,9.95 22.9,11.14L30.21,30.15C27.54,31.61 25.37,34.02 24.24,37.1L22.02,43.11C21.57,44.33 21.3,45.6 21.23,46.86ZM33.88,40.68C33.93,40.52 34,40.38 34.08,40.24L34.5,41.32C34.85,42.23 34.62,42.99 34.45,43.37H34.45C34.28,43.75 33.88,44.43 32.98,44.78L32.26,45.06L33.88,40.68ZM37.79,52.02L33.34,50.37C32.62,50.11 32.06,49.58 31.74,48.88C31.42,48.19 31.39,47.41 31.66,46.7L31.94,45.93L33.23,45.43C34.36,45 34.87,44.13 35.08,43.65C35.29,43.17 35.58,42.21 35.14,41.07L34.58,39.61V39.59L34.35,39.01L34.32,38.91L31.07,30.48L31.06,30.46L30.85,29.91L30.82,29.82L23.55,10.88C22.97,9.39 21.56,8.72 20.41,8.72C20.01,8.72 19.61,8.8 19.21,8.95L10.76,12.24C9.63,12.68 9.11,13.55 8.9,14.02C8.69,14.5 8.4,15.47 8.84,16.61L20.43,46.8C20.61,47.27 20.88,47.67 21.2,47.97C21.24,49.75 21.64,51.52 22.4,53.18C23.03,54.56 23.87,55.79 24.88,56.85C24.44,56.9 24,56.93 23.56,56.93C18.94,56.93 14.71,54.01 13.04,49.67L1.45,19.48C-0.79,13.65 2.1,7.07 7.9,4.81L16.35,1.52C17.66,1.01 19.03,0.75 20.41,0.75C25.04,0.75 29.26,3.67 30.93,8.01L38.88,28.7L38.91,28.78L39.16,29.43L39.18,29.47L42.53,38.2C42.8,38.9 42.99,39.61 43.11,40.33C43.12,40.35 43.13,40.37 43.13,40.4C43.17,40.61 43.2,40.83 43.22,41.05C43.22,41.07 43.22,41.09 43.22,41.11C43.68,45.46 41.58,49.76 37.79,52.02ZM43.86,40.6C43.74,39.71 43.51,38.81 43.18,37.94L40.01,29.69C40.29,29.77 40.58,29.86 40.87,29.97L55.81,35.53L53.67,35.59L56.85,39.27L53.63,39.97L55.24,42.09H52.33L54.41,44.53L43.86,40.6Z"/>
      
    <path android:fillColor="#ffffff" android:pathData="M157.76,99.65L136.71,69.02C134.41,65.69 130.67,63.66 126.65,63.57C125.48,62.52 124.09,61.66 122.51,61.08L107.43,55.47L107.36,55.44L103.68,55.55L106.41,58.69L102.99,59.44L105.06,62.15H102.4L104.54,64.66L115.19,68.62L112.76,70.31C109.62,72.5 107.78,75.86 107.41,79.41L97.62,75.77L99.32,78.92H94.98L96.29,82.12H92.65L94.1,84.72L111.42,91.16C111.59,91.22 111.75,91.28 111.92,91.33L130.63,118.54C132.98,121.96 136.85,124 140.98,124C143.54,124 146.01,123.22 148.12,121.75L154.58,117.26C157.34,115.33 159.19,112.44 159.79,109.12C160.4,105.79 159.68,102.43 157.76,99.65ZM104.95,64.06L103.91,62.85H106.46L104.21,59.89L107.7,59.13L105.17,56.2L107.25,56.14L122.27,61.73C123.5,62.19 124.62,62.82 125.59,63.59C123.31,63.73 121.12,64.49 119.22,65.82L115.89,68.13L104.95,64.06ZM111.65,90.5L111.25,90.35L94.58,84.15L93.84,82.82H97.32L96.01,79.61H100.48L99.1,77.06L107.36,80.13L108.04,80.38L114.5,82.79C115.37,83.11 116.28,83.1 117.1,82.82C117.32,82.75 117.54,82.65 117.74,82.53C118.53,82.1 119.17,81.39 119.5,80.48L120.95,76.56L124.77,73.9C125.25,73.57 125.79,73.39 126.36,73.39C126.8,73.39 127.92,73.51 128.68,74.61L129.76,76.19C129.69,76.47 129.61,76.75 129.51,77.02L127.19,83.33L127.08,83.63C126.11,86.07 124.45,88.03 122.42,89.34C122.23,89.47 122.03,89.59 121.83,89.7C119.04,91.29 115.64,91.75 112.36,90.74C112.13,90.67 111.89,90.59 111.65,90.5ZM117.15,80.21C117.22,79.78 117.48,78.97 118.31,78.39L119.95,77.26L118.85,80.24C118.57,81 118.04,81.58 117.38,81.94C117.04,81.24 117.08,80.57 117.15,80.21ZM130.06,77.56L130.17,77.25C130.2,77.14 130.24,77.04 130.27,76.93L149.73,105.24C150.31,106.08 150.27,106.93 150.19,107.36C150.11,107.79 149.85,108.6 149.02,109.18L142.57,113.67C142.09,114.01 141.55,114.17 140.98,114.17C140.53,114.17 139.41,114.06 138.66,112.95L122.82,89.91C124.96,88.52 126.7,86.46 127.72,83.89L130.06,77.56ZM159.11,108.99C158.54,112.14 156.79,114.87 154.18,116.68L147.73,121.18C145.73,122.57 143.4,123.3 140.98,123.3C137.07,123.3 133.42,121.38 131.2,118.15L112.97,91.63C113.95,91.86 114.94,91.97 115.91,91.97C118.15,91.97 120.32,91.38 122.23,90.28L138.09,113.35C139.03,114.72 140.42,114.87 140.98,114.87C141.7,114.87 142.36,114.66 142.96,114.25L149.42,109.75C150.45,109.03 150.77,108.02 150.87,107.48C150.96,106.95 151.02,105.89 150.3,104.85L130.51,76.06L129.97,75.26L129.25,74.22C128.3,72.84 126.91,72.7 126.36,72.7H126.36C125.64,72.7 124.97,72.91 124.38,73.32L121.37,75.42L120.37,76.11L117.92,77.82C116.88,78.54 116.56,79.55 116.46,80.08C116.39,80.53 116.33,81.34 116.74,82.2C116.1,82.39 115.41,82.38 114.74,82.13L108.08,79.66C108.39,76.25 110.14,72.99 113.15,70.89L115.99,68.91L116.68,68.43L119.61,66.39C121.6,65 123.94,64.27 126.36,64.27H126.37C126.72,64.27 127.07,64.28 127.41,64.31C130.91,64.62 134.12,66.48 136.13,69.42L157.19,100.05C159,102.68 159.68,105.85 159.11,108.99Z"/>
      
    <path android:fillColor="#C272FF" android:pathData="M26.73,77.81L30.91,77.83L30.91,79.04L26.73,79.03V84.32H25.51V79.03L21.2,79.02L21.2,77.8L25.51,77.81V72.54H26.73V77.81Z"/>
      
    <path android:fillColor="#C272FF" android:pathData="M132.82,37.87L137,37.88L137,39.08L132.82,39.07V44.31H131.6V39.07L127.29,39.06L127.29,37.85L131.6,37.86V32.65H132.82V37.87Z"/>
      
    <path android:fillColor="#C272FF" android:pathData="M20.17,99.2C20.17,98.79 19.84,98.46 19.43,98.46C19.02,98.46 18.69,98.79 18.69,99.2C18.69,99.62 19.02,99.95 19.43,99.95V101.17C18.36,101.17 17.49,100.29 17.49,99.2C17.49,98.12 18.36,97.24 19.43,97.24C20.51,97.24 21.38,98.12 21.38,99.2C21.38,100.29 20.51,101.17 19.43,101.17V99.95C19.84,99.95 20.17,99.62 20.17,99.2Z"/>
      
    <path android:fillColor="#C272FF" android:pathData="M116.28,43.22C117.35,43.22 118.22,44.1 118.22,45.18C118.22,46.27 117.35,47.15 116.28,47.15C115.2,47.15 114.33,46.27 114.33,45.18C114.33,44.1 115.2,43.22 116.28,43.22Z"/>
      
    <path android:fillColor="#C272FF" android:pathData="M134.74,51.08C135.81,51.08 136.68,51.96 136.68,53.04C136.68,54.12 135.81,55 134.74,55C133.66,55 132.79,54.12 132.79,53.04C132.79,51.96 133.66,51.08 134.74,51.08Z"/>
      
    <path android:fillColor="#C272FF" android:pathData="M32.81,91.67C32.81,91.26 32.47,90.93 32.06,90.93C31.66,90.93 31.32,91.26 31.32,91.67C31.32,92.09 31.66,92.42 32.06,92.42V93.64C30.99,93.64 30.12,92.76 30.12,91.67C30.12,90.59 30.99,89.71 32.06,89.71C33.14,89.71 34.01,90.59 34.01,91.67C34.01,92.76 33.14,93.64 32.06,93.64V92.42C32.47,92.42 32.81,92.09 32.81,91.67Z"/>
    
</vector>
Loading