Add 'more reactions' button to message (#756)

- Add 'more reactions' button to message
- Fix display of existing emoji reactions to match designs
- Refactor emoji reactions to reduce nesting of composables


---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
jonnyandrew 2023-07-05 15:38:20 +00:00 committed by GitHub
parent f0f00e40a0
commit a6825b66e1
56 changed files with 261 additions and 131 deletions

View file

@ -126,6 +126,9 @@ fun MessagesView(
state.eventSink(MessagesEvents.ToggleReaction(emoji, event.eventId))
}
fun onMoreReactionsClicked(event: TimelineItem.Event): Unit =
state.customReactionState.eventSink(CustomReactionEvents.UpdateSelectedEvent(event.eventId))
Scaffold(
modifier = modifier,
contentWindowInsets = WindowInsets.statusBars,
@ -155,6 +158,7 @@ fun MessagesView(
}
},
onReactionClicked = ::onEmojiReactionClicked,
onMoreReactionsClicked = ::onMoreReactionsClicked,
onSendLocationClicked = onSendLocationClicked,
onSwipeToReply = { targetEvent ->
state.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, targetEvent))
@ -240,6 +244,7 @@ fun MessagesViewContent(
onMessageClicked: (TimelineItem.Event) -> Unit,
onUserDataClicked: (UserId) -> Unit,
onReactionClicked: (key: String, TimelineItem.Event) -> Unit,
onMoreReactionsClicked: (TimelineItem.Event) -> Unit,
onMessageLongClicked: (TimelineItem.Event) -> Unit,
onTimestampClicked: (TimelineItem.Event) -> Unit,
onSendLocationClicked: () -> Unit,
@ -262,6 +267,7 @@ fun MessagesViewContent(
onUserDataClicked = onUserDataClicked,
onTimestampClicked = onTimestampClicked,
onReactionClicked = onReactionClicked,
onMoreReactionsClicked = onMoreReactionsClicked,
onSwipeToReply = onSwipeToReply,
)
}

View file

@ -82,6 +82,7 @@ fun TimelineView(
onTimestampClicked: (TimelineItem.Event) -> Unit,
onSwipeToReply: (TimelineItem.Event) -> Unit,
onReactionClicked: (emoji: String, TimelineItem.Event) -> Unit,
onMoreReactionsClicked: (TimelineItem.Event) -> Unit,
modifier: Modifier = Modifier,
) {
fun onReachedLoadMore() {
@ -127,6 +128,7 @@ fun TimelineView(
onUserDataClick = onUserDataClicked,
inReplyToClick = ::inReplyToClicked,
onReactionClick = onReactionClicked,
onMoreReactionsClick = onMoreReactionsClicked,
onTimestampClicked = onTimestampClicked,
onSwipeToReply = onSwipeToReply,
)
@ -154,6 +156,7 @@ fun TimelineItemRow(
onLongClick: (TimelineItem.Event) -> Unit,
inReplyToClick: (EventId) -> Unit,
onReactionClick: (key: String, TimelineItem.Event) -> Unit,
onMoreReactionsClick: (TimelineItem.Event) -> Unit,
onTimestampClicked: (TimelineItem.Event) -> Unit,
onSwipeToReply: (TimelineItem.Event) -> Unit,
modifier: Modifier = Modifier
@ -184,6 +187,7 @@ fun TimelineItemRow(
onUserDataClick = onUserDataClick,
inReplyToClick = inReplyToClick,
onReactionClick = onReactionClick,
onMoreReactionsClick = onMoreReactionsClick,
onTimestampClicked = onTimestampClicked,
onSwipeToReply = { onSwipeToReply(timelineItem) },
modifier = modifier,
@ -221,6 +225,7 @@ fun TimelineItemRow(
onUserDataClick = onUserDataClick,
onTimestampClicked = onTimestampClicked,
onReactionClick = onReactionClick,
onMoreReactionsClick = onMoreReactionsClick,
onSwipeToReply = {},
)
}
@ -323,6 +328,7 @@ private fun ContentToPreview(content: TimelineItemEventContent) {
onUserDataClicked = {},
onMessageLongClicked = {},
onReactionClicked = { _, _ -> },
onMoreReactionsClicked = {},
onSwipeToReply = {},
)
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.messages.impl.timeline.components
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AddReaction
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.theme.ElementTheme
@Composable
fun MessagesMoreReactionsButton(modifier: Modifier = Modifier, onClick: () -> Unit) {
val buttonColor = ElementTheme.colors.bgSubtleSecondary
Surface(
modifier = modifier
.background(Color.Transparent)
// Outer border, same colour as background
.border(
BorderStroke(2.dp, MaterialTheme.colorScheme.background),
shape = RoundedCornerShape(corner = CornerSize(14.dp))
)
.padding(vertical = 2.dp, horizontal = 2.dp)
// Clip click indicator inside the outer border
.clip(RoundedCornerShape(corner = CornerSize(12.dp)))
.clickable(onClick = onClick)
.background(buttonColor, RoundedCornerShape(corner = CornerSize(12.dp)))
.padding(vertical = 4.dp, horizontal = 10.dp),
color = buttonColor
) {
Icon(
imageVector = Icons.Outlined.AddReaction,
contentDescription = "Add emoji",
tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier
// Same size as the line height of reaction emoji text
.size(with(LocalDensity.current) { 20.sp.toDp() })
)
}
}
@Preview
@Composable
internal fun MessagesMoreReactionsButtonLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun MessagesMoreReactionsButtonDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
MessagesMoreReactionsButton(onClick = {})
}

View file

@ -17,9 +17,9 @@
package io.element.android.features.messages.impl.timeline.components
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
@ -30,6 +30,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
@ -45,35 +46,47 @@ import io.element.android.libraries.theme.ElementTheme
@Composable
fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Modifier, onClick: () -> Unit) {
// First Surface is to render a border with the same background color as the background
val buttonColor = if (reaction.isHighlighted) {
ElementTheme.colors.bgSubtlePrimary
} else {
ElementTheme.colors.bgSubtleSecondary
}
val borderColor = if (reaction.isHighlighted) {
ElementTheme.colors.borderInteractivePrimary
} else {
buttonColor
}
Surface(
modifier = modifier.clickable(onClick = onClick::invoke),
// TODO Should use compound.bgSubtlePrimary
color = ElementTheme.legacyColors.gray300,
border = BorderStroke(2.dp, MaterialTheme.colorScheme.background),
shape = RoundedCornerShape(corner = CornerSize(14.dp)),
modifier = modifier
.background(Color.Transparent)
// Outer border, same colour as background
.border(
BorderStroke(2.dp, MaterialTheme.colorScheme.background),
shape = RoundedCornerShape(corner = CornerSize(14.dp))
)
.padding(vertical = 2.dp, horizontal = 2.dp)
// Clip click indicator inside the outer border
.clip(RoundedCornerShape(corner = CornerSize(12.dp)))
.clickable(onClick = onClick)
// Inner border, to highlight when selected
.border(BorderStroke(1.dp, borderColor), RoundedCornerShape(corner = CornerSize(12.dp)))
.background(buttonColor, RoundedCornerShape(corner = CornerSize(12.dp)))
.padding(vertical = 4.dp, horizontal = 10.dp),
color = buttonColor
) {
Box(modifier = Modifier.padding(2.dp)) {
val reactionModifier = if (reaction.isHighlighted) {
Modifier
// TODO Check the color, should use compound.borderInteractivePrimary
.border(BorderStroke(1.dp, Color(0xFF808994)), RoundedCornerShape(corner = CornerSize(12.dp)))
} else {
Modifier
}
Row(
modifier = reactionModifier.padding(vertical = 4.dp, horizontal = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = reaction.key, fontSize = 15.sp)
if (reaction.count > 1) {
Spacer(modifier = Modifier.width(4.dp))
Text(
text = reaction.count.toString(),
color = if (reaction.isHighlighted) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
fontSize = 14.sp
)
}
Row(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = reaction.key, fontSize = 15.sp, lineHeight = 20.sp
)
if (reaction.count > 1) {
Spacer(modifier = Modifier.width(4.dp))
Text(
text = reaction.count.toString(),
color = if (reaction.isHighlighted) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
fontSize = 14.sp
)
}
}
}

View file

@ -101,6 +101,7 @@ fun TimelineItemEventRow(
inReplyToClick: (EventId) -> Unit,
onTimestampClicked: (TimelineItem.Event) -> Unit,
onReactionClick: (emoji: String, eventId: TimelineItem.Event) -> Unit,
onMoreReactionsClick: (eventId: TimelineItem.Event) -> Unit,
onSwipeToReply: () -> Unit,
modifier: Modifier = Modifier
) {
@ -110,9 +111,6 @@ fun TimelineItemEventRow(
onUserDataClick(event.senderId)
}
fun onReactionClicked(emoji: String) =
onReactionClick(emoji, event)
fun inReplyToClicked() {
val inReplyToEventId = (event.inReplyTo as? InReplyTo.Ready)?.eventId ?: return
inReplyToClick(inReplyToEventId)
@ -144,7 +142,8 @@ fun TimelineItemEventRow(
onTimestampClicked = onTimestampClicked,
inReplyToClicked = ::inReplyToClicked,
onUserDataClicked = ::onUserDataClicked,
onReactionClicked = ::onReactionClicked,
onReactionClicked = { emoji -> onReactionClick(emoji, event) },
onMoreReactionsClicked = { onMoreReactionsClick(event) },
)
}
)
@ -158,7 +157,8 @@ fun TimelineItemEventRow(
onTimestampClicked = onTimestampClicked,
inReplyToClicked = ::inReplyToClicked,
onUserDataClicked = ::onUserDataClicked,
onReactionClicked = ::onReactionClicked,
onReactionClicked = { emoji -> onReactionClick(emoji, event) },
onMoreReactionsClicked = { onMoreReactionsClick(event) },
)
}
// This is assuming that we are in a ColumnScope, but this is OK, for both Preview and real usage.
@ -180,6 +180,7 @@ private fun TimelineItemEventRowContent(
inReplyToClicked: () -> Unit,
onUserDataClicked: () -> Unit,
onReactionClicked: (emoji: String) -> Unit,
onMoreReactionsClicked: (event: TimelineItem.Event) -> Unit,
modifier: Modifier = Modifier,
) {
// To avoid using negative offset, we display in this Box a column with:
@ -240,6 +241,7 @@ private fun TimelineItemEventRowContent(
TimelineItemReactionsView(
reactionsState = event.reactionsState,
onReactionClicked = onReactionClicked,
onMoreReactionsClicked = { onMoreReactionsClicked(event) },
modifier = Modifier
.align(if (event.isMine) Alignment.BottomEnd else Alignment.BottomStart)
.padding(start = if (event.isMine) 16.dp else 36.dp, end = 16.dp)
@ -534,6 +536,7 @@ private fun ContentToPreview() {
onUserDataClick = {},
inReplyToClick = {},
onReactionClick = { _, _ -> },
onMoreReactionsClick = {},
onTimestampClicked = {},
onSwipeToReply = {},
)
@ -551,6 +554,7 @@ private fun ContentToPreview() {
onUserDataClick = {},
inReplyToClick = {},
onReactionClick = { _, _ -> },
onMoreReactionsClick = {},
onTimestampClicked = {},
onSwipeToReply = {},
)
@ -595,6 +599,7 @@ private fun ContentToPreviewWithReply() {
onUserDataClick = {},
inReplyToClick = {},
onReactionClick = { _, _ -> },
onMoreReactionsClick = {},
onTimestampClicked = {},
onSwipeToReply = {},
)
@ -613,6 +618,7 @@ private fun ContentToPreviewWithReply() {
onUserDataClick = {},
inReplyToClick = {},
onReactionClick = { _, _ -> },
onMoreReactionsClick = {},
onTimestampClicked = {},
onSwipeToReply = {},
)
@ -668,6 +674,7 @@ private fun ContentTimestampToPreview(event: TimelineItem.Event) {
onUserDataClick = {},
inReplyToClick = {},
onReactionClick = { _, _ -> },
onMoreReactionsClick = {},
onTimestampClicked = {},
onSwipeToReply = {},
)

View file

@ -29,8 +29,9 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight
@Composable
fun TimelineItemReactionsView(
reactionsState: TimelineItemReactions,
onReactionClicked: (emoji: String) -> Unit,
onMoreReactionsClicked: () -> Unit,
modifier: Modifier = Modifier,
onReactionClicked: (emoji: String) -> Unit
) {
FlowRow(
modifier = modifier,
@ -43,6 +44,9 @@ fun TimelineItemReactionsView(
onClick = { onReactionClicked(reaction.key) }
)
}
MessagesMoreReactionsButton(
onClick = onMoreReactionsClicked
)
}
}
@ -60,6 +64,7 @@ internal fun TimelineItemReactionsViewDarkPreview() =
private fun ContentToPreview() {
TimelineItemReactionsView(
reactionsState = aTimelineItemReactions(),
onReactionClicked = { }
onReactionClicked = {},
onMoreReactionsClicked = {},
)
}

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c8527bc63aceac59916ca5dfe9c73e9fd1309b957b26945e261849cb1b658253
size 6143

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:836fc6c1689c9be78cac4bcd0cfa4cb8fb5f8ed36ace9159889b2404feb8f52e
size 6095

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:35ded8660ee6bf1628271ab2089e7024960ffc3bded961a5ec031960e2cd9b02
size 6684
oid sha256:048cafa3f3d2aa0ec9122c84a6a6fe39d16549021bbbe286c436900c81fb8873
size 6519

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:efbf53aa8eaec37c770281ce5c539810c0e7d081229989164d50a4420d532dce
size 7576
oid sha256:5648d6a428f4b7fa20c9981c6e564555bc04ec6b0911028507e01f90a56a44cf
size 7414

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e7bff9985b4231c67489bbbd01aefde6a66e26532f595aa9033b71888c4aa123
size 7504
oid sha256:d76cd06cf3b36aeb3de567605f6ebc33508cb074049ad854ccec5cf5b382ff36
size 7263

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:913306f961ff082715c2707d467a13d7ec1b2edcbc321f5535abf6ced9e64ca8
size 8421
oid sha256:ab3023d14ccd579dc350bc019f94ea2ddc59ac55238d04f4a96c34a1036361df
size 8185

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1eab05db3cad5c2d0d05ec01a41631b92adea5b625dd0a30c8ca70ff7edff178
size 6648
oid sha256:a0e5cb3791012323f9ad6352537b4e579608ebb33f7f46742241b3cac737e617
size 6349

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:da5e0e74e13ecee477b33c63fedf5c87953facc68b674da765c65658b91ad85b
size 7527
oid sha256:dfdd3edecb3cb2adb7686dec5043407e3a23e15c5a7911a28f5feba279532e9e
size 7261

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:95d693f3ebcd18df2b474175959b5dfe856b2204d2d5a9e0b95637d52e95c73a
size 7425
oid sha256:995f7f218c005e18acd4b500a81d28784b3b3d81a12c2aadcdd9672ef18ebf28
size 7191

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aa3529f9658c15a7de5a3b5cd6fcad1a67a302cd767177d5cfd912493df4aaaf
size 8342
oid sha256:e08bd85cee39e0827fa2cbbee3fd60dc83d860af553f52a609a0f4d691174d2e
size 8140

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f516fec77af8ffaecaa6e4eb6d23cdda607edf31321a14136893e29907758aa
size 136058
oid sha256:3d084d7599820f87fef03f9237e8f439bbe2a888987412eab758256372f31ad4
size 140969

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1629f7b12f7846460cbf3bfb9b0e52c2e00f97666bafdc7aff18be9b24d3761a
size 140954
oid sha256:8b859d6adaaf2d70e57003e8006d0bcda77af1bcb774eac0ac58fee9fdc24a42
size 145280

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d27d08d756b084e349c5c8066ed570ea1dec1daf93aa11b85671bb631acbccce
size 116677
oid sha256:19a24bb5cc453da252b41cfb4a66a1f00416e58981107037c996b4ad313f2456
size 120217

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0e52e57c7f09aaa43f9cf5e3b85b1e9cccacb4db2749eec4409f8653846c47cf
size 121351
oid sha256:2f6740a82570e62c5f723a42388a636e5dc671c417772f4aa1c286fd99929460
size 124946

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:468a23d2d1f7a440659e2c1a8a57420b1aad2bbebd50af65bf3c98b2d4975806
size 13906
oid sha256:39ba97e1d56ab19f08505f40f9ed6a99fa2439bd5cfbe2a113dfe1a63b03a091
size 15515

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2079ae564091c0f1f55f6aea107f8d65d90cc31aff6f4d5a42540e4a8905598d
size 13952
oid sha256:8e13cb79969d6107cec9ef8f30da2915aeaf3f1e0f534d52fc971f3eb27224a4
size 15366

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:76a516d4610c44cff470c8ed3dd4216eb4183a1eee37ddc2d1d50ac8388a6bf1
size 44694
oid sha256:0c0e45b3aab4c249e78c4b6d77eadd1d4244d72eb515529cf816cc0ad4b61225
size 52107

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c68ad8932cac922061ae8579f7f5cca844370fba127de7580804b86aa365714
size 55592
oid sha256:5f92b8452969d7e17b010ff640a82ebb6b2a0c95b33bd59fec8990b9b6dde29b
size 62965

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0dc90137be2f7f1aa7b2ced587e0a539e33abe795260582ed418393aae6ec08c
size 58578
oid sha256:4d4d701ed86f9bc3e23dbcb0d1f4a61f66153e3f2d2e71c12cefb1ef72634f9f
size 65937

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b933ae95db4865a86cac9196e91b99bb7768271a41d8bf37e69637434bb9bb4b
size 49255
oid sha256:bcecf59a9361f9de63971d88a1e3d4daa1041d48cabdbe0bd6485052668d3906
size 56636

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c8b1af339d9f8c4a9e114523956688a48d3817f756f1e50cc63d4692de0336f
size 228299
oid sha256:a437ec6227ea7e617e986adda4943b7a87d099de22eff09d790ed25934e3574c
size 230913

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c7e3c7431a8bb6c75892c0db3d5c1b61fbd233c9bb98f741a2a89c486d1f53f
size 229208
oid sha256:c5187a8eecfaf227fee1b1081652a8c263c765aae9e7662e5b875ee357ef65c9
size 231822

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5233170b8312a919fbaefb43fdb1595a59d6fb044f2cbf2401ba42226bb84e7c
size 63886
oid sha256:eb908fabb11413ac2b7665464df8a68517675cbec43e3127fb684b80fc7d386d
size 71225

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fd89b421b4bd74782f0d4c5a04df291077d5bea46b3bbf0b5962bc5c10bd0e0c
size 78874
oid sha256:fae191865f8662362921cc5d45fae1ca3a446f0ebe5975491d92d246da505b3f
size 85668

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2812002d2aa0862b7bb71db095bde4c3a8ab5b70946609c906e253f0476489d2
size 173384
oid sha256:1706fda748d056ed6404e6a4a9a5c80173eade3cffc80d2cb6585f53d2bf3db7
size 174033

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a7a1c89e89950526e65afa84a3ab60ff563cfee5a56977aacd2be6931bf36b40
size 46101
oid sha256:9d544ff72f07770d725a02ffe23fdf77278c15520273fd83a89509ef6a4632f0
size 53520

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9e2b4f39df6359c7bb1d3ce8f146a13e36197f7e2303421a809c9aedf267cac7
size 57650
oid sha256:7ae78c21fa4c5bc13ef4d9b540a6db805af73a4b2ab686d35b5d37edca33ee1c
size 65012

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:374e99f565fa90cbd89c36081f372cf64af59341208a3ff32ca623727fdee9f2
size 42850
oid sha256:fb8609b0babc1a2e50f990b400090f57d3f0bddffbdfc02f76fb57d4c085bccd
size 50178

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:49c2ab83ae91850a5047e5703e9f4f3675c551b215f2aca9bf02c3a0bde4b14a
size 46151
oid sha256:171c1bf8f369e05dbb0667732187e8177f6d29bf6ca54717e00c2c818f2e8974
size 53689

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1054f6cce57f6a5b73a9eddd819f374735b53864209f48a35fa3cb1010d5b3da
size 58189
oid sha256:22cb2a36ceb117870d0675447d12054549389908b848112991942d88904a0863
size 65475

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b1e2e322dbb32e5f52fed4f00e50e6d97b6149f8d2b46344e07f6c1b5816dcde
size 61344
oid sha256:2c9a43dedfef18acc8713b033ffe8ac59545eb96a77e3640ba69b9048a19bc59
size 68644

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9c5018384f7783297a995d72c088903606b7d092407b7dbb4934b2a678271853
size 51363
oid sha256:9a5713bf7670620247cd96760627c5b97dc393b3576b32712ae9073c7d5948de
size 58797

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cc0e157d9838459d7859dc8ce8e4cf85a0f83c056fd9d151ea5052145c591378
size 228765
oid sha256:e4d22a943048c96df71e5e8d8e3d40f5cdd1385b68725af5b5fc3223a59d6c17
size 231430

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e116bbf8dd5de0ab472368088bf3823010f34fe3fd5f168256365ccb983e8080
size 229754
oid sha256:0de996b82d409f7f054dd212a7031533360a348508ca276655378319cbb363bc
size 232322

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5844f1ef60404ba714b32294c99dd06cbdd35800ddc2758e35da654b2a2921ce
size 66692
oid sha256:97d97fce39e45516fbf6576650b1a3fbb32879e0ff45eb63dcfc3bedbceb0b0f
size 73851

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:beae1875ccdce8390d3d237f5754f0aaa9fc8a0ee2e9bcc87ed9deff7602bd1e
size 83688
oid sha256:556725899abc9274213c6ab6dcea59033aff90c4cf94ace4a54e234e6e019f30
size 90336

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b46199eec3d05a3ee13813c37dbb10bb8bf9d285a0bd349cda9f6956385fa5f5
size 361988
oid sha256:3d0ee4aa4d0981efbef66e59d3887eb26c4e602b5a3cfbeeb6103cd4c9648b88
size 365406

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ebee6b6cf3756c5a4b861dd4fb4a142dd7a443faa8495a4b9c7dfa8cea3e3931
size 47791
oid sha256:1f031f626ce7b2aaa4d9fd551b5ddbf81dc9dd53bc7013bec179bc42a814bd9b
size 55325

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b2403644534084159a0f4b49f3bac626927a2bc228ef8de0f94ade921202ec40
size 60183
oid sha256:351257a00f2b73baea6d6646123f48fa822d7af8dfdc21bc18647aa75ec848cd
size 67457

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d0a783c549f51974beebfdac4d3bf48d98de67c57e040a9120e6cb73ea4b1707
size 44180
oid sha256:73dd69d4168847ee6339f9d02ae80157f810cab559f9f6c4659ba93c10d14a9e
size 51702

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28894ec89a8f0d8b4ba2d4032e3f451d699c165d80cd0a6eea0367b4cde67d24
size 45644
oid sha256:9a3c76459f7b40808100488360fc29cbc6cd205aeccf4faa4507354659d4506d
size 53003

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f9f451aeb5991c6c89f50ac5579a5a67b731d2d0fe1378953c9f74c6ea94f186
size 47234
oid sha256:2b49f74436e610e728b04d079b386357134e99ac0b2e17c1a6dc0477bcaf190f
size 54522

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:194f742f1ea4e15343656fad3acf25147e6fec367f14e2a0a26470df1f0b2443
size 45838
oid sha256:de0314bc0ac75e28e202689ed771faa912ce87fba595123696f2c3064eb8196d
size 53199

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6e4af00485fddc3d8ecafbbdc2e08e8423816f7d5dbdfbb4fc0eba942a866a8e
size 48659
oid sha256:51a7c04f972779be670e41fe98d544a47503f55728665c8edc83e4e548639aa8
size 55962

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:977eb261b9658466904813bd6f238efb16b4a10d48a49780cc62bf15938e47d7
size 45931
oid sha256:f73ab084dc2ff02430015299ec216f9d20210961713e57ce860c2c6abe60c4a7
size 51155

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c1067095cd7f3990baf1a7018de2b5dc236bc2321c40a097a595492a501f806
size 47221
oid sha256:226582e84dfb9da1a81b2582d6799d3caee7ae57796bc42e09f921ad5ec79964
size 54714

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:52d0cc874c1ecfd6125c3666dc6f7dbf8a532a337e8a1d532e1c68a3febc3b75
size 48870
oid sha256:d606bacecbef9707d1bf078f91c562363fab14ff5173e5c72a16a8ce92c64ad1
size 56305

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ac63233b5b7e799cf1b393eb1225c680e07f44ad543ed545017649dfa56976a8
size 47487
oid sha256:f8382e156ba7fe10d7de83ef532ef1e4889499d7d245d9bbf8dff44020e8e79c
size 55005

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c832763a985e5df02c7a1071e910456639387a1edaf2074a5915310e98958ef0
size 50294
oid sha256:88952c8c7c19ced26f34857d78b8513b069939106d2b1068252e82601b7649ae
size 57897

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37597fd224de15ded08333a593a19e9b3ce20cde8a155907f9d9bfb9ecad2d07
size 47091
oid sha256:eaf02c660ac8b6465f22b4bb909769d8715ac6a12791140642c6dc360df2014a
size 52492