@chaitrabhairappa/react-native-rich-text-editor 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/android/src/main/java/com/richtext/editor/FloatingToolbar.kt +12 -12
  2. package/android/src/main/java/com/richtext/editor/RichTextEditorView.kt +99 -5
  3. package/android/src/main/java/com/richtext/editor/RichTextEditorViewManager.kt +18 -0
  4. package/android/src/main/java/com/richtext/editor/ToolbarIcons.kt +67 -0
  5. package/android/src/main/res/drawable/ic_format_align_center.xml +3 -3
  6. package/android/src/main/res/drawable/ic_format_align_left.xml +3 -3
  7. package/android/src/main/res/drawable/ic_format_align_right.xml +3 -3
  8. package/android/src/main/res/drawable/ic_format_bold.xml +3 -3
  9. package/android/src/main/res/drawable/ic_format_checklist.xml +3 -3
  10. package/android/src/main/res/drawable/ic_format_clear.xml +3 -3
  11. package/android/src/main/res/drawable/ic_format_code.xml +3 -3
  12. package/android/src/main/res/drawable/ic_format_heading.xml +3 -3
  13. package/android/src/main/res/drawable/ic_format_highlight.xml +3 -3
  14. package/android/src/main/res/drawable/ic_format_indent.xml +3 -3
  15. package/android/src/main/res/drawable/ic_format_italic.xml +3 -3
  16. package/android/src/main/res/drawable/ic_format_link.xml +3 -3
  17. package/android/src/main/res/drawable/ic_format_list_bulleted.xml +3 -3
  18. package/android/src/main/res/drawable/ic_format_list_numbered.xml +3 -3
  19. package/android/src/main/res/drawable/ic_format_media_attachment.xml +3 -3
  20. package/android/src/main/res/drawable/ic_format_outdent.xml +3 -3
  21. package/android/src/main/res/drawable/ic_format_quote.xml +3 -3
  22. package/android/src/main/res/drawable/ic_format_redo.xml +3 -3
  23. package/android/src/main/res/drawable/ic_format_strikethrough.xml +3 -3
  24. package/android/src/main/res/drawable/ic_format_underline.xml +3 -3
  25. package/android/src/main/res/drawable/ic_format_undo.xml +3 -3
  26. package/ios/RichTextEditorView.swift +60 -12
  27. package/ios/RichTextEditorViewManager.m +2 -0
  28. package/ios/ToolbarIcons.swift +48 -747
  29. package/lib/commonjs/RichTextEditorViewNativeComponent.js.map +1 -1
  30. package/lib/commonjs/index.js +2 -0
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/module/RichTextEditorViewNativeComponent.js.map +1 -1
  33. package/lib/module/index.js +2 -0
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/typescript/src/RichTextEditorViewNativeComponent.d.ts +2 -0
  36. package/lib/typescript/src/RichTextEditorViewNativeComponent.d.ts.map +1 -1
  37. package/lib/typescript/src/index.d.ts.map +1 -1
  38. package/lib/typescript/src/types.d.ts +2 -0
  39. package/lib/typescript/src/types.d.ts.map +1 -1
  40. package/package.json +1 -1
  41. package/src/RichTextEditorViewNativeComponent.ts +2 -0
  42. package/src/index.tsx +2 -0
  43. package/src/types.ts +2 -0
@@ -1,9 +1,11 @@
1
1
  package com.richtext.editor
2
2
 
3
3
  import android.content.Context
4
+ import android.graphics.Bitmap
4
5
  import android.graphics.Color
5
6
  import android.graphics.PorterDuff
6
7
  import android.graphics.PorterDuffColorFilter
8
+ import android.graphics.drawable.BitmapDrawable
7
9
  import android.graphics.drawable.GradientDrawable
8
10
  import android.view.Gravity
9
11
  import android.view.View
@@ -57,6 +59,9 @@ class FloatingToolbar(context: Context) : LinearLayout(context) {
57
59
  private val activeColor = Color.parseColor("#5082C8")
58
60
  private val inactiveColor = Color.WHITE
59
61
 
62
+ private val iconSize = maxOf((20 * density).toInt(), 1)
63
+ private val iconPadding = (8 * density).toInt()
64
+
60
65
  private val buttons = mutableMapOf<String, ImageView>()
61
66
  private val buttonContainer: LinearLayout
62
67
  private val scrollView: HorizontalScrollView
@@ -193,12 +198,8 @@ class FloatingToolbar(context: Context) : LinearLayout(context) {
193
198
  }
194
199
  }
195
200
 
196
- private val iconSize = (20 * density).toInt()
197
- private val iconPadding = (10 * density).toInt()
198
-
199
201
  private fun createButton(option: String): ImageView? {
200
- val drawableResId = getDrawableResId(option)
201
- if (drawableResId == 0) return null
202
+ val bitmap = ToolbarIcons.getIcon(option, inactiveColor, iconSize) ?: return null
202
203
 
203
204
  val button = ImageView(context).apply {
204
205
  scaleType = ImageView.ScaleType.FIT_CENTER
@@ -214,9 +215,7 @@ class FloatingToolbar(context: Context) : LinearLayout(context) {
214
215
  params.marginEnd = buttonSpacing
215
216
  layoutParams = params
216
217
 
217
- // Set the icon - drawable will scale to fit within padding
218
- setImageResource(drawableResId)
219
- colorFilter = PorterDuffColorFilter(inactiveColor, PorterDuff.Mode.SRC_IN)
218
+ setImageBitmap(bitmap)
220
219
  }
221
220
 
222
221
  when (option) {
@@ -283,10 +282,11 @@ class FloatingToolbar(context: Context) : LinearLayout(context) {
283
282
 
284
283
  for ((option, button) in buttons) {
285
284
  val isActive = states[option] ?: false
286
- button.colorFilter = PorterDuffColorFilter(
287
- if (isActive) activeColor else inactiveColor,
288
- PorterDuff.Mode.SRC_IN
289
- )
285
+ val color = if (isActive) activeColor else inactiveColor
286
+ val bitmap = ToolbarIcons.getIcon(option, color, iconSize)
287
+ if (bitmap != null) {
288
+ button.setImageBitmap(bitmap)
289
+ }
290
290
  (button.background as? GradientDrawable)?.setColor(
291
291
  if (isActive) Color.parseColor("#40FFFFFF") else Color.TRANSPARENT
292
292
  )
@@ -55,6 +55,9 @@ class RichTextEditorView(context: Context) : androidx.appcompat.widget.AppCompat
55
55
  private var numberOfLinesValue: Int = 0
56
56
  private var showToolbar: Boolean = true
57
57
  private var variant: String = "outlined"
58
+ private var customFontFamily: String? = null
59
+ private var customFontSize: Float = 16f
60
+ private var customTypeface: Typeface? = null
58
61
  private var density: Float = 1f
59
62
  private var isInternalChange = false
60
63
  private var lastReportedHeight: Float = 0f
@@ -150,8 +153,8 @@ class RichTextEditorView(context: Context) : androidx.appcompat.widget.AppCompat
150
153
  // Disable vertical scrolling by default
151
154
  isVerticalScrollBarEnabled = false
152
155
 
153
- // Set white background by default
154
- setBackgroundColor(Color.WHITE)
156
+ // Transparent background so it inherits parent's background
157
+ setBackgroundColor(Color.TRANSPARENT)
155
158
 
156
159
  // Default outlined style
157
160
  applyVariantStyle()
@@ -211,6 +214,9 @@ class RichTextEditorView(context: Context) : androidx.appcompat.widget.AppCompat
211
214
  if (!handled) {
212
215
  handled = autoContinueListOnEnter(s)
213
216
  }
217
+ if (!handled) {
218
+ handled = applyInlineStyleShortcut(s)
219
+ }
214
220
  if (!handled) {
215
221
  isInternalChange = true
216
222
  renumberNumberedLists()
@@ -872,16 +878,16 @@ class RichTextEditorView(context: Context) : androidx.appcompat.widget.AppCompat
872
878
  private fun applyVariantStyle() {
873
879
  if (variant == "flat") {
874
880
  background = null
875
- setBackgroundColor(Color.WHITE)
881
+ setBackgroundColor(Color.TRANSPARENT)
876
882
  drawBottomBorder = true
877
883
  } else if (variant == "plain") {
878
884
  background = null
879
- setBackgroundColor(Color.WHITE)
885
+ setBackgroundColor(Color.TRANSPARENT)
880
886
  drawBottomBorder = false
881
887
  } else {
882
888
  drawBottomBorder = false
883
889
  val bg = GradientDrawable().apply {
884
- setColor(Color.WHITE)
890
+ setColor(Color.TRANSPARENT)
885
891
  cornerRadius = 8 * density
886
892
  setStroke((1 * density).toInt(), Color.parseColor("#E0E0E0"))
887
893
  }
@@ -958,6 +964,36 @@ class RichTextEditorView(context: Context) : androidx.appcompat.widget.AppCompat
958
964
  hint = value
959
965
  }
960
966
 
967
+ fun setFontFamily(value: String?) {
968
+ customFontFamily = value
969
+ customTypeface = if (value != null) {
970
+ try {
971
+ val assetPath = "fonts/$value.ttf"
972
+ Typeface.createFromAsset(context.assets, assetPath)
973
+ } catch (_: Exception) {
974
+ try {
975
+ val assetPath = "fonts/$value.otf"
976
+ Typeface.createFromAsset(context.assets, assetPath)
977
+ } catch (_: Exception) {
978
+ Typeface.create(value, Typeface.NORMAL)
979
+ }
980
+ }
981
+ } else {
982
+ null
983
+ }
984
+ applyFont()
985
+ }
986
+
987
+ fun setFontSizeValue(value: Float) {
988
+ customFontSize = if (value > 0) value else 16f
989
+ applyFont()
990
+ }
991
+
992
+ private fun applyFont() {
993
+ textSize = customFontSize
994
+ typeface = customTypeface
995
+ }
996
+
961
997
  fun setVariant(value: String) {
962
998
  variant = value
963
999
  applyVariantStyle()
@@ -1736,6 +1772,64 @@ class RichTextEditorView(context: Context) : androidx.appcompat.widget.AppCompat
1736
1772
  return false
1737
1773
  }
1738
1774
 
1775
+ private fun applyInlineStyleShortcut(s: Editable?): Boolean {
1776
+ if (s == null) return false
1777
+
1778
+ val start = selectionStart
1779
+ val end = selectionEnd
1780
+ if (start != end || start <= 0 || start > s.length) return false
1781
+
1782
+ var lineStart = start - 1
1783
+ while (lineStart > 0 && s[lineStart - 1] != '\n') {
1784
+ lineStart--
1785
+ }
1786
+
1787
+ val textBeforeCursor = s.subSequence(lineStart, start).toString()
1788
+ if (textBeforeCursor.length < 3) return false
1789
+
1790
+ data class ShortcutPattern(
1791
+ val regex: Regex,
1792
+ val apply: (Editable, Int, Int) -> Unit,
1793
+ )
1794
+
1795
+ val patterns = listOf(
1796
+ ShortcutPattern(Regex("(^|\\s)\\*([^*\\n]+)\\*$")) { editable, spanStart, spanEnd ->
1797
+ editable.setSpan(StyleSpan(Typeface.BOLD), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
1798
+ },
1799
+ ShortcutPattern(Regex("(^|\\s)_([^_\\n]+)_$")) { editable, spanStart, spanEnd ->
1800
+ editable.setSpan(StyleSpan(Typeface.ITALIC), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
1801
+ },
1802
+ ShortcutPattern(Regex("(^|\\s)~([^~\\n]+)~$")) { editable, spanStart, spanEnd ->
1803
+ editable.setSpan(StrikethroughSpan(), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
1804
+ }
1805
+ )
1806
+
1807
+ for (pattern in patterns) {
1808
+ val match = pattern.regex.find(textBeforeCursor) ?: continue
1809
+ val prefixWhitespaceLen = match.groupValues[1].length
1810
+ val styledText = match.groupValues[2]
1811
+ if (styledText.isEmpty()) continue
1812
+
1813
+ val markerStartInLine = match.range.first + prefixWhitespaceLen
1814
+ val markerStart = lineStart + markerStartInLine
1815
+ if (markerStart < 0 || markerStart > start) continue
1816
+
1817
+ isInternalChange = true
1818
+ s.replace(markerStart, start, styledText)
1819
+
1820
+ val styleStart = markerStart
1821
+ val styleEnd = markerStart + styledText.length
1822
+ if (styleStart < styleEnd && styleEnd <= s.length) {
1823
+ pattern.apply(s, styleStart, styleEnd)
1824
+ setSelection(styleEnd)
1825
+ }
1826
+ isInternalChange = false
1827
+ return true
1828
+ }
1829
+
1830
+ return false
1831
+ }
1832
+
1739
1833
  private fun renumberNumberedLists() {
1740
1834
  val editable = text ?: return
1741
1835
  val fullText = editable.toString()
@@ -106,6 +106,24 @@ class RichTextEditorViewManager : SimpleViewManager<RichTextEditorView>() {
106
106
  }
107
107
  }
108
108
 
109
+ @ReactProp(name = "fontFamily")
110
+ fun setFontFamily(view: RichTextEditorView, fontFamily: String?) {
111
+ try {
112
+ view.setFontFamily(fontFamily)
113
+ } catch (e: Exception) {
114
+ e.printStackTrace()
115
+ }
116
+ }
117
+
118
+ @ReactProp(name = "fontSize", defaultFloat = 16f)
119
+ fun setFontSize(view: RichTextEditorView, fontSize: Float) {
120
+ try {
121
+ view.setFontSizeValue(fontSize)
122
+ } catch (e: Exception) {
123
+ e.printStackTrace()
124
+ }
125
+ }
126
+
109
127
  @ReactProp(name = "variant")
110
128
  fun setVariant(view: RichTextEditorView, variant: String?) {
111
129
  try {
@@ -0,0 +1,67 @@
1
+ package com.richtext.editor
2
+
3
+ import android.graphics.*
4
+ import android.util.Base64
5
+
6
+ /**
7
+ * Provides toolbar icons as pre-rendered PNG images (base64-encoded).
8
+ * Icons are identical to those used on iOS for cross-platform consistency.
9
+ * All icons are rendered from the same SVG path data at 72x72px (3x density).
10
+ */
11
+ object ToolbarIcons {
12
+
13
+ private val iconData = mapOf(
14
+ "bold" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABvElEQVR4nO3aP0uXURjG8SvKpSgVaukl1BI1CM4u2Z/XUGtvQNwcBdFotEFEaCjaamhp7R+0REttFTRJZYMpBt845OL03IWd87s71wfOeg0XD4fznHNLZmZmZmZm9l/gcG0Cb4GHwA3gtLLj39oFVoEzyoo6PgNTyoh6fgDXlQ11bQOXlAn1vQfGlAVt3FIWxCwG1grwPJj3ETiiDAj4w7xZ4Gsg9qJ6LKgArgRi59VrQQXwYiD2rjovaHkg9pE6L2hlIPaxOi/o5UDsHfVaEHA1EHtNPRbE73K+DUR+SnOaJmYusG4Dr4J5N5UF9d1XJtT1BjipTKjnKTChbKhjB5hRRtS1BhxXJtRXDpDjyoI2yn50VBnQznxvN4qL+2sD+BLI/J7ivYyAv8gcBx4EoufUY0EFcAx4NhD9Wr0WVACXB6L3gBPquKBTgfjzGmW0L2haHRc0G4g/px4LAsaCD4mT6q0gYHJ/iGrIO406Du9GsawF4F7wZbVY1qijnZ8jv/80LmhdGdDGhxT/YUWDcrZSTZlRV3kPu6BMqHcnveRL+4PDmmUW8UkZtwPOtv4QzMzMzMzMzMzMzHTALzu/TlkIFz7bAAAAAElFTkSuQmCC",
15
+ "italic" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIElEQVR4nO3Xy0mDURRF4a1jjU34qkRCsBEJIdiIhBBsREKwEqM24WOsS2zgPwchg7j3N72zxYHNlSIiIiIiIsIGO6Z9RwINS6BCAhUSqJBAhQQqJFAhgf4IuG/Eu5EjYAS8F3F+30dyBNw2rudOjoAD4LmI8w2cyxFw3bieB7kCHhuBruQIOAO+ijgvwKEcAavG9UzlCDhuTPuH87TPG9ezkPG0bxvTfiFHwKRxPWu5AjaNQGM5ItM+DFg2rmcm42l/a0z7iRwBs8b1LGU87U+Nab+UI2DcuJ6NXAHrRqCJHAGnjV/7q/OvfdG4nrkcAUeNaf90nvZp43pW+q/YMe07EmhYAhUSqJBAhQQqJFAhgQoJFBEREREREREREbL3A+hWfBELhFT9AAAAAElFTkSuQmCC",
16
+ "underline" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxElEQVR4nO3XQUpbQRzH8T910era7ltBe41SeoWiJ6h4Cw+gySYU92nTVXuIiIQWcSNVz6AeIG7ylYG3kFLm91Ln4Tz5fSAQQpjf5Jf35s1EmJmZmZl1ibz9DvL2c4FRG1xQngsSXJDgggQXJLggwQUJLkhwQYILElyQ4IIEFyS4IMEFCS5IcEGCCxJckOCCBBckuCDBBQnAXaakgygMGGTy5lEb4DYz4UkHed8zeddRG+AsM+E/HeRdZvJOozbAN/I2C2a9E1njqA2wJyZ9WDBrKLI+R22ADWCRmfQceFMoJ/dAWJTI6QRwIv7ZU2DtEeO/An6JjGnUCthB+5F+6H+MvQr8bDH+p6gVsAJctPgR6Sp4u+Rt9bvFuOfAi6gZ8JF25s1iuyWeVkOx5jxce95HHwBHLCftaSbN7njQvL9acoxR9AXtFtOSZsDL6BPgdcv16LFSxnr0EbDe8ZU06205f91uXwoXkxbkUe9uqxzgQzq0FijnvDdPq2WlPQqwDRyLY8m/rphp2gRWv88pJW0UgV3ga3MEuW32O+l103w2br5T59nKzMzs+aInXJDgggQXJLggwQUJT/soMzMzM7N4ju4BPDGZUVsSfzcAAAAASUVORK5CYII=",
17
+ "strikethrough" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAdUlEQVR4nO3VwQ2AQAzAsO6/dNmAiBc6sEfIJzMAAAAcZQ8hUBAoCBQECgIFgYJAQaAwJ9qH5m9WoHsCBYGCQEGgIFAQKAgEAEcu+RQCBYGCQEGgIFB4d30A8Fn70PzNCnRPoCBQECgIFAQKAgWBAAAAAOYNF59/SnvOM5yQAAAAAElFTkSuQmCC",
18
+ "code" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABGklEQVR4nO3ZMU7DQBgF4a3TIYHETVPapQ9HQ8N1BkWQIlKUAPHu/k/Md4Dn3ZGVIm5NkiRJkiRJkkoAVmBL3e+Kr8OfbWn7XXF5+N0v0Xu/K64ffrdL9N7vituHP3kHDg/sH743bllbcJznHZ7zBLzdedb2L+NERmJwnKhITIoTEYnJcUpHokickpEoFqdUJIrGKRGJ4nGmRiIkzpRIhMUZGonQOEMipcfpHgk43hn9AF5bccDLD/4BWP46fkyO1DVOeiRGxEmNNDROWqQpcVIiTY1TPVKJOFUjlYpTLVLJOFUilY4zO1JEnFmRouKMjhQZ58xPz4+/SUv1/SG4foklZX8ILi+xpO2P/E1aU/clSZIkSZIkqf3KJ7XdjUR0XLs+AAAAAElFTkSuQmCC",
19
+ "highlight" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABeUlEQVR4nO3UTUrEQBRF4Wfj1J/dOHMuuAAHoiC4BoeuQxHRrYiCuCWVIw0GGjX1ukkquYn3W0DVy6HyIszMzKwDWnQ5c1ZwoDIHSjhQwoESDvQfAwHHwI56IGAfOOrjrE0uPQE+gBdgVzUQsAe8fs962vW8TeM0eonUt5U4jfqR+B1HMtIfcepHAg6BT9o997WTetg5b4U534GDGhcvgIfCxaO/pMLLWXW3/JZaAyyAx2SAp2oDlGfbXiPOLbBVe5BF4SUtf8HzqgOUZ7sorIF6L2fNSKPGSSINF6clkkSclkjDx/kR6R44CzHAJXBTfeeYmQTEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrEhBrgCh3XoQiNSJpxRCJpxxk50jTijBRpWnEGjjTNOANFmnacypHmEadSpHnFafRVJ+YKBypzoIQDJRwo4UAJB0o4UMKBEg6UcKCEAyUcKOFACQcyMzOLAX0B6ECHyn/I8bMAAAAASUVORK5CYII=",
20
+ "heading" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAhUlEQVR4nO3QsQ2AQBADwSudzg/RAJshvZiJnXhnAAAAOMoeQqAgUBAoCBQECgIFgYJAYU61u1edezbzVyvQO4GCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQAAAAADztRu2Ullm5rngbwAAAABJRU5ErkJggg==",
21
+ "bullet" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABG0lEQVR4nO3aXW7CMBBFYa8AWAwEuqsSFoYotCzvVJbSpzixpUYKxueT8hSRsSbk72pCkCRJkiSpVsAH0ANn4LT2el4GsAOejH3HfaF1pJvz5zHxmyosdVnlHFtu0KWgTm+D5p1bbtCpoE7XbIOi4Wk15R4SqERY8DH/SBz/DmwXKfIOgG54SfwEDmuvR5IkSS8CE8XJxuxMFOf/Oc+Z7z0TRfJMFDNMFDNMFDNMFJlmooiJYvGLYmeiKEmSpBFMFNOALfCT+A6LAw0OLzA//vI10dQq/PtGgQNU2QZdCk5E04liX1Cn6UTxWFBnNExFKw2K4o14psY1JFCJsARgA9wSx7/GfYsUeQfAYZhPjNt+7fVIkiRJkhRa9QtNmk8JUv9uigAAAABJRU5ErkJggg==",
22
+ "numbered" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABDklEQVR4nO3XsU3EMBhAYReIDokNKFiHillArMAEVCxCxQwUzEBBfR3o0URgieRsnxPEf36flC7+o7wkSpKSJEmSJOnfYEGSgap4BzWg8REjiJYGBupBY3WC6IpioAY0VieIlgYG6sEW1Y8JBjKQJEkD+dNP9YgM1B9oV5oxFOACeJvifALXe/YNYc04Z8BLNvumsH8Ia8U5AZ6yuY8Va4YK9JDNfAZODfQT5zaL8wqcV0YNoffOuQI+plnvwGXD2iEC7TY9QHSbX4HoDCRJ0tHyNV9goAIDHYiKXw2COLTB3AnfZVvxAAwYaJaBJvN5DPQNuM82A+2DgX6HWJJGtlglk0ZGhSRJkiRJUlrfF/qJCMx4HPSsAAAAAElFTkSuQmCC",
23
+ "quote" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAsklEQVR4nO3S0QkCURAEwQvNzA1tzOCdHzYqVAXQ7MBeFwAAAAAA8P/2Id/q5xYPqPu5xQPqfm7xgLqfWzyg7ucWD6j7ucUD6n5u8YC6n1s8oO7nFg+o+7nFA+p+bvGAup9bPKDu5xYPqPu5xQPqfm7xgLqfWzyg7ucWD6j7X7ft8cb9z1/t57Y93xjw+NV+ar7nzPcc+J4bvufA99zwPQe+54bvOfA9N3wPAAAAAABwlV6W3Lr8+te/TgAAAABJRU5ErkJggg==",
24
+ "checklist" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABbUlEQVR4nO3ZzUkDQQBH8fHsJdiCJ78gQUsSLMUCPGktYgEe7EEvagixAn2ymIUo7MxkNya7mfc7m3XymITAPwRJkiRJ2g3A/rbP0FvAJfAMHG77LH2N88mPFyM1x6kZKRLHSBlxKm/AcSgR6TjvwEkYOmACXAN7K7zmCviKxHkFjsLQAWNgtnhTdzmRSro546U45ETKjHMadjRONNK647BBbQLdJ555sxwp4ztn5Y8VPQ80Ah4Tz72tImXcnClw1uIM/Q20OOAB8JR49kPi5kzbfufQ90Ar3KS13pwaG9T2jF0idYqz+L8b0+WcbSJ1jjNI5EWaA+ehVMQjlR0nEck4kUgfwMWvP1CofydVv7gn9pB6A3exZu5iEe5iEe5iEe5iEe5iESWtGxN3seY4Y3exvDg1d7FInJq7mLtYgrtYBtzFsiKN3MX+J9LUXayZu1hE2esG7mKtI82Lvjl/uYtlwF1MkiRJkiQpDMw3gf9lg/avHogAAAAASUVORK5CYII=",
25
+ "mediaAttachment" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACF0lEQVR4nO2bL08cQRiH99JAQyowGAqpqMW1HwDNBwBJSHD8qeELVKAraiuQTV01njsI0GAwVU0q6po0B6kg8JBJN4Rcjntndt8ru8Pv8e+ffTL37mRnriiEEEIIIYSoC/Ac2AYOgQvaQ+i1B2wBk+OSMwec0X6+AS/HsXLOyIdT15UEvCM/Nj0FHZEfPU9BffKj7ykoSyTIQIIMJMhAggwkyECCDCTIQIIMJMhAggwkyECCDCTIQIIMJMhAggwkyECCDCTIQIKemKA+sOx55J2boJWylzWvhDkJ+jDQz55H0lwEdQfP0YEXwHlOgk4qxv166CYGsFB3HjVF0D7wDPicGHcFLBp9rbVd0A9gpswxlXgJYieyt722CvoLvB3IMwv8jIj9CnQie6s8jx5b0PoDud4AlyPivgPTif1VmkePKeiTkS9s+G6GxIWHXKjYY/I8qixkSPEUwlW9qYicu0NiV2v2mTSP6tQaLBzLb+B1ZM4O8OVe7EeHPpPmUd16d0TWuwaWigTKN9txea3Y5VJlyjzyqJci6H1RAeAVMF8ltu488iwYtRksGkTMPPIsFrUZbBIx88izWPRmsElY88izUNJmsEmMmkeeRbJEggwk6D8K6pMffzwFHZIfXU9BW+THhqegyfKferkQvpFPuAkKhI/nmUgKcmaLccC/lbRZHsW0aXCHXg/Cz8p95QghhBBCiOJJcgtCLsL+N1x3iwAAAABJRU5ErkJggg==",
26
+ "link" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACPElEQVR4nO3ZTU4UQRjG8RIW4gXEszjBOxg9g6BrYLbGYOLH6DVIPIRAIpkroBudYQOcwCE6f1Pysuuq6Y+3e6bJ80tm+9bT73RXVVeHICIiIiIiIiIiIiIi/QesA1vACBgDl8A1FWXqV3VtGcaWKWZb77Yr4X/wB8DQwjSWGcdDzLgfM3fVnOfAOY5abtCtKfCszcbcA14Dc+fgXTUIy/4OWPNuzhpwSEs6bNCtQ9cmAW9LDPoHOAOOgS9VfplxK9WxsWOGvyXyHnjOOfPMQD+BbeBhWBExC7ADTDK5543nJG5Wq9yE/B64H1YUsGHLfUps4EaTAYaZ4i9CT9gdnrLXZBN4mbpzQs9k7qSLWhM28CQz56zsY7XgcfuVuKZBnYKfEsW2Q08BLxPX9LFOsXFBobh8blas06oaq1vRFuBbnQZdFRQ6q1FnZRpkeX4UlLkINQrNCgp9vQMNOioo89urQUd3oEHHXg26KiikR6zEJP2oYqNbVTHLpuckPUpk2gk9BbxKXNOHOsW2EsXOOzud898opl5eH3u/aoxCzwCfXV81rOg+ab3ZUdvRR8pu0+OOaab4qNFxQcssf+rOaX7cEcVDpQUHZhN7x6n0CtKmuNLahJz7c+M1PfUa8IDF4vL5HThZ4pHriWUoc+T6xqU5kQ7ty3/2GeqzT7k5aYqjzFieJm5zTslN157tIVa9QTHj7lJWW24+KA7iVh04tTCzJTZoZhlOLdPA/SuqiIiIiIiIiIiIiIiEpfgHLFVfxDn1QdwAAAAASUVORK5CYII=",
27
+ "undo" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACP0lEQVR4nO3YTahMYRgH8HN9Jm5XLJC7sFEiNxtJ+VzISpKVYoGFjRQWUsjSgmSFtYWUZGFFUnchoZsklAUllOSGJC73p8MpX3NmzMy5M2em51ezO+/7/ufpnPc8502SEEIIIYQQQgghhBBCCCGEEMIPOJwUDPOxAydwBY/wCu/wEL1Jp/DTgSbnGIdVOIsXaruAnqQT+GVfA2N7sR/P1G9v0gn8Mord/zlmCo5gWOO+YGVSdv6UFmlXjes34alivMScpMz8q2KRsscp3WOKdhOTkrJS2Tds++2aRXhi7JzB0mydWUmZyPcVW7C2yb2mEWk7cAensBl9ZSxQagSftd8nXMKGtKUoU4HK6HHWhI6PAlV3D2viDqpuNHuzTu3GR2wk68DvYhC3cT/boOuVjpvX6QUaxjnsxEJMrJJpNjbiZB2fMa+xvBMLdCPrvic3mK8Hq3Ex68+qeY8VnVKgQSwrOOsArtZY90PadBa5aNHeYmthAStn3l5jr0qPXPqLWqzo76q5hQSrnXtB1hPluYUJRSxUlAeN7jNNZJ+ZvQXzHC1ikSI1H6j+/H3Zaz6vlVjc7AK6oEj92Zl3JdeanVyXFGldlTZgfTMT66Iinc7Jcr2ZSXVLkTADb3KyLGl00rF2rPBKVP8/h3JyHG90wlZo2Z2E6fhYIcPzhg7btE7L7qTso7iSgVZlKLXsaLaSPe3OVgqYlnOWfr7d2UoDQxUKNNTuXKWBg2kX/dfvcrtzhRBCCCGEEEIIIYSQlNV3D0IwYRMB14IAAAAASUVORK5CYII=",
28
+ "redo" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACJ0lEQVR4nO3XzYtNYRzA8TGGBWpSbJSNBVaMha1iISywsbWckn/CRpGiGAsv2aNQRlIslFjIxsLLioWXFPK28vbRaZ6FNOOec895zjn0+9RsptvzPPd7zzn3/kZGQgghhBBCCCGEEEIIIYQQ+gIHuj5Dr+NA1+fodZxeBMICbMQ+nMINPMF7fEnn/IQ36f/XcSK9fh1Gc8XpLBCWYC8u4qN6PuAC9mBRk3FaD2TmEz+Hz/Io1j2JNU3EaS0QJnAVP7Wj2OcS1taJkz0QluMMfujGt3RFjQ8Tp5Azzna81A+vsatqnEKOMAvTp9ZHRzFWNk4hxy11p8Yb+I5H6XlVRD7021/xE+Aanta8ZW/hcNkXNxlnJR4PceDnOIItxdd/yb3G0y08hVcyajLOs4rfMjexG/Nr7j2KnWm9/gXCsnRblFXcgutrbzz7WTbhXm8CmRkTbpfcqxgdJjGvsSJzX1H703jSeaBjJfe5jxWNVSh3ttV42Fkg7Ci5x+W6M1KNMx7sJBCW4kWJ9aeanrYrnLHU75xcgaZKrD1d9xuq6zhDBSoGQHwdsO4DLM7y7luMM2yg8wPWfNf2AzlXnMqBsCqNA38zma1Ay3EKVQ9xfMB6d7t4KOeKUylQmtLfDhgfJrKWaDlO1UAb0vNlLleyluggTmGY0WIbzs5yNW3OVqKjOJUD/XHAMWzF6TRKjP5vcWoFCiGEEEIIIYQQQgghhBBCCGHk3/cLZTX3NeIaKrMAAAAASUVORK5CYII=",
29
+ "clearFormatting" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB2klEQVR4nO3bzS4DURTA8YPYSLDyCNh4DkktSXwUC0sSHoUQz6AbW/UgNsKStQQ7X3+ZILHQe087d3DPPf91Z9r+ctsznemIeJ7neZ7neZ7neZ7nlRUwCnSA1cjjbsmg1DgjwMnnvl+AzcBjp3NAagoHK0gpgTo9nqNCWssVKSXQIvAUQNrIESkZkFUkSR3GkJIDWUOSpsIIUmNAdZFCAfuK97YtOURiJGAMuIvgPAATkkskRAJ2FKvnQHKLREjARQTnDZiRHKMmEjCvWD1nknPAUgDpOXQWQDndWpJ7NHcIcA0Mi4VoBmlPLEVapEdgUqxFOqRjsRpxpPUI0g0wJ5YjPt1WAttOSQlRYyUVE44Uz5EUVVdDenzUvr6TlqXkgL0AUNnfScAQcBkBKhcJaClwykUCun0AlYXEx5Hxa59A5SABRwPgfEdqi9WAceBecUJ+K3LE3S51tFcdKn+WtEsc7W/A7LdtykECFojX/WG7MpCAcwXQjyfkzSOhG+1XoRPyppHQjfZdxX7sIaEf7apr7eaQ6GO097FPG0gMMNqLQkI32ge+1q5A6vnv22LCkeI5Uv3rbh3NPkpdSafVDTh//dr+K5LjBD5u1b0lvnI8z/M8z/M8+ZXeAZv5+Z1GOJFfAAAAAElFTkSuQmCC",
30
+ "indent" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA2UlEQVR4nO3WQQ7DIAwFUW7uLrn1r7LIqqqcUJsUM+8AVhhApDUAAABglIoaDkKgm1TU3Q4EGqWihoMQCAAABFn+PygbgaoHktTDhhUNpMxIekjGAnrY0KKBlH3dlqRPRHICHYh00ndEcgIR6UIgIumanjw/3Oj3/rKATqCESNroBB2MQIFxdjpBljx/6UDWdibiDAeySXv030Sc24Fs0t6sQcS5HMgmbMA00QuwsIEFA73ChlUMlI1ADgI5CAQAwHbPcDYCOQjkIJCDQA4COZ579gAAANBW9waRrOCa9HpusgAAAABJRU5ErkJggg==",
31
+ "outdent" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA7ElEQVR4nO3ZwQqDQAxF0fx1t/75Ky0upFTThElHzT3bQSZehRE0AwAAALJ0U+kgBArSTUU7EChLN5UOQiAAADDI5b+DqhHI0SqQpCVxTY9AkpbMxi0CaY1DICfO35/M2ekjDoGcOARy4hDIjuO0DyQnTutA+iFOJpAmmRKnZSAF4mQ2rkswds6jG3hUblyXYOycwyJZx0CRSBZUn2LMnMMiWXdyIs2e7/SRDMeR1mXsRXovYD/SZgnfIlmQJrFZkSx+XY9AL/z2KdDqDcogkINAAAC0O4arEchBIAeBHARyEMgx79gDAACAXd0TF7nf4uYCfIsAAAAASUVORK5CYII=",
32
+ "alignLeft" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAiElEQVR4nO3VsREDMAwDMe2/NDOCLm7MOMAI3/wMAACcyqOOgwj0pTzq2w4CncqjjoMIBAB/I2WmTcpMm5SZNikzbVJm2qTM7R4A8JA8SqCFQAuBFgItBFrcXR8AVEiZaZMy0yZlpk3KTJuUmTYpc7sHADwkjxJoIdBCoIVAC4EWd9cHAMD8sg+q0NtM71VCsAAAAABJRU5ErkJggg==",
33
+ "alignCenter" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAfUlEQVR4nO3W0QnAMAxDwey/tDtBIxooweZuhPcjrQUAAKdqqOMgAn1UQ33tINCpGuo4iEAAwIv2v+ZvJdCeQIFAgUCBQADQRg0lUCBQIFAgUCBQcHf6AKClumR1UQLtCRQIFAgUCAQAbdRQAgUCBQIFAgUCBXenDwCA1dkDHN+8XSMaKtEAAAAASUVORK5CYII=",
34
+ "alignRight" to "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAiElEQVR4nO3VQREEMQwDQfMnrYPg2nyiS3VDmM/MAADAqTzqOIhAH+VRXzsIdCqPOg4iEADwUcpMm5SZNikzbVJm2qTMtEmZ2z0AoEAeJdBCoIVAC4EWAi3urg8AnpIy0yZlpk3KTJuUmTYpM21S5nYPACiQRwm0EGgh0EKghUCLu+sDAGD+2Q90dNtMxzL28wAAAABJRU5ErkJggg==",
35
+ )
36
+
37
+ private val iconCache = mutableMapOf<String, Bitmap>()
38
+
39
+ fun getIcon(option: String, color: Int, size: Int): Bitmap? {
40
+ val cacheKey = "${option}_${color}_${size}"
41
+ iconCache[cacheKey]?.let { return it }
42
+
43
+ val b64 = iconData[option] ?: return null
44
+ val bytes = Base64.decode(b64, Base64.DEFAULT)
45
+ val original = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: return null
46
+
47
+ val safeSize = maxOf(size, 1)
48
+ val scaled = Bitmap.createScaledBitmap(original, safeSize, safeSize, true)
49
+ if (scaled !== original) original.recycle()
50
+
51
+ // Apply tint color
52
+ val tinted = Bitmap.createBitmap(safeSize, safeSize, Bitmap.Config.ARGB_8888)
53
+ val canvas = Canvas(tinted)
54
+ val paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG)
55
+ paint.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
56
+ canvas.drawBitmap(scaled, 0f, 0f, paint)
57
+ scaled.recycle()
58
+
59
+ iconCache[cacheKey] = tinted
60
+ return tinted
61
+ }
62
+
63
+ fun clearCache() {
64
+ iconCache.values.forEach { it.recycle() }
65
+ iconCache.clear()
66
+ }
67
+ }
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M7,15v2h10v-2H7zM3,21h18v-2H3v2zM3,13h18v-2H3v2zM7,7v2h10V7H7zM3,3v2h18V3H3z"/>
8
+ android:pathData="M120,840l0,-60 720,0l0,60L120,840ZM240,700l0,-60 480,0l0,60L240,700ZM120,560l0,-60 720,0l0,60L120,560ZM240,420l0,-60 480,0l0,60L240,420ZM120,280l0,-60 720,0l0,60L120,280Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M15,15H3v2h12v-2zM15,7H3v2h12V7zM3,13h18v-2H3v2zM3,21h18v-2H3v2zM3,3v2h18V3H3z"/>
8
+ android:pathData="M120,840l0,-60 720,0l0,60L120,840ZM120,700l0,-60 480,0l0,60L120,700ZM120,560l0,-60 720,0l0,60L120,560ZM120,420l0,-60 480,0l0,60L120,420ZM120,280l0,-60 720,0l0,60L120,280Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M3,21h18v-2H3v2zM9,17h12v-2H9v2zM3,13h18v-2H3v2zM9,9h12V7H9v2zM3,3v2h18V3H3z"/>
8
+ android:pathData="M120,840l0,-60 720,0l0,60L120,840ZM360,700l0,-60 480,0l0,60L360,700ZM120,560l0,-60 720,0l0,60L120,560ZM360,420l0,-60 480,0l0,60L360,420ZM120,280l0,-60 720,0l0,60L120,280Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M15.6,10.79c0.97,-0.67 1.65,-1.77 1.65,-2.79 0,-2.26 -1.75,-4 -4,-4H7v14h7.04c2.09,0 3.71,-1.7 3.71,-3.79 0,-1.52 -0.86,-2.82 -2.15,-3.42zM10,6.5h3c0.83,0 1.5,0.67 1.5,1.5s-0.67,1.5 -1.5,1.5h-3v-3zM13.5,15.5H10v-3h3.5c0.83,0 1.5,0.67 1.5,1.5s-0.67,1.5 -1.5,1.5z"/>
8
+ android:pathData="M272,720L272,240l228,0q65.98,0 114.49,44.21Q663,328.42 663,394q0,38.4 -18,69.7 -18,31.3 -49,49.3 38,17 60.5,52.83Q679,601.67 679,645q0,70.64 -50.5,117.82Q578,810 508,810L272,720ZM348,476l164,0q38.64,0 65.82,-25.09Q605,425.82 605,388q0,-37.82 -27.18,-62.91Q550.64,300 512,300L348,300l0,176ZM348,750l182,0q41.81,0 71.41,-27.17Q631,695.65 631,652q0,-43.65 -29.59,-70.83Q571.81,554 530,554L348,554l0,196Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M22,7h-9v2h9V7zM22,15h-9v2h9v-2zM5.54,11L2,7.46l1.41,-1.41 2.12,2.12 4.24,-4.24 1.41,1.41L5.54,11zM5.54,19L2,15.46l1.41,-1.41 2.12,2.12 4.24,-4.24 1.41,1.41L5.54,19z"/>
8
+ android:pathData="M480,760l0,-60 360,0l0,60L480,760ZM480,510l0,-60 360,0l0,60L480,510ZM480,260l0,-60 360,0l0,60L480,260ZM222,836L120,734l42,-42 60,58 140,-140 42,44L222,836ZM222,586L120,484l42,-42 60,58 140,-140 42,44L222,586ZM222,336L120,234l42,-42 60,58 140,-140 42,44L222,336Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M3.27,5L2,6.27l6.97,6.97L6.5,19h3l1.57,-3.66L16.73,21 18,19.73 3.55,5.27 3.27,5zM6,5v0.18L8.82,8h2.4l-0.72,1.68 2.1,2.1L14.21,8H20V5H6z"/>
8
+ android:pathData="M792,826L530,564l-64,156 -60,0 88,-212L406,420l-70,0 0,-60 28,0L148,144l42,-42 644,682 -42,42ZM534,360l30,-72 52,0l0,-48L346,240l0,-60 330,0l0,60 -52,0 -48,118 -42,-44l0,46Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
8
+ android:pathData="M344,768L96,480l248,-288 46,42 -206,246 206,246 -46,42ZM616,768l-46,-42 206,-246 -206,-246 46,-42 248,288 -248,288Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M5,4v3h5.5v12h3V7H19V4H5z"/>
8
+ android:pathData="M160,240l0,60 260,0l0,400 60,0l0,-400 260,0l0,-60L160,240Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M6,14l3,3v5h6v-5l3,-3V9H6V14zM11,2h2v3h-2V2zM3.5,5.88l1.41,-1.41 2.12,2.12L5.62,8 3.5,5.88zM16.96,6.59l2.12,-2.12 1.41,1.41 -2.12,2.12 -1.41,-1.41z"/>
8
+ android:pathData="M320,880l0,-160 -80,-80 0,-200 -80,0 0,-60 560,0 0,60 -80,0 0,200 -80,80 0,160L320,880ZM380,820l200,0 0,-130 80,-80 0,-170L300,440l0,170 80,80 0,130ZM420,160l60,0 0,120 -60,0 0,-120ZM636,266l42,-42 84,86 -42,42 -84,-86ZM198,310l84,-86 42,42 -84,86 -42,-42ZM480,610Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M3,21h18v-2H3v2zM3,8v8l4,-4 -4,-4zM11,17h10v-2H11v2zM3,3v2h18V3H3zM11,9h10V7H11v2zM11,13h10v-2H11v2z"/>
8
+ android:pathData="M120,840l0,-60 720,0l0,60L120,840ZM440,700l0,-60 400,0l0,60L440,700ZM120,620l160,-140L120,340l0,280ZM440,560l0,-60 400,0l0,60L440,560ZM440,420l0,-60 400,0l0,60L440,420ZM120,280l0,-60 720,0l0,60L120,280Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M10,4v3h2.21l-3.42,8H6v3h8v-3h-2.21l3.42,-8H18V4z"/>
8
+ android:pathData="M224,800l0,-60 154,0 168,-520L392,220l0,-60 336,0l0,60 -150,0 -168,520L560,740l0,60L224,800Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4V7H7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9H7c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2H8v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4V17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z"/>
8
+ android:pathData="M440,680L280,680q-83,0 -141.5,-58.5T80,480q0,-83 58.5,-141.5T280,280l160,0l0,60 -160,0q-58,0 -99,41t-41,99q0,58 41,99t99,41l160,0l0,60ZM320,510l0,-60 320,0l0,60L320,510ZM520,680l0,-60 160,0q58,0 99,-41t41,-99q0,-58 -41,-99t-99,-41l-160,0l0,-60 160,0q83,0 141.5,58.5T880,480q0,83 -58.5,141.5T680,680l-160,0Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M4,10.5c-0.83,0 -1.5,0.67 -1.5,1.5s0.67,1.5 1.5,1.5 1.5,-0.67 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM4,4.5c-0.83,0 -1.5,0.67 -1.5,1.5S3.17,7.5 4,7.5 5.5,6.83 5.5,6 4.83,4.5 4,4.5zM4,16.5c-0.83,0 -1.5,0.68 -1.5,1.5s0.68,1.5 1.5,1.5 1.5,-0.68 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM7,19h14v-2H7v2zM7,13h14v-2H7v2zM7,5v2h14V5H7z"/>
8
+ android:pathData="M360,760l0,-60 480,0l0,60L360,760ZM360,510l0,-60 480,0l0,60L360,510ZM360,260l0,-60 480,0l0,60L360,260ZM180,790q-33,0 -56.5,-23.5T100,710q0,-33 23.5,-56.5T180,630q33,0 56.5,23.5T260,710q0,33 -23.5,56.5T180,790ZM180,540q-33,0 -56.5,-23.5T100,460q0,-33 23.5,-56.5T180,380q33,0 56.5,23.5T260,460q0,33 -23.5,56.5T180,540ZM180,290q-33,0 -56.5,-23.5T100,210q0,-33 23.5,-56.5T180,130q33,0 56.5,23.5T260,210q0,33 -23.5,56.5T180,290Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M2,17h2v0.5H3v1h1v0.5H2v1h3v-4H2v1zM3,8h1V4H2v1h1v3zM2,11h1.8L2,13.1v0.9h3v-1H3.2L5,10.9V10H2v1zM7,5v2h14V5H7zM7,19h14v-2H7v2zM7,13h14v-2H7v2z"/>
8
+ android:pathData="M120,820l0,-60 100,0l0,-30 -60,0l0,-40h60v-30L120,660l0,-60 160,0l0,110 -50,0 0,0 50,0l0,110L120,820ZM120,580l0,-50 90,-80L120,450l0,-50 160,0l0,50L190,530l90,0l0,50L120,580ZM180,380l0,-200 -60,0l0,-50 110,0l0,250L180,380ZM360,760l0,-60 480,0l0,60L360,760ZM360,510l0,-60 480,0l0,60L360,510ZM360,260l0,-60 480,0l0,60L360,260Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M19,3H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2zM19,19H5V5h14v14zM8.5,11A1.5,1.5 0 1,0 8.5,8A1.5,1.5 0 1,0 8.5,11zM6,17h12l-3.75,-5 -2.75,3.54 -1.75,-2.04L6,17z" />
8
+ android:pathData="M200,840q-33,0 -56.5,-23.5T120,760l0,-560q0,-33 23.5,-56.5T200,120l560,0q33,0 56.5,23.5T840,200l0,560q0,33 -23.5,56.5T760,840L200,840ZM200,780l560,0q7,0 13.5,-6.5T780,760l0,-560q0,-7 -6.5,-13.5T760,180L200,180q-7,0 -13.5,6.5T180,200l0,560q0,7 6.5,13.5T200,780ZM300,680l360,0 -120,-160 -90,120 -60,-80 -90,120ZM180,780l0,-600 0,600Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M11,17h10v-2H11v2zM3,12l4,4V8l-4,4zM3,21h18v-2H3v2zM3,3v2h18V3H3zM11,9h10V7H11v2zM11,13h10v-2H11v2z"/>
8
+ android:pathData="M120,840l0,-60 720,0l0,60L120,840ZM440,700l0,-60 400,0l0,60L440,700ZM280,620L280,340L120,480l160,140ZM440,560l0,-60 400,0l0,60L440,560ZM440,420l0,-60 400,0l0,60L440,420ZM120,280l0,-60 720,0l0,60L120,280Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M6,17h3l2,-4V7H5v6h3zM14,17h3l2,-4V7h-6v6h3z"/>
8
+ android:pathData="M580,640l80,-160L520,480l0,-200 200,0l0,200l-80,160L580,640ZM220,640l80,-160L160,480l0,-200 200,0l0,200l-80,160L220,640Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
8
+ android:pathData="M396,760q-89,0 -152.5,-53T180,556q0,-98 63.5,-155T396,344l344,0L596,200l42,-42 218,218 -218,218 -42,-42 144,-144L396,408q-63,0 -109.5,40T240,552q0,64 46.5,106T396,700l284,0l0,60L396,760Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M10,19h4v-3h-4v3zM5,4v3h5v3h4V7h5V4H5zM3,14h18v-2H3v2z"/>
8
+ android:pathData="M80,540l0,-60 800,0l0,60L80,540ZM478,380l-134,0 0,-140 272,0 0,140 -78,0 0,-80L538,300l0,80ZM404,580l152,0l0,80L404,660l0,80L344,740l0,-80L344,580l60,0Z"/>
9
9
  </vector>
@@ -1,9 +1,9 @@
1
1
  <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  android:width="24dp"
3
3
  android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
6
  <path
7
7
  android:fillColor="#FFFFFF"
8
- android:pathData="M12,17c3.31,0 6,-2.69 6,-6V3h-2.5v8c0,1.93 -1.57,3.5 -3.5,3.5S8.5,12.93 8.5,11V3H6v8c0,3.31 2.69,6 6,6zM5,19v2h14v-2H5z"/>
8
+ android:pathData="M200,880l0,-60 560,0l0,60L200,880ZM480,740q-100,0 -170,-68.5T240,504l0,-344 60,0l0,344q0,74 51,124t129,50q78,0 129,-50t51,-124l0,-344 60,0l0,344q0,99 -70,167.5T480,740Z"/>
9
9
  </vector>