umap-project 2.3.1__py3-none-any.whl → 2.4.0b0__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.
- umap/.DS_Store +0 -0
- umap/__init__.py +1 -1
- umap/locale/en/LC_MESSAGES/django.po +81 -31
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +109 -59
- umap/management/commands/run_websocket_server.py +23 -0
- umap/models.py +6 -1
- umap/settings/base.py +11 -3
- umap/static/.DS_Store +0 -0
- umap/static/umap/.DS_Store +0 -0
- umap/static/umap/base.css +53 -162
- umap/static/umap/content.css +3 -2
- umap/static/umap/css/dialog.css +18 -0
- umap/static/umap/css/icon.css +8 -0
- umap/static/umap/css/importers.css +44 -0
- umap/static/umap/css/panel.css +19 -57
- umap/static/umap/css/tooltip.css +59 -0
- umap/static/umap/css/window.css +35 -0
- umap/static/umap/favicons/.DS_Store +0 -0
- umap/static/umap/fonts/.DS_Store +0 -0
- umap/static/umap/img/.DS_Store +0 -0
- umap/static/umap/img/alert-icon-error.svg +8 -0
- umap/static/umap/img/alert-icon-info.svg +4 -0
- umap/static/umap/img/alert-icon-success.svg +3 -0
- umap/static/umap/img/icon-external-link.svg +3 -0
- umap/static/umap/img/importers/communesfr.svg +5 -0
- umap/static/umap/img/importers/datasets.svg +13 -0
- umap/static/umap/img/importers/geodatamine.svg +10 -0
- umap/static/umap/img/importers/overpass.svg +7 -0
- umap/static/umap/img/importers/random.svg +18 -0
- umap/static/umap/img/importers/random1.svg +4 -0
- umap/static/umap/img/importers/random2.svg +4 -0
- umap/static/umap/img/source/.DS_Store +0 -0
- umap/static/umap/js/components/alerts/alert.css +160 -0
- umap/static/umap/js/components/alerts/alert.js +169 -0
- umap/static/umap/js/components/base.js +54 -0
- umap/static/umap/js/modules/autocomplete.js +347 -0
- umap/static/umap/js/modules/browser.js +1 -1
- umap/static/umap/js/modules/caption.js +4 -3
- umap/static/umap/js/modules/global.js +36 -12
- umap/static/umap/js/modules/help.js +255 -0
- umap/static/umap/js/modules/importer.js +280 -0
- umap/static/umap/js/modules/importers/communesfr.js +44 -0
- umap/static/umap/js/modules/importers/datasets.js +41 -0
- umap/static/umap/js/modules/importers/geodatamine.js +95 -0
- umap/static/umap/js/modules/importers/overpass.js +84 -0
- umap/static/umap/js/modules/request.js +12 -14
- umap/static/umap/js/modules/rules.js +241 -0
- umap/static/umap/js/modules/schema.js +63 -14
- umap/static/umap/js/modules/sync/engine.js +93 -0
- umap/static/umap/js/modules/sync/updaters.js +109 -0
- umap/static/umap/js/modules/sync/websocket.js +25 -0
- umap/static/umap/js/modules/ui/dialog.js +52 -0
- umap/static/umap/js/modules/{panel.js → ui/panel.js} +25 -14
- umap/static/umap/js/modules/ui/tooltip.js +116 -0
- umap/static/umap/js/modules/utils.js +25 -18
- umap/static/umap/js/umap.controls.js +13 -14
- umap/static/umap/js/umap.core.js +1 -324
- umap/static/umap/js/umap.features.js +67 -27
- umap/static/umap/js/umap.forms.js +9 -13
- umap/static/umap/js/umap.js +220 -180
- umap/static/umap/js/umap.layer.js +142 -74
- umap/static/umap/js/umap.permissions.js +5 -9
- umap/static/umap/js/umap.tableeditor.js +8 -8
- umap/static/umap/locale/am_ET.js +51 -16
- umap/static/umap/locale/am_ET.json +51 -16
- umap/static/umap/locale/ar.js +51 -16
- umap/static/umap/locale/ar.json +51 -16
- umap/static/umap/locale/ast.js +51 -16
- umap/static/umap/locale/ast.json +51 -16
- umap/static/umap/locale/bg.js +51 -16
- umap/static/umap/locale/bg.json +51 -16
- umap/static/umap/locale/br.js +55 -20
- umap/static/umap/locale/br.json +55 -20
- umap/static/umap/locale/ca.js +51 -16
- umap/static/umap/locale/ca.json +51 -16
- umap/static/umap/locale/cs_CZ.js +93 -58
- umap/static/umap/locale/cs_CZ.json +93 -58
- umap/static/umap/locale/da.js +51 -16
- umap/static/umap/locale/da.json +51 -16
- umap/static/umap/locale/de.js +56 -21
- umap/static/umap/locale/de.json +56 -21
- umap/static/umap/locale/el.js +51 -16
- umap/static/umap/locale/el.json +51 -16
- umap/static/umap/locale/en.js +51 -16
- umap/static/umap/locale/en.json +51 -16
- umap/static/umap/locale/en_US.json +51 -16
- umap/static/umap/locale/es.js +51 -16
- umap/static/umap/locale/es.json +51 -16
- umap/static/umap/locale/et.js +51 -16
- umap/static/umap/locale/et.json +51 -16
- umap/static/umap/locale/eu.js +51 -16
- umap/static/umap/locale/eu.json +51 -16
- umap/static/umap/locale/fa_IR.js +51 -16
- umap/static/umap/locale/fa_IR.json +51 -16
- umap/static/umap/locale/fi.js +51 -16
- umap/static/umap/locale/fi.json +51 -16
- umap/static/umap/locale/fr.js +52 -17
- umap/static/umap/locale/fr.json +52 -17
- umap/static/umap/locale/gl.js +51 -16
- umap/static/umap/locale/gl.json +51 -16
- umap/static/umap/locale/he.js +51 -16
- umap/static/umap/locale/he.json +51 -16
- umap/static/umap/locale/hr.js +51 -16
- umap/static/umap/locale/hr.json +51 -16
- umap/static/umap/locale/hu.js +51 -16
- umap/static/umap/locale/hu.json +51 -16
- umap/static/umap/locale/id.js +51 -16
- umap/static/umap/locale/id.json +51 -16
- umap/static/umap/locale/is.js +51 -16
- umap/static/umap/locale/is.json +51 -16
- umap/static/umap/locale/it.js +51 -16
- umap/static/umap/locale/it.json +51 -16
- umap/static/umap/locale/ja.js +51 -16
- umap/static/umap/locale/ja.json +51 -16
- umap/static/umap/locale/ko.js +51 -16
- umap/static/umap/locale/ko.json +51 -16
- umap/static/umap/locale/lt.js +51 -16
- umap/static/umap/locale/lt.json +51 -16
- umap/static/umap/locale/ms.js +51 -16
- umap/static/umap/locale/ms.json +51 -16
- umap/static/umap/locale/nl.js +51 -16
- umap/static/umap/locale/nl.json +51 -16
- umap/static/umap/locale/no.js +51 -16
- umap/static/umap/locale/no.json +51 -16
- umap/static/umap/locale/pl.js +93 -58
- umap/static/umap/locale/pl.json +93 -58
- umap/static/umap/locale/pl_PL.json +51 -16
- umap/static/umap/locale/pt.js +215 -180
- umap/static/umap/locale/pt.json +215 -180
- umap/static/umap/locale/pt_BR.js +51 -16
- umap/static/umap/locale/pt_BR.json +51 -16
- umap/static/umap/locale/pt_PT.js +51 -16
- umap/static/umap/locale/pt_PT.json +51 -16
- umap/static/umap/locale/ro.js +51 -16
- umap/static/umap/locale/ro.json +51 -16
- umap/static/umap/locale/ru.js +51 -16
- umap/static/umap/locale/ru.json +51 -16
- umap/static/umap/locale/si.js +51 -16
- umap/static/umap/locale/si.json +51 -16
- umap/static/umap/locale/sk_SK.js +51 -16
- umap/static/umap/locale/sk_SK.json +51 -16
- umap/static/umap/locale/sl.js +51 -16
- umap/static/umap/locale/sl.json +51 -16
- umap/static/umap/locale/sr.js +51 -16
- umap/static/umap/locale/sr.json +51 -16
- umap/static/umap/locale/sv.js +51 -16
- umap/static/umap/locale/sv.json +51 -16
- umap/static/umap/locale/th_TH.js +51 -16
- umap/static/umap/locale/th_TH.json +51 -16
- umap/static/umap/locale/tr.js +51 -16
- umap/static/umap/locale/tr.json +51 -16
- umap/static/umap/locale/uk_UA.js +51 -16
- umap/static/umap/locale/uk_UA.json +51 -16
- umap/static/umap/locale/vi.js +51 -16
- umap/static/umap/locale/vi.json +51 -16
- umap/static/umap/locale/vi_VN.json +51 -16
- umap/static/umap/locale/zh.js +51 -16
- umap/static/umap/locale/zh.json +51 -16
- umap/static/umap/locale/zh_CN.json +51 -16
- umap/static/umap/locale/zh_TW.Big5.json +51 -16
- umap/static/umap/locale/zh_TW.js +51 -16
- umap/static/umap/locale/zh_TW.json +51 -16
- umap/static/umap/map.css +27 -41
- umap/static/umap/unittests/sync.js +105 -0
- umap/static/umap/unittests/utils.js +76 -34
- umap/static/umap/vars.css +18 -1
- umap/static/umap/vendors/dompurify/purify.es.js +5 -59
- umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
- umap/templates/umap/components/alerts/alert.html +89 -0
- umap/templates/umap/content.html +4 -3
- umap/templates/umap/css.html +4 -0
- umap/templates/umap/home.html +3 -0
- umap/templates/umap/js.html +0 -3
- umap/templates/umap/map_init.html +2 -8
- umap/templates/umap/messages.html +9 -11
- umap/templates/umap/search.html +3 -0
- umap/tests/.DS_Store +0 -0
- umap/tests/base.py +2 -0
- umap/tests/integration/.DS_Store +0 -0
- umap/tests/integration/conftest.py +30 -0
- umap/tests/integration/test_anonymous_owned_map.py +8 -13
- umap/tests/integration/test_browser.py +1 -1
- umap/tests/integration/test_conditional_rules.py +201 -0
- umap/tests/integration/test_dashboard.py +1 -1
- umap/tests/integration/test_datalayer.py +2 -3
- umap/tests/integration/test_edit_datalayer.py +4 -4
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_facets_browser.py +3 -3
- umap/tests/integration/test_import.py +138 -49
- umap/tests/integration/test_map.py +2 -2
- umap/tests/integration/{test_collaborative_editing.py → test_optimistic_merge.py} +7 -7
- umap/tests/integration/test_owned_map.py +1 -1
- umap/tests/integration/test_picto.py +2 -2
- umap/tests/integration/test_statics.py +1 -1
- umap/tests/integration/test_websocket_sync.py +283 -0
- umap/tests/settings.py +5 -0
- umap/tests/test_datalayer_views.py +0 -1
- umap/tests/test_views.py +53 -0
- umap/urls.py +5 -0
- umap/views.py +40 -11
- umap/websocket_server.py +92 -0
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/METADATA +11 -9
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/RECORD +207 -164
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/WHEEL +1 -1
- umap/static/umap/js/umap.autocomplete.js +0 -341
- umap/static/umap/js/umap.importer.js +0 -187
- umap/static/umap/js/umap.ui.js +0 -190
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -48,16 +48,12 @@
|
|
|
48
48
|
"by": "由",
|
|
49
49
|
"Cache proxied request": "快取代理請求",
|
|
50
50
|
"Cancel edits": "取消編輯",
|
|
51
|
-
"Cancel": "取消",
|
|
52
51
|
"Caption": "標題",
|
|
53
52
|
"Center map on your location": "將您的位置設為地圖中心",
|
|
54
53
|
"Change map background": "更改地圖背景",
|
|
55
54
|
"Change tilelayers": "改變地圖磚圖層",
|
|
56
55
|
"Change": "變動",
|
|
57
|
-
"Choose a preset": "選擇一種預設值",
|
|
58
56
|
"Choose the data format": "選擇資料格式",
|
|
59
|
-
"Choose the format of the data to import": "選擇匯入的資料格式",
|
|
60
|
-
"Choose the layer to import in": "選擇匯入圖層",
|
|
61
57
|
"Choropleth breakpoints": "等時線圖點",
|
|
62
58
|
"Choropleth classes": "等時線圖類型",
|
|
63
59
|
"Choropleth color palette": "等時線圖色彩盤",
|
|
@@ -87,7 +83,6 @@
|
|
|
87
83
|
"Congratulations, your map has been created!": "恭喜您的地圖已經新增完成",
|
|
88
84
|
"Continue line": "連續線段",
|
|
89
85
|
"Coordinates": "座標",
|
|
90
|
-
"Copy link": "複製連結",
|
|
91
86
|
"copy": "複製",
|
|
92
87
|
"Credits": "工作人員名單",
|
|
93
88
|
"Current map view": "目前地圖檢視",
|
|
@@ -152,7 +147,6 @@
|
|
|
152
147
|
"Edit the title of the map": "編輯地圖標題",
|
|
153
148
|
"Edit this feature": "編輯此圖徵",
|
|
154
149
|
"Edit": "編輯",
|
|
155
|
-
"Email": "電子郵件",
|
|
156
150
|
"Embed and link options": "嵌入與連結選項",
|
|
157
151
|
"Embed the map": "嵌入地圖",
|
|
158
152
|
"Emoji & Character": "表情符號和字元",
|
|
@@ -200,7 +194,6 @@
|
|
|
200
194
|
"Image: {{http://image.url.com}}": "圖像: {{http://image.url.com}}",
|
|
201
195
|
"Import data": "匯入資料",
|
|
202
196
|
"Import in a new layer": "匯入至新圖層",
|
|
203
|
-
"Import": "匯入",
|
|
204
197
|
"Imports all umap data, including layers and settings.": "匯入所有 umap 資料,包含圖層與設定。",
|
|
205
198
|
"Include full screen link?": "是否包含全螢幕的連結?",
|
|
206
199
|
"Inherit": "繼承",
|
|
@@ -311,7 +304,6 @@
|
|
|
311
304
|
"Rename this property on all the features": "在所有特徵中重新命名該物件",
|
|
312
305
|
"Replace layer content": "取代圖層內容",
|
|
313
306
|
"Restore this version": "回復此版本",
|
|
314
|
-
"Save anyway": "通通都儲存吧!",
|
|
315
307
|
"Save current edits": "儲存近期的變更",
|
|
316
308
|
"Save map": "儲存地圖",
|
|
317
309
|
"Save this center and zoom": "保存地圖中心點位置與縮放大小",
|
|
@@ -320,12 +312,9 @@
|
|
|
320
312
|
"Saved center and zoom": "儲存地圖中心點位置與縮放大小",
|
|
321
313
|
"Search location": "搜尋地點",
|
|
322
314
|
"Search": "搜尋",
|
|
323
|
-
"Secret edit link copied to clipboard!": "複製私密編輯連結到剪貼簿!",
|
|
324
315
|
"Secret edit link:": "祕密編輯連結:",
|
|
325
|
-
"See layers": "See layers",
|
|
326
316
|
"See full screen": "觀看全螢幕",
|
|
327
317
|
"See on OpenStreetMap": "在開放街圖檢視",
|
|
328
|
-
"Send me the link": "寄送連結給我",
|
|
329
318
|
"Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "設定為假時,在幻燈片時、資料檢視器和彈出式導航中可將此圖層隱藏...",
|
|
330
319
|
"settings": "設定",
|
|
331
320
|
"Shape properties": "形狀屬性",
|
|
@@ -398,9 +387,7 @@
|
|
|
398
387
|
"Will be displayed in the bottom right corner of the map": "將會顯示在地圖的右下角",
|
|
399
388
|
"Will be permanently visible in the bottom left corner of the map": "Will be permanently visible in the bottom left corner of the map",
|
|
400
389
|
"Will be visible in the caption of the map": "標題將出現在地圖上",
|
|
401
|
-
"Woops! Someone else seems to have edited the data. You can save anyway, but this will erase the changes made by others.": "糟糕,好像有人正在進行編輯,您仍可儲存資料,但您做的變更將被他人修改取代。",
|
|
402
390
|
"yes": "是",
|
|
403
|
-
"Your map has been created! As you are not logged in, here is your secret link to edit the map, please keep it safe:": "已經新增你的地圖!由於你並未登入,這是你的編輯地圖的祕密連結,請妥善保管:",
|
|
404
391
|
"Zoom in": "放大",
|
|
405
392
|
"Zoom level for automatic zooms": "自動縮放的比例大小",
|
|
406
393
|
"Zoom out": "縮小",
|
|
@@ -444,7 +431,55 @@
|
|
|
444
431
|
"Filter data": "Filter data",
|
|
445
432
|
"Search map features…": "Search map features…",
|
|
446
433
|
"Reset all": "Reset all",
|
|
447
|
-
"
|
|
448
|
-
"
|
|
449
|
-
"
|
|
434
|
+
"Open browser": "Open browser",
|
|
435
|
+
"Open caption": "Open caption",
|
|
436
|
+
"Your map has been created with an anonymous account!": "Your map has been created with an anonymous account!",
|
|
437
|
+
"Real-time collaboration": "Real-time collaboration",
|
|
438
|
+
"Cannot parse data": "Cannot parse data",
|
|
439
|
+
"Start typing...": "Start typing...",
|
|
440
|
+
"No result": "No result",
|
|
441
|
+
"Data browser": "Data browser",
|
|
442
|
+
"When providing an URL, uMap can copy the remote data in a layer, or add this URL as remote source of the layer. In that case, data will always be fetched from that URL, and thus be up to date, but it will not be possible to edit it inside uMap.": "When providing an URL, uMap can copy the remote data in a layer, or add this URL as remote source of the layer. In that case, data will always be fetched from that URL, and thus be up to date, but it will not be possible to edit it inside uMap.",
|
|
443
|
+
"Overpass supported expressions": "Overpass supported expressions",
|
|
444
|
+
"key (eg. building)": "key (eg. building)",
|
|
445
|
+
"!key (eg. !name)": "!key (eg. !name)",
|
|
446
|
+
"key=value (eg. building=yes)": "key=value (eg. building=yes)",
|
|
447
|
+
"key!=value (eg. building!=yes)": "key!=value (eg. building!=yes)",
|
|
448
|
+
"key~value (eg. name~Grisy)": "key~value (eg. name~Grisy)",
|
|
449
|
+
"key=\"value|value2\" (eg. name=\"Paris|Berlin\")": "key=\"value|value2\" (eg. name=\"Paris|Berlin\")",
|
|
450
|
+
"More info about Overpass syntax": "More info about Overpass syntax",
|
|
451
|
+
"For more complex needs, see": "For more complex needs, see",
|
|
452
|
+
"Choose data": "Choose data",
|
|
453
|
+
"Import helpers:": "Import helpers:",
|
|
454
|
+
"Choose the format": "Choose the format",
|
|
455
|
+
"Choose the layer": "Choose the layer",
|
|
456
|
+
"Layer name": "Layer name",
|
|
457
|
+
"Choose import mode": "Choose import mode",
|
|
458
|
+
"Copy into the layer": "Copy into the layer",
|
|
459
|
+
"Link to the layer as remote data": "Link to the layer as remote data",
|
|
460
|
+
"Condition": "Condition",
|
|
461
|
+
"key=value or key!=value": "key=value or key!=value",
|
|
462
|
+
"Are you sure you want to delete this rule?": "Are you sure you want to delete this rule?",
|
|
463
|
+
"empty rule": "empty rule",
|
|
464
|
+
"Conditional style rules": "Conditional style rules",
|
|
465
|
+
"Add rule": "Add rule",
|
|
466
|
+
"Browser: data": "Browser: data",
|
|
467
|
+
"Browser: layers": "Browser: layers",
|
|
468
|
+
"Browser: filters": "Browser: filters",
|
|
469
|
+
"Enable real-time collaboration": "Enable real-time collaboration",
|
|
470
|
+
"✅ Copied!": "✅ Copied!",
|
|
471
|
+
"Choose a dataset": "Choose a dataset",
|
|
472
|
+
"Choose this dataset": "Choose this dataset",
|
|
473
|
+
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
|
|
474
|
+
"Choose a theme": "Choose a theme",
|
|
475
|
+
"Symplify all geometries to points": "Symplify all geometries to points",
|
|
476
|
+
"Choose this data": "Choose this data",
|
|
477
|
+
"Search admin boundary": "Search admin boundary",
|
|
478
|
+
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
|
|
479
|
+
"Expression": "Expression",
|
|
480
|
+
"Geometry mode": "Geometry mode",
|
|
481
|
+
"Only geometry centers": "Only geometry centers",
|
|
482
|
+
"Search area": "Search area",
|
|
483
|
+
"Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view",
|
|
484
|
+
"Please define an expression for the query first": "Please define an expression for the query first"
|
|
450
485
|
}
|
umap/static/umap/map.css
CHANGED
|
@@ -17,6 +17,24 @@
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
/* *********** */
|
|
21
|
+
/* Structure */
|
|
22
|
+
/* *********** */
|
|
23
|
+
|
|
24
|
+
.umap-edit-enabled {
|
|
25
|
+
--current-header-height: var(--header-height);
|
|
26
|
+
}
|
|
27
|
+
.umap-caption-bar-enabled {
|
|
28
|
+
--current-footer-height: var(--footer-height);
|
|
29
|
+
}
|
|
30
|
+
.leaflet-top {
|
|
31
|
+
top: var(--current-header-height);
|
|
32
|
+
}
|
|
33
|
+
.leaflet-bottom {
|
|
34
|
+
bottom: var(--current-footer-height);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
20
38
|
/* *********** */
|
|
21
39
|
/* Controls */
|
|
22
40
|
/* *********** */
|
|
@@ -99,10 +117,10 @@
|
|
|
99
117
|
box-shadow: 0 0 4px 0 black inset;
|
|
100
118
|
}
|
|
101
119
|
.leaflet-control-star [type="button"] {
|
|
102
|
-
background-position: -
|
|
120
|
+
background-position: -144px -144px;
|
|
103
121
|
}
|
|
104
122
|
.leaflet-control-star.starred [type="button"] {
|
|
105
|
-
background-position: -
|
|
123
|
+
background-position: -108px -144px;
|
|
106
124
|
}
|
|
107
125
|
.leaflet-control-search [type="button"] {
|
|
108
126
|
background-position: -36px -108px;
|
|
@@ -390,24 +408,6 @@ ul.photon-autocomplete {
|
|
|
390
408
|
/* ********************************* */
|
|
391
409
|
/* Help Lightbox */
|
|
392
410
|
/* ********************************* */
|
|
393
|
-
.umap-help-box {
|
|
394
|
-
z-index: 10001;
|
|
395
|
-
position: absolute;
|
|
396
|
-
margin: 0 calc(50% - 500px/2);
|
|
397
|
-
width: 500px;
|
|
398
|
-
max-width: 100vw;
|
|
399
|
-
padding: 40px 20px;
|
|
400
|
-
border: 1px solid #222;
|
|
401
|
-
background-color: var(--color-darkGray);
|
|
402
|
-
color: #efefef;
|
|
403
|
-
font-size: 0.8em;
|
|
404
|
-
visibility: hidden;
|
|
405
|
-
top: -100%;
|
|
406
|
-
}
|
|
407
|
-
.umap-help-box .umap-close-link {
|
|
408
|
-
float: right;
|
|
409
|
-
width: 100px;
|
|
410
|
-
}
|
|
411
411
|
.umap-help-button {
|
|
412
412
|
display: inline-block;
|
|
413
413
|
width: 16px;
|
|
@@ -426,10 +426,6 @@ ul.photon-autocomplete {
|
|
|
426
426
|
.dark .umap-help-button {
|
|
427
427
|
background-image: url('./img/16-white.svg');
|
|
428
428
|
}
|
|
429
|
-
.umap-help-on .umap-help-box {
|
|
430
|
-
visibility: visible;
|
|
431
|
-
top: 100px;
|
|
432
|
-
}
|
|
433
429
|
.umap-help-entry + .umap-help-entry {
|
|
434
430
|
margin-top: 10px;
|
|
435
431
|
border-top: 1px solid #aaa;
|
|
@@ -639,9 +635,6 @@ ul.photon-autocomplete {
|
|
|
639
635
|
.umap-edit-enabled .umap-main-edit-toolbox {
|
|
640
636
|
top: 0;
|
|
641
637
|
}
|
|
642
|
-
.umap-edit-enabled .umap-caption-bar {
|
|
643
|
-
display: none;
|
|
644
|
-
}
|
|
645
638
|
.umap-caption-bar h3,
|
|
646
639
|
.umap-main-edit-toolbox h3 {
|
|
647
640
|
display: inline;
|
|
@@ -664,29 +657,23 @@ ul.photon-autocomplete {
|
|
|
664
657
|
padding-left: 20px;
|
|
665
658
|
display: inline-block; /* Prevents underline on hover. */
|
|
666
659
|
}
|
|
667
|
-
.umap-edit-enabled .leaflet-top {
|
|
668
|
-
top: 46px;
|
|
669
|
-
}
|
|
670
660
|
.umap-caption-bar-enabled .umap-caption-bar {
|
|
671
661
|
display: block;
|
|
672
|
-
height:
|
|
662
|
+
height: var(--footer-height);
|
|
673
663
|
background-color: #fff;
|
|
674
664
|
width: 100%;
|
|
675
665
|
position: absolute;
|
|
676
666
|
left: 0;
|
|
677
667
|
bottom: 0;
|
|
678
668
|
right: 0;
|
|
679
|
-
padding:
|
|
669
|
+
padding: var(--gutter);
|
|
680
670
|
text-align: left;
|
|
681
|
-
line-height:
|
|
671
|
+
line-height: 100%;
|
|
682
672
|
cursor: auto;
|
|
683
673
|
border-top: 1px solid var(--color-lightGray);
|
|
684
674
|
opacity: 0.93;
|
|
685
675
|
z-index: 1000;
|
|
686
676
|
}
|
|
687
|
-
.umap-caption-bar-enabled .leaflet-bottom {
|
|
688
|
-
bottom: 46px;
|
|
689
|
-
}
|
|
690
677
|
.umap-help {
|
|
691
678
|
font-style: italic;
|
|
692
679
|
}
|
|
@@ -1000,9 +987,6 @@ a.umap-control-caption,
|
|
|
1000
987
|
.datalayer-name {
|
|
1001
988
|
cursor: pointer;
|
|
1002
989
|
}
|
|
1003
|
-
.umap-caption h3 {
|
|
1004
|
-
margin-bottom: 0;
|
|
1005
|
-
}
|
|
1006
990
|
.umap-caption .umap-map-owner {
|
|
1007
991
|
padding-left: 31px;
|
|
1008
992
|
}
|
|
@@ -1576,9 +1560,11 @@ span.popup-icon {
|
|
|
1576
1560
|
.umap-popup-container {
|
|
1577
1561
|
flex-grow: 1;
|
|
1578
1562
|
word-break: break-word;
|
|
1563
|
+
white-space: pre-line;
|
|
1564
|
+
margin-bottom: 10px;
|
|
1579
1565
|
}
|
|
1580
|
-
.
|
|
1581
|
-
|
|
1566
|
+
.umap-popup-container ul {
|
|
1567
|
+
list-style-type: disc;
|
|
1582
1568
|
}
|
|
1583
1569
|
.leaflet-control-toolbar,
|
|
1584
1570
|
.leaflet-bar {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { describe, it } from 'mocha'
|
|
2
|
+
import sinon from 'sinon'
|
|
3
|
+
|
|
4
|
+
import pkg from 'chai'
|
|
5
|
+
const { expect } = pkg
|
|
6
|
+
|
|
7
|
+
import { MapUpdater } from '../js/modules/sync/updaters.js'
|
|
8
|
+
import { SyncEngine } from '../js/modules/sync/engine.js'
|
|
9
|
+
|
|
10
|
+
describe('SyncEngine', () => {
|
|
11
|
+
it('should initialize methods even before start', function () {
|
|
12
|
+
const engine = new SyncEngine({})
|
|
13
|
+
engine.upsert()
|
|
14
|
+
engine.update()
|
|
15
|
+
engine.delete()
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe('#dispatch', function () {
|
|
20
|
+
it('should raise an error on unknown updater', function () {
|
|
21
|
+
const dispatcher = new SyncEngine({})
|
|
22
|
+
expect(() => {
|
|
23
|
+
dispatcher.dispatch({
|
|
24
|
+
kind: 'operation',
|
|
25
|
+
subject: 'unknown',
|
|
26
|
+
metadata: {},
|
|
27
|
+
})
|
|
28
|
+
}).to.throw(Error)
|
|
29
|
+
})
|
|
30
|
+
it('should produce an error on malformated messages', function () {
|
|
31
|
+
const dispatcher = new SyncEngine({})
|
|
32
|
+
expect(() => {
|
|
33
|
+
dispatcher.dispatch({
|
|
34
|
+
yeah: 'yeah',
|
|
35
|
+
payload: { foo: 'bar' },
|
|
36
|
+
})
|
|
37
|
+
}).to.throw(Error)
|
|
38
|
+
})
|
|
39
|
+
it('should raise an unknown operations', function () {
|
|
40
|
+
const dispatcher = new SyncEngine({})
|
|
41
|
+
expect(() => {
|
|
42
|
+
dispatcher.dispatch({
|
|
43
|
+
kind: 'something-else',
|
|
44
|
+
})
|
|
45
|
+
}).to.throw(Error)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('Updaters', () => {
|
|
50
|
+
describe('BaseUpdater', function () {
|
|
51
|
+
let updater
|
|
52
|
+
let map
|
|
53
|
+
let obj
|
|
54
|
+
|
|
55
|
+
this.beforeEach(function () {
|
|
56
|
+
map = {}
|
|
57
|
+
updater = new MapUpdater(map)
|
|
58
|
+
obj = {}
|
|
59
|
+
})
|
|
60
|
+
it('should be able to set object properties', function () {
|
|
61
|
+
let obj = {}
|
|
62
|
+
updater.updateObjectValue(obj, 'foo', 'foo')
|
|
63
|
+
expect(obj).deep.equal({ foo: 'foo' })
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should be able to set object properties recursively on existing objects', function () {
|
|
67
|
+
let obj = { foo: {} }
|
|
68
|
+
updater.updateObjectValue(obj, 'foo.bar', 'foo')
|
|
69
|
+
expect(obj).deep.equal({ foo: { bar: 'foo' } })
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should be able to set object properties recursively on deep objects', function () {
|
|
73
|
+
let obj = { foo: { bar: { baz: {} } } }
|
|
74
|
+
updater.updateObjectValue(obj, 'foo.bar.baz.test', 'value')
|
|
75
|
+
expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('should be able to replace object properties recursively on deep objects', function () {
|
|
79
|
+
let obj = { foo: { bar: { baz: { test: 'test' } } } }
|
|
80
|
+
updater.updateObjectValue(obj, 'foo.bar.baz.test', 'value')
|
|
81
|
+
expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('should not set object properties recursively on non-existing objects', function () {
|
|
85
|
+
let obj = { foo: {} }
|
|
86
|
+
updater.updateObjectValue(obj, 'bar.bar', 'value')
|
|
87
|
+
|
|
88
|
+
expect(obj).deep.equal({ foo: {} })
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('should delete keys for undefined values', function () {
|
|
92
|
+
let obj = { foo: 'foo' }
|
|
93
|
+
updater.updateObjectValue(obj, 'foo', undefined)
|
|
94
|
+
|
|
95
|
+
expect(obj).deep.equal({})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('should delete keys for undefined values, recursively', function () {
|
|
99
|
+
let obj = { foo: { bar: 'bar' } }
|
|
100
|
+
updater.updateObjectValue(obj, 'foo.bar', undefined)
|
|
101
|
+
|
|
102
|
+
expect(obj).deep.equal({ foo: {} })
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
})
|
|
@@ -13,12 +13,12 @@ describe('Utils', function () {
|
|
|
13
13
|
it('should handle title', function () {
|
|
14
14
|
assert.equal(Utils.toHTML('# A title'), '<h3>A title</h3>')
|
|
15
15
|
})
|
|
16
|
+
it('should handle title followed by text', function () {
|
|
17
|
+
assert.equal(Utils.toHTML('# A title\nSome text.'), '<h3>A title</h3>Some text.')
|
|
18
|
+
})
|
|
16
19
|
|
|
17
20
|
it('should handle title in the middle of the content', function () {
|
|
18
|
-
assert.equal(
|
|
19
|
-
Utils.toHTML('A phrase\n## A title'),
|
|
20
|
-
'A phrase<br>\n<h4>A title</h4>'
|
|
21
|
-
)
|
|
21
|
+
assert.equal(Utils.toHTML('A phrase\n## A title'), 'A phrase\n<h4>A title</h4>')
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
it('should handle hr', function () {
|
|
@@ -33,18 +33,6 @@ describe('Utils', function () {
|
|
|
33
33
|
assert.equal(Utils.toHTML('Some *italic*'), 'Some <em>italic</em>')
|
|
34
34
|
})
|
|
35
35
|
|
|
36
|
-
it('should handle newlines', function () {
|
|
37
|
-
assert.equal(Utils.toHTML('two\nlines'), 'two<br>\nlines')
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('should not change last newline', function () {
|
|
41
|
-
assert.equal(Utils.toHTML('two\nlines\n'), 'two<br>\nlines\n')
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('should handle two successive newlines', function () {
|
|
45
|
-
assert.equal(Utils.toHTML('two\n\nlines\n'), 'two<br>\n<br>\nlines\n')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
36
|
it('should handle links without formatting', function () {
|
|
49
37
|
assert.equal(
|
|
50
38
|
Utils.toHTML('A simple http://osm.org link'),
|
|
@@ -90,7 +78,7 @@ describe('Utils', function () {
|
|
|
90
78
|
it('should handle simple link followed by a carriage return', function () {
|
|
91
79
|
assert.equal(
|
|
92
80
|
Utils.toHTML('A simple link http://osm.org\nAnother line'),
|
|
93
|
-
'A simple link <a href="http://osm.org" target="_blank">http://osm.org</a
|
|
81
|
+
'A simple link <a href="http://osm.org" target="_blank">http://osm.org</a>\nAnother line'
|
|
94
82
|
)
|
|
95
83
|
})
|
|
96
84
|
|
|
@@ -174,6 +162,27 @@ describe('Utils', function () {
|
|
|
174
162
|
'A phrase with a <a href="http://iframeurl.com?to=http://another.com" target="_blank">http://iframeurl.com?to=http://another.com</a>.'
|
|
175
163
|
)
|
|
176
164
|
})
|
|
165
|
+
|
|
166
|
+
it('simple bullet points', function () {
|
|
167
|
+
assert.equal(
|
|
168
|
+
Utils.toHTML('* First point\n* Second point\n* Last point'),
|
|
169
|
+
'<ul><li>First point</li><li>Second point</li><li>Last point</li></ul>'
|
|
170
|
+
)
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('bullet points with bold and italic', function () {
|
|
174
|
+
assert.equal(
|
|
175
|
+
Utils.toHTML('* First *point*\n* Second **point**\n* Last [[https://here.org|point]]'),
|
|
176
|
+
'<ul><li>First <em>point</em></li><li>Second <strong>point</strong></li><li>Last <a href="https://here.org" target="_blank">point</a></li></ul>'
|
|
177
|
+
)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('title followed by bullet points', function () {
|
|
181
|
+
assert.equal(
|
|
182
|
+
Utils.toHTML('## Some title\n* First *point*\n* Second **point**\n* Last [[https://here.org|point]]'),
|
|
183
|
+
'<h4>Some title</h4><ul><li>First <em>point</em></li><li>Second <strong>point</strong></li><li>Last <a href="https://here.org" target="_blank">point</a></li></ul>'
|
|
184
|
+
)
|
|
185
|
+
})
|
|
177
186
|
})
|
|
178
187
|
|
|
179
188
|
describe('#escapeHTML', function () {
|
|
@@ -192,6 +201,24 @@ describe('Utils', function () {
|
|
|
192
201
|
)
|
|
193
202
|
})
|
|
194
203
|
|
|
204
|
+
it('should not escape video tag with dedicated attributes', function () {
|
|
205
|
+
assert.equal(
|
|
206
|
+
Utils.escapeHTML(
|
|
207
|
+
'<video width="100%" height="281" controls><source type="video/mp4" src="movie.mp4"></video>'
|
|
208
|
+
),
|
|
209
|
+
'<video controls="" height="281" width="100%"><source src="movie.mp4" type="video/mp4"></video>'
|
|
210
|
+
)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('should not escape audio tag with dedicated attributes', function () {
|
|
214
|
+
assert.equal(
|
|
215
|
+
Utils.escapeHTML(
|
|
216
|
+
'<audio controls><source type="audio/ogg" src="horse.ogg"></audio>'
|
|
217
|
+
),
|
|
218
|
+
'<audio controls=""><source src="horse.ogg" type="audio/ogg"></audio>'
|
|
219
|
+
)
|
|
220
|
+
})
|
|
221
|
+
|
|
195
222
|
it('should not fail with int value', function () {
|
|
196
223
|
assert.equal(Utils.escapeHTML(25), '25')
|
|
197
224
|
})
|
|
@@ -461,13 +488,12 @@ describe('Utils', function () {
|
|
|
461
488
|
})
|
|
462
489
|
|
|
463
490
|
describe('#normalize()', function () {
|
|
464
|
-
it('should remove accents',
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
})
|
|
491
|
+
it('should remove accents', function () {
|
|
492
|
+
// French é
|
|
493
|
+
assert.equal(Utils.normalize('aéroport'), 'aeroport')
|
|
494
|
+
// American é
|
|
495
|
+
assert.equal(Utils.normalize('aéroport'), 'aeroport')
|
|
496
|
+
})
|
|
471
497
|
})
|
|
472
498
|
|
|
473
499
|
describe('#sortFeatures()', function () {
|
|
@@ -530,17 +556,17 @@ describe('Utils', function () {
|
|
|
530
556
|
})
|
|
531
557
|
})
|
|
532
558
|
|
|
533
|
-
describe(
|
|
559
|
+
describe('#copyJSON', function () {
|
|
534
560
|
it('should actually copy the JSON', function () {
|
|
535
|
-
let originalJSON = {
|
|
561
|
+
let originalJSON = { some: 'json' }
|
|
536
562
|
let returned = Utils.CopyJSON(originalJSON)
|
|
537
563
|
|
|
538
564
|
// Change the original JSON
|
|
539
|
-
originalJSON[
|
|
565
|
+
originalJSON['anotherKey'] = 'value'
|
|
540
566
|
|
|
541
567
|
// ensure the two aren't the same object
|
|
542
568
|
assert.notEqual(returned, originalJSON)
|
|
543
|
-
assert.deepEqual(returned, {
|
|
569
|
+
assert.deepEqual(returned, { some: 'json' })
|
|
544
570
|
})
|
|
545
571
|
})
|
|
546
572
|
|
|
@@ -597,21 +623,37 @@ describe('Utils', function () {
|
|
|
597
623
|
assert.deepEqual(getImpactsFromSchema(['foo', 'bar', 'baz'], schema), ['A', 'B'])
|
|
598
624
|
})
|
|
599
625
|
})
|
|
600
|
-
|
|
626
|
+
|
|
627
|
+
describe('#parseNaiveDate', () => {
|
|
601
628
|
it('should parse a date', () => {
|
|
602
|
-
assert.equal(
|
|
629
|
+
assert.equal(
|
|
630
|
+
Utils.parseNaiveDate('2024/03/04').toISOString(),
|
|
631
|
+
'2024-03-04T00:00:00.000Z'
|
|
632
|
+
)
|
|
603
633
|
})
|
|
604
634
|
it('should parse a datetime', () => {
|
|
605
|
-
assert.equal(
|
|
635
|
+
assert.equal(
|
|
636
|
+
Utils.parseNaiveDate('2024/03/04 12:13:14').toISOString(),
|
|
637
|
+
'2024-03-04T00:00:00.000Z'
|
|
638
|
+
)
|
|
606
639
|
})
|
|
607
640
|
it('should parse an iso datetime', () => {
|
|
608
|
-
assert.equal(
|
|
641
|
+
assert.equal(
|
|
642
|
+
Utils.parseNaiveDate('2024-03-04T00:00:00.000Z').toISOString(),
|
|
643
|
+
'2024-03-04T00:00:00.000Z'
|
|
644
|
+
)
|
|
609
645
|
})
|
|
610
646
|
it('should parse a GMT time', () => {
|
|
611
|
-
assert.equal(
|
|
647
|
+
assert.equal(
|
|
648
|
+
Utils.parseNaiveDate('04 Mar 2024 00:12:00 GMT').toISOString(),
|
|
649
|
+
'2024-03-04T00:00:00.000Z'
|
|
650
|
+
)
|
|
612
651
|
})
|
|
613
652
|
it('should parse a GMT time with explicit timezone', () => {
|
|
614
|
-
assert.equal(
|
|
653
|
+
assert.equal(
|
|
654
|
+
Utils.parseNaiveDate('Thu, 04 Mar 2024 00:00:00 GMT+0300').toISOString(),
|
|
655
|
+
'2024-03-03T00:00:00.000Z'
|
|
656
|
+
)
|
|
615
657
|
})
|
|
616
658
|
})
|
|
617
659
|
})
|
umap/static/umap/vars.css
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
--color-limeGreen: #b9f5d2;
|
|
9
9
|
--color-brightCyan: #46ece6;
|
|
10
10
|
--color-lightCyan: #d4fbf9;
|
|
11
|
+
--color-red: #c60f13;
|
|
12
|
+
--color-darkRed: #5b2a2a;
|
|
11
13
|
|
|
12
14
|
--background-color: var(--color-light);
|
|
13
15
|
--color-accent: var(--color-brightCyan);
|
|
16
|
+
--text-color: black;
|
|
14
17
|
|
|
15
18
|
/* Buttons. */
|
|
16
19
|
--button-primary-background: var(--color-waterMint);
|
|
@@ -19,14 +22,28 @@
|
|
|
19
22
|
--button-neutral-color: var(--color-darkGray);
|
|
20
23
|
|
|
21
24
|
/* Sizes and spaces */
|
|
25
|
+
--gutter: 8px;
|
|
22
26
|
--panel-gutter: 10px;
|
|
23
27
|
--panel-bottom: 40px;
|
|
24
28
|
--panel-header-height: 36px;
|
|
25
29
|
--panel-width: 400px;
|
|
26
30
|
--header-height: 46px;
|
|
27
|
-
--
|
|
31
|
+
--current-header-height: 0px;
|
|
32
|
+
--footer-height: 28px;
|
|
33
|
+
--current-footer-height: 0px;
|
|
28
34
|
--control-size: 36px;
|
|
35
|
+
--border-radius: 4px;
|
|
36
|
+
--box-padding: 20px;
|
|
37
|
+
--box-margin: 14px;
|
|
29
38
|
}
|
|
30
39
|
.dark {
|
|
31
40
|
--background-color: var(--color-darkGray);
|
|
41
|
+
--text-color: #efefef;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@media only screen and (max-width:770px) {
|
|
45
|
+
:root {
|
|
46
|
+
--box-padding: 10px;
|
|
47
|
+
--box-margin: 7px;
|
|
48
|
+
}
|
|
32
49
|
}
|