umap-project 3.1.2__py3-none-any.whl → 3.2.0__py3-none-any.whl

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.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (151) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/en/LC_MESSAGES/django.po +21 -17
  3. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/fr/LC_MESSAGES/django.po +21 -17
  5. umap/management/commands/export_pictogram.py +29 -0
  6. umap/management/commands/migrate_to_S3.py +5 -1
  7. umap/management/commands/purge_old_versions.py +8 -6
  8. umap/settings/__init__.py +21 -0
  9. umap/settings/base.py +1 -0
  10. umap/static/umap/content.css +7 -2
  11. umap/static/umap/css/icon.css +77 -3
  12. umap/static/umap/css/panel.css +31 -1
  13. umap/static/umap/js/modules/browser.js +1 -1
  14. umap/static/umap/js/modules/data/features.js +14 -29
  15. umap/static/umap/js/modules/data/layer.js +248 -136
  16. umap/static/umap/js/modules/facets.js +2 -2
  17. umap/static/umap/js/modules/form/fields.js +56 -19
  18. umap/static/umap/js/modules/formatter.js +36 -8
  19. umap/static/umap/js/modules/importers/opendata.js +23 -6
  20. umap/static/umap/js/modules/managers.js +59 -0
  21. umap/static/umap/js/modules/rendering/icon.js +3 -5
  22. umap/static/umap/js/modules/rendering/layers/classified.js +8 -7
  23. umap/static/umap/js/modules/rendering/map.js +1 -1
  24. umap/static/umap/js/modules/rendering/ui.js +13 -0
  25. umap/static/umap/js/modules/rules.js +76 -23
  26. umap/static/umap/js/modules/schema.js +3 -0
  27. umap/static/umap/js/modules/slideshow.js +1 -1
  28. umap/static/umap/js/modules/sync/updaters.js +1 -6
  29. umap/static/umap/js/modules/tableeditor.js +13 -37
  30. umap/static/umap/js/modules/templates.js +7 -6
  31. umap/static/umap/js/modules/ui/panel.js +7 -0
  32. umap/static/umap/js/modules/umap.js +17 -6
  33. umap/static/umap/js/modules/utils.js +8 -7
  34. umap/static/umap/locale/am_ET.js +43 -6
  35. umap/static/umap/locale/am_ET.json +43 -6
  36. umap/static/umap/locale/ar.js +43 -6
  37. umap/static/umap/locale/ar.json +43 -6
  38. umap/static/umap/locale/ast.js +43 -6
  39. umap/static/umap/locale/ast.json +43 -6
  40. umap/static/umap/locale/bg.js +43 -6
  41. umap/static/umap/locale/bg.json +43 -6
  42. umap/static/umap/locale/br.js +30 -26
  43. umap/static/umap/locale/br.json +30 -26
  44. umap/static/umap/locale/ca.js +50 -13
  45. umap/static/umap/locale/ca.json +50 -13
  46. umap/static/umap/locale/cs_CZ.js +43 -6
  47. umap/static/umap/locale/cs_CZ.json +43 -6
  48. umap/static/umap/locale/da.js +10 -6
  49. umap/static/umap/locale/da.json +10 -6
  50. umap/static/umap/locale/de.js +10 -6
  51. umap/static/umap/locale/de.json +10 -6
  52. umap/static/umap/locale/el.js +20 -10
  53. umap/static/umap/locale/el.json +20 -10
  54. umap/static/umap/locale/en.js +10 -6
  55. umap/static/umap/locale/en.json +10 -6
  56. umap/static/umap/locale/en_US.json +43 -6
  57. umap/static/umap/locale/es.js +10 -6
  58. umap/static/umap/locale/es.json +10 -6
  59. umap/static/umap/locale/et.js +43 -6
  60. umap/static/umap/locale/et.json +43 -6
  61. umap/static/umap/locale/eu.js +43 -6
  62. umap/static/umap/locale/eu.json +43 -6
  63. umap/static/umap/locale/fa_IR.js +43 -6
  64. umap/static/umap/locale/fa_IR.json +43 -6
  65. umap/static/umap/locale/fi.js +43 -6
  66. umap/static/umap/locale/fi.json +43 -6
  67. umap/static/umap/locale/fr.js +10 -6
  68. umap/static/umap/locale/fr.json +10 -6
  69. umap/static/umap/locale/gl.js +43 -6
  70. umap/static/umap/locale/gl.json +43 -6
  71. umap/static/umap/locale/he.js +43 -6
  72. umap/static/umap/locale/he.json +43 -6
  73. umap/static/umap/locale/hr.js +43 -6
  74. umap/static/umap/locale/hr.json +43 -6
  75. umap/static/umap/locale/hu.js +34 -24
  76. umap/static/umap/locale/hu.json +34 -24
  77. umap/static/umap/locale/id.js +43 -6
  78. umap/static/umap/locale/id.json +43 -6
  79. umap/static/umap/locale/is.js +43 -6
  80. umap/static/umap/locale/is.json +43 -6
  81. umap/static/umap/locale/it.js +10 -6
  82. umap/static/umap/locale/it.json +10 -6
  83. umap/static/umap/locale/ja.js +43 -6
  84. umap/static/umap/locale/ja.json +43 -6
  85. umap/static/umap/locale/ko.js +43 -6
  86. umap/static/umap/locale/ko.json +43 -6
  87. umap/static/umap/locale/lt.js +43 -6
  88. umap/static/umap/locale/lt.json +43 -6
  89. umap/static/umap/locale/ms.js +43 -6
  90. umap/static/umap/locale/ms.json +43 -6
  91. umap/static/umap/locale/nl.js +10 -6
  92. umap/static/umap/locale/nl.json +10 -6
  93. umap/static/umap/locale/no.js +43 -6
  94. umap/static/umap/locale/no.json +43 -6
  95. umap/static/umap/locale/pl.js +43 -6
  96. umap/static/umap/locale/pl.json +43 -6
  97. umap/static/umap/locale/pl_PL.json +43 -6
  98. umap/static/umap/locale/pt.js +43 -6
  99. umap/static/umap/locale/pt.json +43 -6
  100. umap/static/umap/locale/pt_BR.js +53 -16
  101. umap/static/umap/locale/pt_BR.json +53 -16
  102. umap/static/umap/locale/pt_PT.js +43 -6
  103. umap/static/umap/locale/pt_PT.json +43 -6
  104. umap/static/umap/locale/ro.js +43 -6
  105. umap/static/umap/locale/ro.json +43 -6
  106. umap/static/umap/locale/ru.js +43 -6
  107. umap/static/umap/locale/ru.json +43 -6
  108. umap/static/umap/locale/sk_SK.js +43 -6
  109. umap/static/umap/locale/sk_SK.json +43 -6
  110. umap/static/umap/locale/sl.js +43 -6
  111. umap/static/umap/locale/sl.json +43 -6
  112. umap/static/umap/locale/sr.js +43 -6
  113. umap/static/umap/locale/sr.json +43 -6
  114. umap/static/umap/locale/sv.js +43 -6
  115. umap/static/umap/locale/sv.json +43 -6
  116. umap/static/umap/locale/th_TH.js +43 -6
  117. umap/static/umap/locale/th_TH.json +43 -6
  118. umap/static/umap/locale/tr.js +43 -6
  119. umap/static/umap/locale/tr.json +43 -6
  120. umap/static/umap/locale/uk_UA.js +43 -6
  121. umap/static/umap/locale/uk_UA.json +43 -6
  122. umap/static/umap/locale/vi.js +43 -6
  123. umap/static/umap/locale/vi.json +43 -6
  124. umap/static/umap/locale/vi_VN.json +43 -6
  125. umap/static/umap/locale/zh.js +43 -6
  126. umap/static/umap/locale/zh.json +43 -6
  127. umap/static/umap/locale/zh_CN.json +43 -6
  128. umap/static/umap/locale/zh_TW.Big5.json +43 -6
  129. umap/static/umap/locale/zh_TW.js +43 -6
  130. umap/static/umap/locale/zh_TW.json +43 -6
  131. umap/static/umap/map.css +239 -65
  132. umap/static/umap/vendors/betterknown/betterknown.mjs +287 -0
  133. umap/storage/fs.py +3 -2
  134. umap/templates/base.html +4 -1
  135. umap/tests/base.py +9 -1
  136. umap/tests/integration/test_basics.py +1 -1
  137. umap/tests/integration/test_conditional_rules.py +62 -20
  138. umap/tests/integration/test_edit_datalayer.py +1 -1
  139. umap/tests/integration/test_edit_marker.py +1 -1
  140. umap/tests/integration/test_export_map.py +10 -0
  141. umap/tests/integration/test_import.py +140 -0
  142. umap/tests/integration/test_optimistic_merge.py +72 -12
  143. umap/tests/integration/test_tableeditor.py +6 -3
  144. umap/utils.py +33 -0
  145. umap/views.py +16 -2
  146. umap_project-3.2.0.dist-info/METADATA +76 -0
  147. {umap_project-3.1.2.dist-info → umap_project-3.2.0.dist-info}/RECORD +150 -148
  148. umap_project-3.1.2.dist-info/METADATA +0 -68
  149. {umap_project-3.1.2.dist-info → umap_project-3.2.0.dist-info}/WHEEL +0 -0
  150. {umap_project-3.1.2.dist-info → umap_project-3.2.0.dist-info}/entry_points.txt +0 -0
  151. {umap_project-3.1.2.dist-info → umap_project-3.2.0.dist-info}/licenses/LICENSE +0 -0
umap/__init__.py CHANGED
@@ -1 +1 @@
1
- VERSION = "3.1.2"
1
+ VERSION = "3.2.0"
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2025-06-10 09:19+0000\n"
11
+ "POT-Creation-Date: 2025-07-10 14:12+0000\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -530,7 +530,7 @@ msgstr ""
530
530
  msgid "template"
531
531
  msgstr ""
532
532
 
533
- #: templates/umap/map_list.html:18 views.py:458
533
+ #: templates/umap/map_list.html:18 views.py:459
534
534
  msgid "by"
535
535
  msgstr ""
536
536
 
@@ -809,70 +809,74 @@ msgstr ""
809
809
  msgid "No template found."
810
810
  msgstr ""
811
811
 
812
- #: views.py:233
812
+ #: views.py:235
813
813
  msgid "Cannot delete a team with more than one member"
814
814
  msgstr ""
815
815
 
816
- #: views.py:237
816
+ #: views.py:239
817
817
  #, python-format
818
818
  msgid "Team “%(name)s” has been deleted"
819
819
  msgstr ""
820
820
 
821
- #: views.py:463
821
+ #: views.py:464
822
822
  msgid "View the map"
823
823
  msgstr ""
824
824
 
825
- #: views.py:864
825
+ #: views.py:865
826
826
  msgid "See full screen"
827
827
  msgstr ""
828
828
 
829
- #: views.py:1007
829
+ #: views.py:1008
830
830
  msgid "Map editors updated with success!"
831
831
  msgstr ""
832
832
 
833
- #: views.py:1043
833
+ #: views.py:1044
834
834
  #, python-format
835
835
  msgid "The uMap edit link for your map: %(map_name)s"
836
836
  msgstr ""
837
837
 
838
- #: views.py:1046
838
+ #: views.py:1047
839
839
  #, python-format
840
840
  msgid "Here is your secret edit link: %(link)s"
841
841
  msgstr ""
842
842
 
843
- #: views.py:1053
843
+ #: views.py:1054
844
844
  #, python-format
845
845
  msgid "Can't send email to %(email)s"
846
846
  msgstr ""
847
847
 
848
- #: views.py:1056
848
+ #: views.py:1057
849
849
  #, python-format
850
850
  msgid "Email sent to %(email)s"
851
851
  msgstr ""
852
852
 
853
- #: views.py:1067
853
+ #: views.py:1068
854
854
  msgid "Only its owner can delete the map."
855
855
  msgstr ""
856
856
 
857
- #: views.py:1073
857
+ #: views.py:1074
858
858
  msgid "Map successfully deleted."
859
859
  msgstr ""
860
860
 
861
- #: views.py:1099
861
+ #: views.py:1100
862
862
  #, python-format
863
863
  msgid ""
864
864
  "Your map has been cloned! If you want to edit this map from another "
865
865
  "computer, please use this link: %(anonymous_url)s"
866
866
  msgstr ""
867
867
 
868
- #: views.py:1104
868
+ #: views.py:1105
869
869
  msgid "Congratulations, your map has been cloned!"
870
870
  msgstr ""
871
871
 
872
- #: views.py:1358
872
+ #: views.py:1359
873
873
  msgid "Layer successfully deleted."
874
874
  msgstr ""
875
875
 
876
- #: views.py:1380
876
+ #: views.py:1381
877
877
  msgid "Permissions updated with success!"
878
878
  msgstr ""
879
+
880
+ #: views.py:1398
881
+ msgid "Generic"
882
+ msgstr ""
Binary file
@@ -24,7 +24,7 @@ msgid ""
24
24
  msgstr ""
25
25
  "Project-Id-Version: uMap\n"
26
26
  "Report-Msgid-Bugs-To: \n"
27
- "POT-Creation-Date: 2025-06-10 09:19+0000\n"
27
+ "POT-Creation-Date: 2025-07-10 14:12+0000\n"
28
28
  "PO-Revision-Date: 2013-11-22 14:00+0000\n"
29
29
  "Last-Translator: yohanboniface <yohanboniface@free.fr>, 2013-2014,2018-2019,2023-2025\n"
30
30
  "Language-Team: French (http://app.transifex.com/openstreetmap/umap/language/fr/)\n"
@@ -547,7 +547,7 @@ msgstr "Vous êtes maintenant identifié. Merci de patienter..."
547
547
  msgid "template"
548
548
  msgstr "modèle"
549
549
 
550
- #: templates/umap/map_list.html:18 views.py:458
550
+ #: templates/umap/map_list.html:18 views.py:459
551
551
  msgid "by"
552
552
  msgstr "par"
553
553
 
@@ -828,70 +828,74 @@ msgstr "Créer un modèle"
828
828
  msgid "No template found."
829
829
  msgstr "Aucun modèle trouvé."
830
830
 
831
- #: views.py:233
831
+ #: views.py:235
832
832
  msgid "Cannot delete a team with more than one member"
833
833
  msgstr "Impossible de supprimer une équipe ayant plus d'un membre"
834
834
 
835
- #: views.py:237
835
+ #: views.py:239
836
836
  #, python-format
837
837
  msgid "Team “%(name)s” has been deleted"
838
838
  msgstr "L'équipe «%(name)s» a été supprimée"
839
839
 
840
- #: views.py:463
840
+ #: views.py:464
841
841
  msgid "View the map"
842
842
  msgstr "Voir la carte"
843
843
 
844
- #: views.py:864
844
+ #: views.py:865
845
845
  msgid "See full screen"
846
846
  msgstr "Plein écran"
847
847
 
848
- #: views.py:1007
848
+ #: views.py:1008
849
849
  msgid "Map editors updated with success!"
850
850
  msgstr "Éditeurs de la carte mis à jour !"
851
851
 
852
- #: views.py:1043
852
+ #: views.py:1044
853
853
  #, python-format
854
854
  msgid "The uMap edit link for your map: %(map_name)s"
855
855
  msgstr "Le lien d'édition uMap pour votre carte : %(map_name)s"
856
856
 
857
- #: views.py:1046
857
+ #: views.py:1047
858
858
  #, python-format
859
859
  msgid "Here is your secret edit link: %(link)s"
860
860
  msgstr "Voici votre lien d'édition secret : %(link)s"
861
861
 
862
- #: views.py:1053
862
+ #: views.py:1054
863
863
  #, python-format
864
864
  msgid "Can't send email to %(email)s"
865
865
  msgstr "Impossible d'envoyer un courriel vers %(email)s"
866
866
 
867
- #: views.py:1056
867
+ #: views.py:1057
868
868
  #, python-format
869
869
  msgid "Email sent to %(email)s"
870
870
  msgstr "Courriel envoyé à %(email)s"
871
871
 
872
- #: views.py:1067
872
+ #: views.py:1068
873
873
  msgid "Only its owner can delete the map."
874
874
  msgstr "Seul le créateur de la carte peut la supprimer."
875
875
 
876
- #: views.py:1073
876
+ #: views.py:1074
877
877
  msgid "Map successfully deleted."
878
878
  msgstr "La carte a bien été supprimée."
879
879
 
880
- #: views.py:1099
880
+ #: views.py:1100
881
881
  #, python-format
882
882
  msgid ""
883
883
  "Your map has been cloned! If you want to edit this map from another "
884
884
  "computer, please use this link: %(anonymous_url)s"
885
885
  msgstr "Votre carte a été dupliquée ! Si vous souhaitez la modifier depuis un autre ordinateur, veuillez utiliser ce lien : %(anonymous_url)s"
886
886
 
887
- #: views.py:1104
887
+ #: views.py:1105
888
888
  msgid "Congratulations, your map has been cloned!"
889
889
  msgstr "Votre carte a été dupliquée !"
890
890
 
891
- #: views.py:1358
891
+ #: views.py:1359
892
892
  msgid "Layer successfully deleted."
893
893
  msgstr "Calque supprimé."
894
894
 
895
- #: views.py:1380
895
+ #: views.py:1381
896
896
  msgid "Permissions updated with success!"
897
897
  msgstr "Les permissions ont bien été modifiées !"
898
+
899
+ #: views.py:1398
900
+ msgid "Generic"
901
+ msgstr "Générique"
@@ -0,0 +1,29 @@
1
+ import shutil
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ from django.core.management.base import BaseCommand
6
+
7
+ from umap.models import Pictogram
8
+
9
+
10
+ class Command(BaseCommand):
11
+ help = "Export pictogram to some given folder."
12
+
13
+ def add_arguments(self, parser):
14
+ parser.add_argument("dest", help="Destination folder to export pictograms")
15
+
16
+ def handle(self, *args, **options):
17
+ dest = Path(options["dest"])
18
+ if not dest.exists():
19
+ sys.exit("Destination does not exist", dest)
20
+
21
+ for picto in Pictogram.objects.all():
22
+ parent = dest
23
+ if picto.category:
24
+ parent = parent / picto.category.replace("/", "-")
25
+ parent.mkdir(exist_ok=True)
26
+ path = parent / Path(picto.pictogram.name).name
27
+ shutil.copy2(picto.pictogram.path, path)
28
+ if options["verbosity"] > 1:
29
+ print("Copied", picto.pictogram.path, "to", path)
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  from django.conf import settings
2
4
  from django.core.files.storage import FileSystemStorage
3
5
  from django.core.management.base import BaseCommand
@@ -25,7 +27,9 @@ class Command(BaseCommand):
25
27
  fs_storage = FileSystemStorage()
26
28
  for picto in Pictogram.objects.all():
27
29
  fs_path = str(picto.pictogram)
28
- picto.pictogram.save(picto.pictogram.name, fs_storage.open(fs_path))
30
+ picto.pictogram.save(
31
+ Path(picto.pictogram.name).name, fs_storage.open(fs_path)
32
+ )
29
33
  if options["verbosity"] > 1:
30
34
  print("Migrated:", fs_path)
31
35
  else:
@@ -49,14 +49,16 @@ class Command(BaseCommand):
49
49
  layer_id = layer.uuid
50
50
  layer_name = layer.name
51
51
  last_modified = layer.modified_at.date()
52
- deleted = 0
52
+ deleted = layer.geojson.storage.purge_old_versions(
53
+ layer, keep=1, dry_run=options["dry_run"]
54
+ )
55
+ total_deleted += deleted
53
56
  if not options["dry_run"]:
54
- deleted = layer.geojson.storage.purge_old_versions(layer, keep=1)
55
57
  layer.geojson.storage.purge_gzip(layer)
56
- total_deleted += deleted
57
- print(
58
- f"Deleted {deleted} old versions of `{layer_name}` ({layer_id}), unmodified since {last_modified}"
59
- )
58
+ if (deleted and options["verbosity"] > 0) or options["verbosity"] > 1:
59
+ print(
60
+ f"Deleted {deleted} old versions of `{layer_name}` ({layer_id}), unmodified since {last_modified}"
61
+ )
60
62
  if not options["dry_run"]:
61
63
  print(f"Successfully deleted {total_deleted} geojson files.")
62
64
  else:
umap/settings/__init__.py CHANGED
@@ -1,7 +1,9 @@
1
1
  import os
2
2
  import sys
3
3
  import types
4
+ from pathlib import Path
4
5
 
6
+ from django.core.exceptions import ImproperlyConfigured
5
7
  from django.utils.termcolors import colorize
6
8
 
7
9
  from .base import * # NOQA, default values
@@ -44,4 +46,23 @@ if path:
44
46
  elif key == "UMAP_FEEDBACK_LINK":
45
47
  globals()["UMAP_HELP_URL"] = value
46
48
  else:
49
+ if key == "UMAP_PICTOGRAMS_COLLECTIONS" and value:
50
+ for name, options in value.items():
51
+ # relative path will be looked relatively to the STATIC_ROOT
52
+ path = Path(options["path"])
53
+ if not path.is_absolute():
54
+ continue
55
+ if not path.exists():
56
+ msg = (
57
+ f"UMAP_PICTOGRAMS_COLLECTIONS defines path {path} but it does "
58
+ "not exist"
59
+ )
60
+ raise ImproperlyConfigured(msg)
61
+ if not (path / "pictograms").exists():
62
+ msg = (
63
+ f"UMAP_PICTOGRAMS_COLLECTIONS defines path {path} but it does "
64
+ "not have a 'pictograms' root folder"
65
+ )
66
+ raise ImproperlyConfigured(msg)
67
+ globals()["STATICFILES_DIRS"].append(path)
47
68
  globals()[key] = value
umap/settings/base.py CHANGED
@@ -341,6 +341,7 @@ LOCALE_PATHS = [os.path.join(PROJECT_DIR, "locale")]
341
341
  LEAFLET_LONGITUDE = env.int("LEAFLET_LONGITUDE", default=2)
342
342
  LEAFLET_LATITUDE = env.int("LEAFLET_LATITUDE", default=51)
343
343
  LEAFLET_ZOOM = env.int("LEAFLET_ZOOM", default=6)
344
+ UMAP_PICTOGRAMS_COLLECTIONS = {}
344
345
 
345
346
 
346
347
  # =============================================================================
@@ -113,8 +113,9 @@ h2.section {
113
113
  text-align: center;
114
114
  }
115
115
  h2.tabs {
116
- display: flex;
117
- justify-content: space-around;
116
+ display: inline-flex;
117
+ justify-content: left;
118
+ gap: 22px;
118
119
  text-transform: uppercase;
119
120
  color: var(--color-darkBlue);
120
121
  text-align: start;
@@ -136,7 +137,11 @@ h2.tabs a:not(.selected) {
136
137
  }
137
138
  h2.tabs a:hover {
138
139
  text-decoration: underline;
140
+ text-decoration-thickness: 3px;
141
+ text-decoration-skip-ink: none;
142
+ text-underline-offset: 7px;
139
143
  }
144
+
140
145
  .showcase-map .map_fragment {
141
146
  height: 400px;
142
147
  }
@@ -7,229 +7,303 @@
7
7
  border: none;
8
8
  background-color: initial;
9
9
  }
10
+
10
11
  .icon-16 {
11
12
  height: 24px;
12
13
  line-height: 24px;
13
14
  width: 24px;
14
15
  --tile: -24px;
15
16
  }
17
+
16
18
  .icon-24 {
17
19
  background-image: url('../img/24.svg');
18
20
  --tile: -36px;
19
21
  height: 36px;
20
22
  width: 36px;
21
23
  }
22
- .icon + span {
24
+
25
+ .icon+span {
23
26
  margin-inline-start: 5px;
24
27
  margin-inline-end: 5px;
25
28
  }
29
+
26
30
  html[dir="rtl"] .icon {
27
- transform: scaleX(-1);
31
+ transform: scaleX(-1);
28
32
  }
33
+
29
34
  .icon-block {
30
35
  display: block;
31
36
  float: inline-start;
32
37
  margin-inline-end: 10px;
33
38
  }
34
- .icon-block + span {
39
+
40
+ .icon-block+span {
35
41
  margin-inline-start: 0;
36
42
  }
43
+
37
44
  .icon-16.icon-white,
38
45
  .dark .icon-16 {
39
46
  background-image: url('../img/16-white.svg');
40
47
  }
48
+
41
49
  .icon-24.icon-white,
42
50
  .dark .icon-24 {
43
51
  background-image: url('../img/24-white.svg');
44
52
  }
53
+
45
54
  .icon-16.icon-black,
46
55
  .icon-16 {
47
56
  background-image: url('../img/16.svg');
48
57
  }
58
+
49
59
  .icon-24.icon-black,
50
60
  .icon-24 {
51
61
  background-image: url('../img/24.svg');
52
62
  }
63
+
53
64
  .icon-add {
54
65
  background-position: var(--tile) var(--tile);
55
66
  }
67
+
56
68
  .icon-back {
57
69
  background-position: calc(var(--tile) * 5) calc(var(--tile) * 6);
58
70
  }
71
+
59
72
  .icon-backup {
60
73
  background-position: var(--tile) calc(var(--tile) * 6);
61
74
  }
75
+
62
76
  .icon-caption {
63
77
  background-position: calc(var(--tile) * 4) var(--tile);
64
78
  }
79
+
65
80
  .icon-center {
66
81
  background-position: calc(var(--tile) * 4) calc(var(--tile) * 2);
67
82
  }
83
+
68
84
  .icon-clone {
69
85
  background-position: calc(var(--tile) * 7) calc(var(--tile) * 2);
70
86
  }
87
+
71
88
  .icon-close {
72
89
  background-position: var(--tile) 0px;
73
90
  }
91
+
74
92
  .icon-continue-line {
75
93
  background-position: calc(var(--tile) * 4) 0;
76
94
  }
95
+
77
96
  .icon-copy {
78
97
  background-position: calc(var(--tile) * 4) calc(var(--tile) * 7);
79
98
  }
99
+
80
100
  .icon-delete {
81
101
  background-position: calc(var(--tile) * 5) calc(var(--tile) * 2);
82
102
  }
103
+
83
104
  .icon-delete-shape {
84
105
  background-position: calc(var(--tile) * 4) calc(var(--tile) * 3);
85
106
  }
107
+
86
108
  .icon-delete-vertex {
87
109
  background-position: calc(var(--tile) * 5) calc(var(--tile) * 4);
88
110
  }
111
+
89
112
  .readonly .icon-delete,
90
113
  .off .icon-delete {
91
114
  background-position: calc(var(--tile) * 5) calc(var(--tile) * 5);
92
115
  }
116
+
93
117
  .icon-download {
94
118
  background-position: 0 calc(var(--tile) * 6);
95
119
  }
120
+
96
121
  .icon-drag {
97
122
  background-position: calc(var(--tile) * 3) calc(var(--tile) * 3);
98
123
  cursor: move;
99
124
  float: inline-end;
125
+ visibility: hidden;
100
126
  }
127
+
128
+ .orderable:hover .icon-drag {
129
+ visibility: visible;
130
+ }
131
+
101
132
  .icon-empty {
102
133
  background-position: calc(var(--tile) * 7) calc(var(--tile) * 3);
103
134
  }
135
+
104
136
  .icon-eye {
105
137
  background-position: calc(var(--tile) * 2) var(--tile);
106
138
  }
139
+
107
140
  .off .icon-eye {
108
141
  background-position: calc(var(--tile) * 3) var(--tile);
109
142
  }
143
+
110
144
  .icon-edit {
111
145
  background-position: calc(var(--tile) * 2) calc(var(--tile) * 2);
112
146
  }
147
+
113
148
  .off .icon-edit {
114
149
  background-position: calc(var(--tile) * 2) calc(var(--tile) * 3);
115
150
  }
151
+
116
152
  .icon-external-link {
117
153
  background-position: calc(var(--tile) * 6) calc(var(--tile) * 7);
118
154
  }
155
+
119
156
  .icon-extract-shape {
120
157
  background-position: calc(var(--tile) * 5) 0;
121
158
  }
159
+
122
160
  .icon-filters {
123
161
  background-position: 0px var(--tile);
124
162
  }
163
+
125
164
  .icon-forward {
126
165
  background-position: calc(var(--tile) * 6) calc(var(--tile) * 6);
127
166
  }
167
+
128
168
  .icon-help {
129
169
  background-position: 0 0;
130
170
  }
171
+
131
172
  .icon-hole {
132
173
  background-position: calc(var(--tile) * 3) calc(var(--tile) * 4);
133
174
  }
175
+
134
176
  .icon-key {
135
177
  background-position: calc(var(--tile) * 6) calc(var(--tile) * 5);
136
178
  }
179
+
137
180
  .icon-layers {
138
181
  background-position: calc(var(--tile) * 4) calc(var(--tile) * 5);
139
182
  }
183
+
140
184
  .icon-list {
141
185
  background-position: var(--tile) calc(var(--tile) * 4);
142
186
  }
187
+
143
188
  .icon-magic {
144
189
  background-position: calc(var(--tile) * 7) 0;
145
190
  }
191
+
146
192
  .icon-marker {
147
193
  background-position: calc(var(--tile) * 7) var(--tile);
148
194
  }
195
+
149
196
  .icon-marker-plus {
150
197
  background-position: calc(var(--tile) * 8) var(--tile);
151
198
  }
199
+
152
200
  .icon-multipolygon {
153
201
  background-position: calc(var(--tile) * 7) calc(var(--tile) * 5);
154
202
  }
203
+
155
204
  .icon-multiline {
156
205
  background-position: calc(var(--tile) * 7) calc(var(--tile) * 7);
157
206
  }
207
+
158
208
  .icon-peers {
159
209
  background-position: calc(var(--tile) * 3) calc(var(--tile) * 2);
160
210
  }
211
+
161
212
  .icon-polygon {
162
213
  background-position: calc(var(--tile) * 7) calc(var(--tile) * 4);
163
214
  }
215
+
164
216
  .icon-polygon-plus {
165
217
  background-position: calc(var(--tile) * 8) calc(var(--tile) * 4);
166
218
  }
219
+
167
220
  .icon-polyline {
168
221
  background-position: calc(var(--tile) * 7) calc(var(--tile) * 6);
169
222
  }
223
+
170
224
  .icon-profile {
171
225
  background-position: 0 calc(var(--tile) * 4);
172
226
  }
227
+
173
228
  .icon-redo {
174
229
  background-position: calc(var(--tile) * 3) calc(var(--tile) * 7);
175
230
  }
231
+
176
232
  .icon-resize {
177
233
  background-position: calc(var(--tile) * 3) calc(var(--tile) * 6);
178
234
  }
235
+
179
236
  .icon-undo,
180
237
  .icon-restore {
181
238
  background-position: calc(var(--tile) * 2) calc(var(--tile) * 7);
182
239
  }
240
+
183
241
  .expanded .icon-resize {
184
242
  background-position: calc(var(--tile) * 2) calc(var(--tile) * 6);
185
243
  }
244
+
186
245
  .icon-save {
187
246
  background-position: calc(var(--tile) * 6) var(--tile);
188
247
  }
248
+
189
249
  /* FIXME move to a 16-disabled.svg sprite ? */
190
250
  .icon-save-disabled {
191
251
  background-position: calc(var(--tile) * 6) 0;
192
252
  }
253
+
193
254
  .icon-search {
194
255
  background-position: var(--tile) calc(var(--tile) * 5);
195
256
  }
257
+
196
258
  .icon-settings {
197
259
  background-position: var(--tile) calc(var(--tile) * 4);
198
260
  }
261
+
199
262
  .icon-share {
200
263
  background-position: 0px calc(var(--tile) * 5);
201
264
  }
265
+
202
266
  .icon-split-line {
203
267
  background-position: calc(var(--tile) * 5) var(--tile);
204
268
  }
269
+
205
270
  .icon-star {
206
271
  background-position: var(--tile) calc(var(--tile) * 7);
207
272
  }
273
+
208
274
  .icon-starred {
209
275
  background-position: 0 calc(var(--tile) * 7);
210
276
  }
277
+
211
278
  .icon-table {
212
279
  background-position: calc(var(--tile) * 2) 0px;
213
280
  }
281
+
214
282
  .readonly .icon-table,
215
283
  .off .icon-table {
216
284
  background-position: calc(var(--tile) * 3) 0px;
217
285
  }
286
+
218
287
  .remotelayer .icon-table {
219
288
  display: none !important;
220
289
  }
290
+
221
291
  .icon-template {
222
292
  background-position: calc(var(--tile) * 5) calc(var(--tile) * 7);
223
293
  }
294
+
224
295
  .icon-tilelayer {
225
296
  background-position: calc(var(--tile) * 4) calc(var(--tile) * 6);
226
297
  }
298
+
227
299
  .icon-upload {
228
300
  background-position: calc(var(--tile) * 6) calc(var(--tile) * 4);
229
301
  }
302
+
230
303
  .icon-zoom {
231
304
  background-position: 0px calc(var(--tile) * 2);
232
305
  }
306
+
233
307
  .off .icon-zoom {
234
308
  background-position: var(--tile) calc(var(--tile) * 2);
235
309
  }