umap-project 1.14.0a1__py3-none-any.whl → 1.14.0a2__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 (182) hide show
  1. umap/__init__.py +1 -1
  2. umap/static/.gitignore +0 -0
  3. umap/static/umap/base.css +994 -0
  4. umap/static/umap/bitbucket.png +0 -0
  5. umap/static/umap/content.css +395 -0
  6. umap/static/umap/favicons/apple-touch-icon.png +0 -0
  7. umap/static/umap/favicons/favicon.ico +0 -0
  8. umap/static/umap/favicons/icon-192.png +0 -0
  9. umap/static/umap/favicons/icon-512.png +0 -0
  10. umap/static/umap/favicons/icon.svg +5 -0
  11. umap/static/umap/font/FiraSans-Light.woff +0 -0
  12. umap/static/umap/font/FiraSans-Light.woff2 +0 -0
  13. umap/static/umap/font/FiraSans-LightItalic.woff +0 -0
  14. umap/static/umap/font/FiraSans-LightItalic.woff2 +0 -0
  15. umap/static/umap/font/FiraSans-SemiBold.woff +0 -0
  16. umap/static/umap/font/FiraSans-SemiBold.woff2 +0 -0
  17. umap/static/umap/font.css +33 -0
  18. umap/static/umap/github.png +0 -0
  19. umap/static/umap/img/16-white.svg +190 -0
  20. umap/static/umap/img/16.svg +182 -0
  21. umap/static/umap/img/24-white.svg +62 -0
  22. umap/static/umap/img/24.svg +90 -0
  23. umap/static/umap/img/edit.svg +7 -0
  24. umap/static/umap/img/icon-bg.png +0 -0
  25. umap/static/umap/img/logo.svg +4 -0
  26. umap/static/umap/img/logo_filigree.png +0 -0
  27. umap/static/umap/img/logo_small.svg +14 -0
  28. umap/static/umap/img/marker.png +0 -0
  29. umap/static/umap/img/opensource.svg +7 -0
  30. umap/static/umap/img/osm.svg +7 -0
  31. umap/static/umap/img/search.gif +0 -0
  32. umap/static/umap/img/source/16-white.svg +980 -0
  33. umap/static/umap/img/source/16.svg +201 -0
  34. umap/static/umap/img/source/24-white.svg +83 -0
  35. umap/static/umap/img/source/24.svg +110 -0
  36. umap/static/umap/js/components/fragment.js +13 -0
  37. umap/static/umap/js/modules/global.js +8 -0
  38. umap/static/umap/js/modules/urls.js +29 -0
  39. umap/static/umap/js/umap.autocomplete.js +336 -0
  40. umap/static/umap/js/umap.browser.js +148 -0
  41. umap/static/umap/js/umap.controls.js +1542 -0
  42. umap/static/umap/js/umap.core.js +851 -0
  43. umap/static/umap/js/umap.datalayer.permissions.js +72 -0
  44. umap/static/umap/js/umap.features.js +1216 -0
  45. umap/static/umap/js/umap.forms.js +1267 -0
  46. umap/static/umap/js/umap.icon.js +234 -0
  47. umap/static/umap/js/umap.importer.js +166 -0
  48. umap/static/umap/js/umap.js +2010 -0
  49. umap/static/umap/js/umap.layer.js +1636 -0
  50. umap/static/umap/js/umap.permissions.js +212 -0
  51. umap/static/umap/js/umap.popup.js +340 -0
  52. umap/static/umap/js/umap.share.js +254 -0
  53. umap/static/umap/js/umap.slideshow.js +165 -0
  54. umap/static/umap/js/umap.tableeditor.js +120 -0
  55. umap/static/umap/js/umap.ui.js +240 -0
  56. umap/static/umap/js/umap.xhr.js +304 -0
  57. umap/static/umap/locale/am_ET.js +447 -0
  58. umap/static/umap/locale/am_ET.json +445 -0
  59. umap/static/umap/locale/ar.js +447 -0
  60. umap/static/umap/locale/ar.json +445 -0
  61. umap/static/umap/locale/ast.js +447 -0
  62. umap/static/umap/locale/ast.json +445 -0
  63. umap/static/umap/locale/bg.js +447 -0
  64. umap/static/umap/locale/bg.json +445 -0
  65. umap/static/umap/locale/br.js +447 -0
  66. umap/static/umap/locale/br.json +445 -0
  67. umap/static/umap/locale/ca.js +447 -0
  68. umap/static/umap/locale/ca.json +445 -0
  69. umap/static/umap/locale/cs_CZ.js +447 -0
  70. umap/static/umap/locale/cs_CZ.json +445 -0
  71. umap/static/umap/locale/da.js +447 -0
  72. umap/static/umap/locale/da.json +445 -0
  73. umap/static/umap/locale/de.js +447 -0
  74. umap/static/umap/locale/de.json +445 -0
  75. umap/static/umap/locale/el.js +447 -0
  76. umap/static/umap/locale/el.json +445 -0
  77. umap/static/umap/locale/en.js +447 -0
  78. umap/static/umap/locale/en.json +445 -0
  79. umap/static/umap/locale/en_US.json +445 -0
  80. umap/static/umap/locale/es.js +447 -0
  81. umap/static/umap/locale/es.json +445 -0
  82. umap/static/umap/locale/et.js +447 -0
  83. umap/static/umap/locale/et.json +445 -0
  84. umap/static/umap/locale/eu.js +413 -0
  85. umap/static/umap/locale/eu.json +411 -0
  86. umap/static/umap/locale/fa_IR.js +447 -0
  87. umap/static/umap/locale/fa_IR.json +445 -0
  88. umap/static/umap/locale/fi.js +447 -0
  89. umap/static/umap/locale/fi.json +445 -0
  90. umap/static/umap/locale/fr.js +447 -0
  91. umap/static/umap/locale/fr.json +445 -0
  92. umap/static/umap/locale/gl.js +447 -0
  93. umap/static/umap/locale/gl.json +445 -0
  94. umap/static/umap/locale/he.js +447 -0
  95. umap/static/umap/locale/he.json +445 -0
  96. umap/static/umap/locale/hr.js +447 -0
  97. umap/static/umap/locale/hr.json +445 -0
  98. umap/static/umap/locale/hu.js +447 -0
  99. umap/static/umap/locale/hu.json +445 -0
  100. umap/static/umap/locale/id.js +447 -0
  101. umap/static/umap/locale/id.json +445 -0
  102. umap/static/umap/locale/is.js +447 -0
  103. umap/static/umap/locale/is.json +445 -0
  104. umap/static/umap/locale/it.js +447 -0
  105. umap/static/umap/locale/it.json +445 -0
  106. umap/static/umap/locale/ja.js +447 -0
  107. umap/static/umap/locale/ja.json +445 -0
  108. umap/static/umap/locale/ko.js +447 -0
  109. umap/static/umap/locale/ko.json +445 -0
  110. umap/static/umap/locale/lt.js +447 -0
  111. umap/static/umap/locale/lt.json +445 -0
  112. umap/static/umap/locale/ms.js +447 -0
  113. umap/static/umap/locale/ms.json +445 -0
  114. umap/static/umap/locale/nl.js +447 -0
  115. umap/static/umap/locale/nl.json +445 -0
  116. umap/static/umap/locale/no.js +447 -0
  117. umap/static/umap/locale/no.json +445 -0
  118. umap/static/umap/locale/pl.js +447 -0
  119. umap/static/umap/locale/pl.json +445 -0
  120. umap/static/umap/locale/pl_PL.json +445 -0
  121. umap/static/umap/locale/pt.js +447 -0
  122. umap/static/umap/locale/pt.json +445 -0
  123. umap/static/umap/locale/pt_BR.js +447 -0
  124. umap/static/umap/locale/pt_BR.json +445 -0
  125. umap/static/umap/locale/pt_PT.js +447 -0
  126. umap/static/umap/locale/pt_PT.json +445 -0
  127. umap/static/umap/locale/ro.js +447 -0
  128. umap/static/umap/locale/ro.json +445 -0
  129. umap/static/umap/locale/ru.js +447 -0
  130. umap/static/umap/locale/ru.json +445 -0
  131. umap/static/umap/locale/si.js +439 -0
  132. umap/static/umap/locale/si.json +437 -0
  133. umap/static/umap/locale/sk_SK.js +447 -0
  134. umap/static/umap/locale/sk_SK.json +445 -0
  135. umap/static/umap/locale/sl.js +447 -0
  136. umap/static/umap/locale/sl.json +445 -0
  137. umap/static/umap/locale/sr.js +447 -0
  138. umap/static/umap/locale/sr.json +445 -0
  139. umap/static/umap/locale/sv.js +447 -0
  140. umap/static/umap/locale/sv.json +445 -0
  141. umap/static/umap/locale/th_TH.js +447 -0
  142. umap/static/umap/locale/th_TH.json +445 -0
  143. umap/static/umap/locale/tr.js +447 -0
  144. umap/static/umap/locale/tr.json +445 -0
  145. umap/static/umap/locale/uk_UA.js +447 -0
  146. umap/static/umap/locale/uk_UA.json +445 -0
  147. umap/static/umap/locale/vi.js +447 -0
  148. umap/static/umap/locale/vi.json +445 -0
  149. umap/static/umap/locale/vi_VN.json +445 -0
  150. umap/static/umap/locale/zh.js +447 -0
  151. umap/static/umap/locale/zh.json +445 -0
  152. umap/static/umap/locale/zh_CN.json +445 -0
  153. umap/static/umap/locale/zh_TW.Big5.json +445 -0
  154. umap/static/umap/locale/zh_TW.js +447 -0
  155. umap/static/umap/locale/zh_TW.json +445 -0
  156. umap/static/umap/map.css +1843 -0
  157. umap/static/umap/nav.css +81 -0
  158. umap/static/umap/openstreetmap.png +0 -0
  159. umap/static/umap/test/.eslintrc +22 -0
  160. umap/static/umap/test/Choropleth.js +243 -0
  161. umap/static/umap/test/Controls.js +100 -0
  162. umap/static/umap/test/DataLayer.js +495 -0
  163. umap/static/umap/test/Feature.js +382 -0
  164. umap/static/umap/test/Map.Export.js +106 -0
  165. umap/static/umap/test/Map.Init.js +46 -0
  166. umap/static/umap/test/Map.js +342 -0
  167. umap/static/umap/test/Marker.js +122 -0
  168. umap/static/umap/test/Permissions.js +74 -0
  169. umap/static/umap/test/Polygon.js +367 -0
  170. umap/static/umap/test/Polyline.js +402 -0
  171. umap/static/umap/test/TableEditor.js +100 -0
  172. umap/static/umap/test/URLs.js +54 -0
  173. umap/static/umap/test/Util.js +549 -0
  174. umap/static/umap/test/_pre.js +460 -0
  175. umap/static/umap/test/index.html +135 -0
  176. umap/static/umap/theme.css +1 -0
  177. umap/static/umap/twitter.png +0 -0
  178. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/METADATA +1 -1
  179. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/RECORD +182 -6
  180. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/WHEEL +0 -0
  181. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/entry_points.txt +0 -0
  182. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,851 @@
1
+ /* Poor man pub/sub handler, enough for now */
2
+
3
+ L.UmapSingleton = L.Evented.extend({})
4
+ L.U = new L.UmapSingleton()
5
+ L.U.Map = L.Map.extend({})
6
+
7
+ /*
8
+ * Utils
9
+ */
10
+ L.Util.queryString = (name, fallback) => {
11
+ const decode = (s) => decodeURIComponent(s.replace(/\+/g, ' '))
12
+ const qs = window.location.search.slice(1).split('&'),
13
+ qa = {}
14
+ for (const i in qs) {
15
+ const key = qs[i].split('=')
16
+ if (!key) continue
17
+ qa[decode(key[0])] = key[1] ? decode(key[1]) : 1
18
+ }
19
+ return qa[name] || fallback
20
+ }
21
+
22
+ L.Util.booleanFromQueryString = (name) => {
23
+ const value = L.Util.queryString(name)
24
+ return value === '1' || value === 'true'
25
+ }
26
+
27
+ L.Util.setFromQueryString = (options, name) => {
28
+ const value = L.Util.queryString(name)
29
+ if (typeof value !== 'undefined') options[name] = value
30
+ }
31
+
32
+ L.Util.setBooleanFromQueryString = (options, name) => {
33
+ const value = L.Util.queryString(name)
34
+ if (typeof value !== 'undefined') options[name] = value == '1' || value == 'true'
35
+ }
36
+ L.Util.setNullableBooleanFromQueryString = (options, name) => {
37
+ let value = L.Util.queryString(name)
38
+ if (typeof value !== 'undefined') {
39
+ if (value === 'null') value = null
40
+ else if (value === '0' || value === 'false') value = false
41
+ else value = true
42
+ options[name] = value
43
+ }
44
+ }
45
+ L.Util.escapeHTML = (s) => {
46
+ s = s ? s.toString() : ''
47
+ s = DOMPurify.sanitize(s, {
48
+ USE_PROFILES: { html: true },
49
+ ADD_TAGS: ['iframe'],
50
+ ALLOWED_TAGS: [
51
+ 'h3',
52
+ 'h4',
53
+ 'h5',
54
+ 'hr',
55
+ 'strong',
56
+ 'em',
57
+ 'ul',
58
+ 'li',
59
+ 'a',
60
+ 'div',
61
+ 'iframe',
62
+ 'img',
63
+ 'br',
64
+ ],
65
+ ADD_ATTR: ['target', 'allow', 'allowfullscreen', 'frameborder', 'scrolling'],
66
+ ALLOWED_ATTR: ['href', 'src', 'width', 'height'],
67
+ // Added: `geo:` URL scheme as defined in RFC5870:
68
+ // https://www.rfc-editor.org/rfc/rfc5870.html
69
+ // The base RegExp comes from:
70
+ // https://github.com/cure53/DOMPurify/blob/main/src/regexp.js#L10
71
+ ALLOWED_URI_REGEXP:
72
+ /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|geo):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
73
+ })
74
+ return s
75
+ }
76
+ L.Util.toHTML = (r, options) => {
77
+ if (!r) return ''
78
+ const target = (options && options.target) || 'blank'
79
+ let ii
80
+
81
+ // detect newline format
82
+ const newline = r.indexOf('\r\n') != -1 ? '\r\n' : r.indexOf('\n') != -1 ? '\n' : ''
83
+
84
+ // headings and hr
85
+ r = r.replace(/^### (.*)/gm, '<h5>$1</h5>')
86
+ r = r.replace(/^## (.*)/gm, '<h4>$1</h4>')
87
+ r = r.replace(/^# (.*)/gm, '<h3>$1</h3>')
88
+ r = r.replace(/^---/gm, '<hr>')
89
+
90
+ // bold, italics
91
+ r = r.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
92
+ r = r.replace(/\*(.*?)\*/g, '<em>$1</em>')
93
+
94
+ // unordered lists
95
+ r = r.replace(/^\*\* (.*)/gm, '<ul><ul><li>$1</li></ul></ul>')
96
+ r = r.replace(/^\* (.*)/gm, '<ul><li>$1</li></ul>')
97
+ for (ii = 0; ii < 3; ii++)
98
+ r = r.replace(new RegExp(`</ul>${newline}<ul>`, 'g'), newline)
99
+
100
+ // links
101
+ r = r.replace(/(\[\[http)/g, '[[h_t_t_p') // Escape for avoiding clash between [[http://xxx]] and http://xxx
102
+ r = r.replace(/({{http)/g, '{{h_t_t_p')
103
+ r = r.replace(/(=http)/g, '=h_t_t_p') // http://xxx as query string, see https://github.com/umap-project/umap/issues/607
104
+ r = r.replace(/(https?:[^ \<)\n]*)/g, `<a target="_${target}" href="$1">$1</a>`)
105
+ r = r.replace(
106
+ /\[\[(h_t_t_ps?:[^\]|]*?)\]\]/g,
107
+ `<a target="_${target}" href="$1">$1</a>`
108
+ )
109
+ r = r.replace(
110
+ /\[\[(h_t_t_ps?:[^|]*?)\|(.*?)\]\]/g,
111
+ `<a target="_${target}" href="$1">$2</a>`
112
+ )
113
+ r = r.replace(/\[\[([^\]|]*?)\]\]/g, `<a target="_${target}" href="$1">$1</a>`)
114
+ r = r.replace(/\[\[([^|]*?)\|(.*?)\]\]/g, `<a target="_${target}" href="$1">$2</a>`)
115
+
116
+ // iframe
117
+ r = r.replace(
118
+ /{{{(h_t_t_ps?[^ |{]*)}}}/g,
119
+ '<div><iframe frameborder="0" src="$1" width="100%" height="300px"></iframe></div>'
120
+ )
121
+ r = r.replace(
122
+ /{{{(h_t_t_ps?[^ |{]*)\|(\d*)(px)?}}}/g,
123
+ '<div><iframe frameborder="0" src="$1" width="100%" height="$2px"></iframe></div>'
124
+ )
125
+ r = r.replace(
126
+ /{{{(h_t_t_ps?[^ |{]*)\|(\d*)(px)?\*(\d*)(px)?}}}/g,
127
+ '<div><iframe frameborder="0" src="$1" width="$4px" height="$2px"></iframe></div>'
128
+ )
129
+
130
+ // images
131
+ r = r.replace(/{{([^\]|]*?)}}/g, '<img src="$1">')
132
+ r = r.replace(
133
+ /{{([^|]*?)\|(\d*?)(px)?}}/g,
134
+ '<img src="$1" style="width:$2px;min-width:$2px;">'
135
+ )
136
+
137
+ //Unescape http
138
+ r = r.replace(/(h_t_t_p)/g, 'http')
139
+
140
+ // Preserver line breaks
141
+ if (newline) r = r.replace(new RegExp(`${newline}(?=[^]+)`, 'g'), `<br>${newline}`)
142
+
143
+ r = L.Util.escapeHTML(r)
144
+
145
+ return r
146
+ }
147
+ L.Util.isObject = (what) => typeof what === 'object' && what !== null
148
+ L.Util.CopyJSON = (geojson) => JSON.parse(JSON.stringify(geojson))
149
+ L.Util.detectFileType = (f) => {
150
+ const filename = f.name ? escape(f.name.toLowerCase()) : ''
151
+ function ext(_) {
152
+ return filename.indexOf(_) !== -1
153
+ }
154
+ if (f.type === 'application/vnd.google-earth.kml+xml' || ext('.kml')) {
155
+ return 'kml'
156
+ }
157
+ if (ext('.gpx')) return 'gpx'
158
+ if (ext('.geojson') || ext('.json')) return 'geojson'
159
+ if (f.type === 'text/csv' || ext('.csv') || ext('.tsv') || ext('.dsv')) {
160
+ return 'csv'
161
+ }
162
+ if (ext('.xml') || ext('.osm')) return 'osm'
163
+ if (ext('.umap')) return 'umap'
164
+ }
165
+
166
+ L.Util.usableOption = (options, option) =>
167
+ options[option] !== undefined && options[option] !== ''
168
+
169
+ L.Util.greedyTemplate = (str, data, ignore) => {
170
+ function getValue(data, path) {
171
+ let value = data
172
+ for (let i = 0; i < path.length; i++) {
173
+ value = value[path[i]]
174
+ if (value === undefined) break
175
+ }
176
+ return value
177
+ }
178
+
179
+ if (typeof str !== 'string') return ''
180
+
181
+ return str.replace(
182
+ /\{ *([^\{\}/\-]+)(?:\|("[^"]*"))? *\}/g,
183
+ (str, key, staticFallback) => {
184
+ const vars = key.split('|')
185
+ let value
186
+ let path
187
+ if (staticFallback !== undefined) {
188
+ vars.push(staticFallback)
189
+ }
190
+ for (let i = 0; i < vars.length; i++) {
191
+ path = vars[i]
192
+ if (path.startsWith('"') && path.endsWith('"'))
193
+ value = path.substring(1, path.length - 1) // static default value.
194
+ else value = getValue(data, path.split('.'))
195
+ if (value !== undefined) break
196
+ }
197
+ if (value === undefined) {
198
+ if (ignore) value = str
199
+ else value = ''
200
+ }
201
+ return value
202
+ }
203
+ )
204
+ }
205
+
206
+ L.Util.naturalSort = (a, b) => {
207
+ return a
208
+ .toString()
209
+ .toLowerCase()
210
+ .localeCompare(b.toString().toLowerCase(), L.lang || 'en', {
211
+ sensitivity: 'base',
212
+ numeric: true,
213
+ })
214
+ }
215
+
216
+ L.Util.sortFeatures = (features, sortKey) => {
217
+ const sortKeys = (sortKey || 'name').split(',')
218
+
219
+ const sort = (a, b, i) => {
220
+ let sortKey = sortKeys[i],
221
+ reverse = 1
222
+ if (sortKey[0] === '-') {
223
+ reverse = -1
224
+ sortKey = sortKey.substring(1)
225
+ }
226
+ let score
227
+ const valA = a.properties[sortKey] || ''
228
+ const valB = b.properties[sortKey] || ''
229
+ if (!valA) score = -1
230
+ else if (!valB) score = 1
231
+ else score = L.Util.naturalSort(valA, valB)
232
+ if (score === 0 && sortKeys[i + 1]) return sort(a, b, i + 1)
233
+ return score * reverse
234
+ }
235
+
236
+ features.sort((a, b) => {
237
+ if (!a.properties || !b.properties) {
238
+ return 0
239
+ }
240
+ return sort(a, b, 0)
241
+ })
242
+
243
+ return features
244
+ }
245
+
246
+ L.Util.flattenCoordinates = (coords) => {
247
+ while (coords[0] && typeof coords[0][0] !== 'number') coords = coords[0]
248
+ return coords
249
+ }
250
+
251
+ L.Util.buildQueryString = (params) => {
252
+ const query_string = []
253
+ for (const key in params) {
254
+ query_string.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
255
+ }
256
+ return query_string.join('&')
257
+ }
258
+
259
+ L.Util.getBaseUrl = () => `//${window.location.host}${window.location.pathname}`
260
+
261
+ L.Util.hasVar = (value) => {
262
+ return typeof value === 'string' && value.indexOf('{') != -1
263
+ }
264
+
265
+ L.Util.isPath = function (value) {
266
+ return value && value.length && value.startsWith('/')
267
+ }
268
+
269
+ L.Util.isRemoteUrl = function (value) {
270
+ return value && value.length && value.startsWith('http')
271
+ }
272
+
273
+ L.Util.isDataImage = function (value) {
274
+ return value && value.length && value.startsWith('data:image')
275
+ }
276
+
277
+ L.Util.copyToClipboard = function (textToCopy) {
278
+ // https://stackoverflow.com/a/65996386
279
+ // Navigator clipboard api needs a secure context (https)
280
+ if (navigator.clipboard && window.isSecureContext) {
281
+ navigator.clipboard.writeText(textToCopy)
282
+ } else {
283
+ // Use the 'out of viewport hidden text area' trick
284
+ const textArea = document.createElement('textarea')
285
+ textArea.value = textToCopy
286
+
287
+ // Move textarea out of the viewport so it's not visible
288
+ textArea.style.position = 'absolute'
289
+ textArea.style.left = '-999999px'
290
+
291
+ document.body.prepend(textArea)
292
+ textArea.select()
293
+
294
+ try {
295
+ document.execCommand('copy')
296
+ } catch (error) {
297
+ console.error(error)
298
+ } finally {
299
+ textArea.remove()
300
+ }
301
+ }
302
+ }
303
+
304
+ L.Util.normalize = function (s) {
305
+ return (s || '')
306
+ .toLowerCase()
307
+ .normalize('NFD')
308
+ .replace(/[\u0300-\u036f]/g, '')
309
+ }
310
+
311
+ L.DomUtil.add = (tagName, className, container, content) => {
312
+ const el = L.DomUtil.create(tagName, className, container)
313
+ if (content) {
314
+ if (content.nodeType && content.nodeType === 1) {
315
+ el.appendChild(content)
316
+ } else {
317
+ el.innerHTML = content
318
+ }
319
+ }
320
+ return el
321
+ }
322
+
323
+ L.DomUtil.createFieldset = (container, legend, options) => {
324
+ options = options || {}
325
+ const fieldset = L.DomUtil.create('div', 'fieldset toggle', container)
326
+ const legendEl = L.DomUtil.add('h5', 'legend style_options_toggle', fieldset, legend)
327
+ const fieldsEl = L.DomUtil.add('div', 'fields with-transition', fieldset)
328
+ L.DomEvent.on(legendEl, 'click', function () {
329
+ if (L.DomUtil.hasClass(fieldset, 'on')) {
330
+ L.DomUtil.removeClass(fieldset, 'on')
331
+ } else {
332
+ L.DomUtil.addClass(fieldset, 'on')
333
+ if (options.callback) options.callback.call(options.context || this)
334
+ }
335
+ })
336
+ return fieldsEl
337
+ }
338
+
339
+ L.DomUtil.createButton = (className, container, content, callback, context) => {
340
+ const el = L.DomUtil.add('button', className, container, content)
341
+ el.type = 'button'
342
+ el.title = content
343
+ if (callback) {
344
+ L.DomEvent.on(el, 'click', L.DomEvent.stop).on(el, 'click', callback, context)
345
+ }
346
+ return el
347
+ }
348
+
349
+ L.DomUtil.createLink = (className, container, content, url, target, title) => {
350
+ const el = L.DomUtil.add('a', className, container, content)
351
+ el.href = url
352
+ if (target) {
353
+ el.target = target
354
+ }
355
+ if (title) {
356
+ el.title = title
357
+ }
358
+ return el
359
+ }
360
+
361
+ L.DomUtil.createCopiableInput = (parent, label, value) => {
362
+ const wrapper = L.DomUtil.add('div', 'copiable-input', parent)
363
+ const labelEl = L.DomUtil.add('label', '', wrapper, label)
364
+ const input = L.DomUtil.add('input', '', labelEl)
365
+ input.type = 'text'
366
+ input.readOnly = true
367
+ input.value = value
368
+ const button = L.DomUtil.createButton(
369
+ '',
370
+ wrapper,
371
+ '',
372
+ () => L.Util.copyToClipboard(input.value),
373
+ this
374
+ )
375
+ button.title = L._('copy')
376
+ return input
377
+ }
378
+
379
+ L.DomUtil.classIf = (el, className, bool) => {
380
+ if (bool) L.DomUtil.addClass(el, className)
381
+ else L.DomUtil.removeClass(el, className)
382
+ }
383
+
384
+ L.DomUtil.element = (what, attrs, parent) => {
385
+ const el = document.createElement(what)
386
+ for (const attr in attrs) {
387
+ el[attr] = attrs[attr]
388
+ }
389
+ if (typeof parent !== 'undefined') {
390
+ parent.appendChild(el)
391
+ }
392
+ return el
393
+ }
394
+
395
+ L.DomUtil.before = (target, el) => {
396
+ target.parentNode.insertBefore(el, target)
397
+ return el
398
+ }
399
+
400
+ L.DomUtil.after = (target, el) => {
401
+ target.parentNode.insertBefore(el, target.nextSibling)
402
+ return el
403
+ }
404
+
405
+ L.DomUtil.RGBRegex = /rgb *\( *([0-9]{1,3}) *, *([0-9]{1,3}) *, *([0-9]{1,3}) *\)/
406
+ L.DomUtil.TextColorFromBackgroundColor = (el, bgcolor) => {
407
+ return L.DomUtil.contrastedColor(el, bgcolor) ? '#ffffff' : '#000000'
408
+ }
409
+ const _CACHE_CONSTRAST = {}
410
+ L.DomUtil.contrastedColor = (el, bgcolor) => {
411
+ // Return 0 for black and 1 for white
412
+ // bgcolor is a human color, it can be a any keyword (purple…)
413
+ if (typeof _CACHE_CONSTRAST[bgcolor] !== 'undefined') return _CACHE_CONSTRAST[bgcolor]
414
+ let out = 0
415
+ let rgb = window.getComputedStyle(el).getPropertyValue('background-color')
416
+ rgb = L.DomUtil.RGBRegex.exec(rgb)
417
+ if (!rgb || rgb.length !== 4) return out
418
+ rgb = parseInt(rgb[1], 10) + parseInt(rgb[2], 10) + parseInt(rgb[3], 10)
419
+ if (rgb < (255 * 3) / 2) out = 1
420
+ if (bgcolor) _CACHE_CONSTRAST[bgcolor] = out
421
+ return out
422
+ }
423
+ L.DomEvent.once = (el, types, fn, context) => {
424
+ // cf https://github.com/Leaflet/Leaflet/pull/3528#issuecomment-134551575
425
+
426
+ if (typeof types === 'object') {
427
+ for (const type in types) {
428
+ L.DomEvent.once(el, type, types[type], fn)
429
+ }
430
+ return L.DomEvent
431
+ }
432
+
433
+ const handler = L.bind(() => {
434
+ L.DomEvent.off(el, types, fn, context).off(el, types, handler, context)
435
+ }, L.DomEvent)
436
+
437
+ // add a listener that's executed once and removed after that
438
+ return L.DomEvent.on(el, types, fn, context).on(el, types, handler, context)
439
+ }
440
+
441
+ /*
442
+ * Global events
443
+ */
444
+ L.U.Keys = {
445
+ LEFT: 37,
446
+ UP: 38,
447
+ RIGHT: 39,
448
+ DOWN: 40,
449
+ TAB: 9,
450
+ ENTER: 13,
451
+ ESC: 27,
452
+ APPLE: 91,
453
+ SHIFT: 16,
454
+ ALT: 17,
455
+ CTRL: 18,
456
+ E: 69,
457
+ F: 70,
458
+ H: 72,
459
+ I: 73,
460
+ L: 76,
461
+ M: 77,
462
+ O: 79,
463
+ P: 80,
464
+ S: 83,
465
+ Z: 90,
466
+ }
467
+
468
+ L.U.Help = L.Class.extend({
469
+ SHORTCUTS: {
470
+ DRAW_MARKER: {
471
+ shortcut: 'Modifier+M',
472
+ label: L._('Draw a marker'),
473
+ },
474
+ DRAW_LINE: {
475
+ shortcut: 'Modifier+L',
476
+ label: L._('Draw a polyline'),
477
+ },
478
+ DRAW_POLYGON: {
479
+ shortcut: 'Modifier+P',
480
+ label: L._('Draw a polygon'),
481
+ },
482
+ TOGGLE_EDIT: {
483
+ shortcut: 'Modifier+E',
484
+ label: L._('Toggle edit mode'),
485
+ },
486
+ STOP_EDIT: {
487
+ shortcut: 'Modifier+E',
488
+ label: L._('Stop editing'),
489
+ },
490
+ SAVE_MAP: {
491
+ shortcut: 'Modifier+S',
492
+ label: L._('Save map'),
493
+ },
494
+ IMPORT_PANEL: {
495
+ shortcut: 'Modifier+I',
496
+ label: L._('Import data'),
497
+ },
498
+ SEARCH: {
499
+ shortcut: 'Modifier+F',
500
+ label: L._('Search location'),
501
+ },
502
+ CANCEL: {
503
+ shortcut: 'Modifier+Z',
504
+ label: L._('Cancel edits'),
505
+ },
506
+ PREVIEW: {
507
+ shortcut: 'Modifier+E',
508
+ label: L._('Back to preview'),
509
+ },
510
+ SAVE: {
511
+ shortcut: 'Modifier+S',
512
+ label: L._('Save current edits'),
513
+ },
514
+ },
515
+
516
+ displayLabel: function (action, withKbdTag = true) {
517
+ let { shortcut, label } = this.SHORTCUTS[action]
518
+ const modifier = this.isMacOS ? 'Cmd' : 'Ctrl'
519
+ shortcut = shortcut.replace('Modifier', modifier)
520
+ if (withKbdTag) {
521
+ shortcut = shortcut
522
+ .split('+')
523
+ .map((el) => `<kbd>${el}</kbd>`)
524
+ .join('+')
525
+ label += ` ${shortcut}`
526
+ } else {
527
+ label += ` (${shortcut})`
528
+ }
529
+ return label
530
+ },
531
+
532
+ initialize: function (map) {
533
+ this.map = map
534
+ this.box = L.DomUtil.create(
535
+ 'div',
536
+ 'umap-help-box with-transition dark',
537
+ document.body
538
+ )
539
+ const closeButton = L.DomUtil.createButton(
540
+ 'umap-close-link',
541
+ this.box,
542
+ '',
543
+ this.hide,
544
+ this
545
+ )
546
+ L.DomUtil.add('i', 'umap-close-icon', closeButton)
547
+ const label = L.DomUtil.create('span', '', closeButton)
548
+ label.title = label.textContent = L._('Close')
549
+ this.content = L.DomUtil.create('div', 'umap-help-content', this.box)
550
+ this.isMacOS = /mac/i.test(
551
+ navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform
552
+ )
553
+ },
554
+
555
+ onKeyDown: function (e) {
556
+ const key = e.keyCode,
557
+ ESC = 27
558
+ if (key === ESC) {
559
+ this.hide()
560
+ }
561
+ },
562
+
563
+ show: function () {
564
+ this.content.innerHTML = ''
565
+ for (let i = 0, name; i < arguments.length; i++) {
566
+ name = arguments[i]
567
+ L.DomUtil.add('div', 'umap-help-entry', this.content, this.resolve(name))
568
+ }
569
+ L.DomUtil.addClass(document.body, 'umap-help-on')
570
+ },
571
+
572
+ hide: function () {
573
+ L.DomUtil.removeClass(document.body, 'umap-help-on')
574
+ },
575
+
576
+ visible: function () {
577
+ return L.DomUtil.hasClass(document.body, 'umap-help-on')
578
+ },
579
+
580
+ resolve: function (name) {
581
+ return typeof this[name] === 'function' ? this[name]() : this[name]
582
+ },
583
+
584
+ button: function (container, entries, classname) {
585
+ const helpButton = L.DomUtil.createButton(
586
+ classname || 'umap-help-button',
587
+ container,
588
+ L._('Help')
589
+ )
590
+ if (entries) {
591
+ L.DomEvent.on(helpButton, 'click', L.DomEvent.stop).on(
592
+ helpButton,
593
+ 'click',
594
+ function (e) {
595
+ const args = typeof entries === 'string' ? [entries] : entries
596
+ this.show.apply(this, args)
597
+ },
598
+ this
599
+ )
600
+ }
601
+ return helpButton
602
+ },
603
+
604
+ link: function (container, entries) {
605
+ const helpButton = this.button(container, entries, 'umap-help-link')
606
+ helpButton.textContent = L._('Help')
607
+ return helpButton
608
+ },
609
+
610
+ edit: function () {
611
+ const container = L.DomUtil.create('div', ''),
612
+ self = this,
613
+ title = L.DomUtil.create('h3', '', container),
614
+ actionsContainer = L.DomUtil.create('ul', 'umap-edit-actions', container)
615
+ const addAction = (action) => {
616
+ const actionContainer = L.DomUtil.add('li', '', actionsContainer)
617
+ L.DomUtil.add('i', action.options.className, actionContainer),
618
+ L.DomUtil.add('span', '', actionContainer, action.options.tooltip)
619
+ L.DomEvent.on(actionContainer, 'click', action.addHooks, action)
620
+ L.DomEvent.on(actionContainer, 'click', self.hide, self)
621
+ }
622
+ title.textContent = L._('Where do we go from here?')
623
+ for (const id in this.map.helpMenuActions) {
624
+ addAction(this.map.helpMenuActions[id])
625
+ }
626
+ return container
627
+ },
628
+
629
+ importFormats: function () {
630
+ const container = L.DomUtil.create('div')
631
+ L.DomUtil.add('h3', '', container, 'GeojSON')
632
+ L.DomUtil.add('p', '', container, L._('All properties are imported.'))
633
+ L.DomUtil.add('h3', '', container, 'GPX')
634
+ L.DomUtil.add('p', '', container, `${L._('Properties imported:')}name, desc`)
635
+ L.DomUtil.add('h3', '', container, 'KML')
636
+ L.DomUtil.add('p', '', container, `${L._('Properties imported:')}name, description`)
637
+ L.DomUtil.add('h3', '', container, 'CSV')
638
+ L.DomUtil.add(
639
+ 'p',
640
+ '',
641
+ container,
642
+ L._(
643
+ 'Comma, tab or semi-colon separated values. SRS WGS84 is implied. Only Point geometries are imported. The import will look at the column headers for any mention of «lat» and «lon» at the begining of the header, case insensitive. All other column are imported as properties.'
644
+ )
645
+ )
646
+ L.DomUtil.add('h3', '', container, 'uMap')
647
+ L.DomUtil.add(
648
+ 'p',
649
+ '',
650
+ container,
651
+ L._('Imports all umap data, including layers and settings.')
652
+ )
653
+ return container
654
+ },
655
+
656
+ textFormatting: function () {
657
+ const container = L.DomUtil.create('div'),
658
+ title = L.DomUtil.add('h3', '', container, L._('Text formatting')),
659
+ elements = L.DomUtil.create('ul', '', container)
660
+ L.DomUtil.add('li', '', elements, L._('*single star for italic*'))
661
+ L.DomUtil.add('li', '', elements, L._('**double star for bold**'))
662
+ L.DomUtil.add('li', '', elements, L._('# one hash for main heading'))
663
+ L.DomUtil.add('li', '', elements, L._('## two hashes for second heading'))
664
+ L.DomUtil.add('li', '', elements, L._('### three hashes for third heading'))
665
+ L.DomUtil.add('li', '', elements, L._('Simple link: [[http://example.com]]'))
666
+ L.DomUtil.add(
667
+ 'li',
668
+ '',
669
+ elements,
670
+ L._('Link with text: [[http://example.com|text of the link]]')
671
+ )
672
+ L.DomUtil.add('li', '', elements, L._('Image: {{http://image.url.com}}'))
673
+ L.DomUtil.add(
674
+ 'li',
675
+ '',
676
+ elements,
677
+ L._('Image with custom width (in px): {{http://image.url.com|width}}')
678
+ )
679
+ L.DomUtil.add('li', '', elements, L._('Iframe: {{{http://iframe.url.com}}}'))
680
+ L.DomUtil.add(
681
+ 'li',
682
+ '',
683
+ elements,
684
+ L._('Iframe with custom height (in px): {{{http://iframe.url.com|height}}}')
685
+ )
686
+ L.DomUtil.add(
687
+ 'li',
688
+ '',
689
+ elements,
690
+ L._(
691
+ 'Iframe with custom height and width (in px): {{{http://iframe.url.com|height*width}}}'
692
+ )
693
+ )
694
+ L.DomUtil.add('li', '', elements, L._('--- for a horizontal rule'))
695
+ return container
696
+ },
697
+
698
+ dynamicProperties: function () {
699
+ const container = L.DomUtil.create('div')
700
+ L.DomUtil.add('h3', '', container, L._('Dynamic properties'))
701
+ L.DomUtil.add(
702
+ 'p',
703
+ '',
704
+ container,
705
+ L._(
706
+ 'Use placeholders with feature properties between brackets, eg. &#123;name&#125;, they will be dynamically replaced by the corresponding values.'
707
+ )
708
+ )
709
+ return container
710
+ },
711
+
712
+ formatURL: `${L._(
713
+ 'Supported variables that will be dynamically replaced'
714
+ )}: {bbox}, {lat}, {lng}, {zoom}, {east}, {north}..., {left}, {top}..., locale, lang`,
715
+ formatIconSymbol: L._(
716
+ 'Symbol can be either a unicode character or an URL. You can use feature properties as variables: ex.: with "http://myserver.org/images/{name}.png", the {name} variable will be replaced by the "name" value of each marker.'
717
+ ),
718
+ colorValue: L._('Must be a valid CSS value (eg.: DarkBlue or #123456)'),
719
+ smoothFactor: L._(
720
+ 'How much to simplify the polyline on each zoom level (more = better performance and smoother look, less = more accurate)'
721
+ ),
722
+ dashArray: L._(
723
+ 'A comma separated list of numbers that defines the stroke dash pattern. Ex.: "5, 10, 15".'
724
+ ),
725
+ zoomTo: L._('Zoom level for automatic zooms'),
726
+ labelKey: L._(
727
+ 'The name of the property to use as feature label (eg.: "nom"). You can also use properties inside brackets to use more than one or mix with static content (eg.: "{name} in {place}")'
728
+ ),
729
+ stroke: L._('Whether to display or not polygons paths.'),
730
+ fill: L._('Whether to fill polygons with color.'),
731
+ fillColor: L._('Optional. Same as color if not set.'),
732
+ shortCredit: L._('Will be displayed in the bottom right corner of the map'),
733
+ longCredit: L._('Will be visible in the caption of the map'),
734
+ permanentCredit: L._(
735
+ 'Will be permanently visible in the bottom left corner of the map'
736
+ ),
737
+ sortKey: L._(
738
+ 'Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'
739
+ ),
740
+ slugKey: L._('The name of the property to use as feature unique identifier.'),
741
+ filterKey: L._('Comma separated list of properties to use when filtering features'),
742
+ facetKey: L._(
743
+ 'Comma separated list of properties to use for facet search (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key)'
744
+ ),
745
+ interactive: L._(
746
+ 'If false, the polygon or line will act as a part of the underlying map.'
747
+ ),
748
+ outlink: L._('Define link to open in a new window on polygon click.'),
749
+ dynamicRemoteData: L._('Fetch data each time map view changes.'),
750
+ proxyRemoteData: L._("To use if remote server doesn't allow cross domain (slower)"),
751
+ browsable: L._(
752
+ 'Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…'
753
+ ),
754
+ })
755
+
756
+ L.U.Orderable = L.Evented.extend({
757
+ options: {
758
+ selector: 'li',
759
+ color: '#374E75',
760
+ },
761
+
762
+ initialize: function (parent, options) {
763
+ L.Util.setOptions(this, options)
764
+ this.parent = parent
765
+ this.src = null
766
+ this.dst = null
767
+ this.els = this.parent.querySelectorAll(this.options.selector)
768
+ for (let i = 0; i < this.els.length; i++) this.makeDraggable(this.els[i])
769
+ },
770
+
771
+ makeDraggable: function (node) {
772
+ node.draggable = true
773
+ L.DomEvent.on(node, 'dragstart', this.onDragStart, this)
774
+ L.DomEvent.on(node, 'dragenter', this.onDragEnter, this)
775
+ L.DomEvent.on(node, 'dragover', this.onDragOver, this)
776
+ L.DomEvent.on(node, 'dragleave', this.onDragLeave, this)
777
+ L.DomEvent.on(node, 'drop', this.onDrop, this)
778
+ L.DomEvent.on(node, 'dragend', this.onDragEnd, this)
779
+ },
780
+
781
+ nodeIndex: function (node) {
782
+ return Array.prototype.indexOf.call(this.parent.children, node)
783
+ },
784
+
785
+ findTarget: function (node) {
786
+ while (node) {
787
+ if (this.nodeIndex(node) !== -1) return node
788
+ node = node.parentNode
789
+ }
790
+ },
791
+
792
+ onDragStart: function (e) {
793
+ // e.target is the source node.
794
+ this.src = e.target
795
+ this.initialIndex = this.nodeIndex(this.src)
796
+ this.srcBackgroundColor = this.src.style.backgroundColor
797
+ this.src.style.backgroundColor = this.options.color
798
+ e.dataTransfer.effectAllowed = 'move'
799
+ e.dataTransfer.setData('text/html', this.src.innerHTML)
800
+ },
801
+
802
+ onDragOver: function (e) {
803
+ L.DomEvent.stop(e)
804
+ if (e.preventDefault) e.preventDefault() // Necessary. Allows us to drop.
805
+ e.dataTransfer.dropEffect = 'move'
806
+ return false
807
+ },
808
+
809
+ onDragEnter: function (e) {
810
+ L.DomEvent.stop(e)
811
+ // e.target is the current hover target.
812
+ const dst = this.findTarget(e.target)
813
+ if (!dst || dst === this.src) return
814
+ this.dst = dst
815
+ const targetIndex = this.nodeIndex(this.dst),
816
+ srcIndex = this.nodeIndex(this.src)
817
+ if (targetIndex > srcIndex) this.parent.insertBefore(this.dst, this.src)
818
+ else this.parent.insertBefore(this.src, this.dst)
819
+ },
820
+
821
+ onDragLeave: function (e) {
822
+ // e.target is previous target element.
823
+ },
824
+
825
+ onDrop: function (e) {
826
+ // e.target is current target element.
827
+ if (e.stopPropagation) e.stopPropagation() // Stops the browser from redirecting.
828
+ if (!this.dst) return
829
+ this.fire('drop', {
830
+ src: this.src,
831
+ initialIndex: this.initialIndex,
832
+ finalIndex: this.nodeIndex(this.src),
833
+ dst: this.dst,
834
+ })
835
+ return false
836
+ },
837
+
838
+ onDragEnd: function (e) {
839
+ // e.target is the source node.
840
+ this.src.style.backgroundColor = this.srcBackgroundColor
841
+ },
842
+ })
843
+
844
+ L.LatLng.prototype.isValid = function () {
845
+ return (
846
+ isFinite(this.lat) &&
847
+ Math.abs(this.lat) <= 90 &&
848
+ isFinite(this.lng) &&
849
+ Math.abs(this.lng) <= 180
850
+ )
851
+ }