@premiate/strapi-plugin-maplibre-field 1.0.6

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 @premiate/strapi-plugin-maplibre-field might be problematic. Click here for more details.

Files changed (47) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/LICENSE +23 -0
  3. package/README.md +781 -0
  4. package/dist/_chunks/de-CGU2cyif.mjs +16 -0
  5. package/dist/_chunks/de-Dq_t3Z6M.js +16 -0
  6. package/dist/_chunks/en-BxxNWf9i.mjs +16 -0
  7. package/dist/_chunks/en-CgSPA-1L.js +16 -0
  8. package/dist/_chunks/es-B_cPv3G5.mjs +16 -0
  9. package/dist/_chunks/es-Sgja1XAa.js +16 -0
  10. package/dist/_chunks/fr-B3JIzyzo.js +16 -0
  11. package/dist/_chunks/fr-Dw5wEoDC.mjs +16 -0
  12. package/dist/_chunks/index-BF5T-kqa.mjs +171 -0
  13. package/dist/_chunks/index-BNnkn7JG.mjs +1778 -0
  14. package/dist/_chunks/index-CGJogtZr.js +1799 -0
  15. package/dist/_chunks/index-nbk0hg-O.js +170 -0
  16. package/dist/_chunks/it-BgWDIXzn.js +16 -0
  17. package/dist/_chunks/it-CoUEVPt6.mjs +16 -0
  18. package/dist/admin/index.js +3 -0
  19. package/dist/admin/index.mjs +4 -0
  20. package/dist/admin/src/components/Initializer.d.ts +6 -0
  21. package/dist/admin/src/components/MapInput/basemap-control.d.ts +8 -0
  22. package/dist/admin/src/components/MapInput/credits-control.d.ts +10 -0
  23. package/dist/admin/src/components/MapInput/geocoder-control.d.ts +20 -0
  24. package/dist/admin/src/components/MapInput/index.d.ts +19 -0
  25. package/dist/admin/src/components/MapInput/layer-control.d.ts +18 -0
  26. package/dist/admin/src/components/PluginIcon.d.ts +2 -0
  27. package/dist/admin/src/hooks/usePluginConfig.d.ts +2 -0
  28. package/dist/admin/src/index.d.ts +16 -0
  29. package/dist/admin/src/mutations/mutateEditViewHook.d.ts +30 -0
  30. package/dist/admin/src/services/poi-service.d.ts +160 -0
  31. package/dist/admin/src/utils/getTrad.d.ts +2 -0
  32. package/dist/admin/src/utils/pluginId.d.ts +2 -0
  33. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  34. package/dist/server/index.js +107 -0
  35. package/dist/server/index.mjs +108 -0
  36. package/dist/server/src/bootstrap.d.ts +2 -0
  37. package/dist/server/src/config/index.d.ts +61 -0
  38. package/dist/server/src/config/schema.d.ts +58 -0
  39. package/dist/server/src/controllers/config.d.ts +7 -0
  40. package/dist/server/src/controllers/index.d.ts +8 -0
  41. package/dist/server/src/destroy.d.ts +5 -0
  42. package/dist/server/src/index.d.ts +85 -0
  43. package/dist/server/src/register.d.ts +5 -0
  44. package/dist/server/src/routes/index.d.ts +9 -0
  45. package/dist/server/src/types/config.d.ts +26 -0
  46. package/logo.png +0 -0
  47. package/package.json +99 -0
@@ -0,0 +1,1799 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const admin = require("@strapi/strapi/admin");
6
+ const MapLibreGeocoder = require("@maplibre/maplibre-gl-geocoder");
7
+ const maplibregl = require("maplibre-gl");
8
+ require("@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css");
9
+ const Map = require("react-map-gl/maplibre");
10
+ const designSystem = require("@strapi/design-system");
11
+ const index = require("./index-nbk0hg-O.js");
12
+ const pmtiles = require("pmtiles");
13
+ require("maplibre-gl/dist/maplibre-gl.css");
14
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
18
+ if (e) {
19
+ for (const k in e) {
20
+ if (k !== "default") {
21
+ const d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: () => e[k]
25
+ });
26
+ }
27
+ }
28
+ }
29
+ n.default = e;
30
+ return Object.freeze(n);
31
+ }
32
+ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
33
+ const MapLibreGeocoder__default = /* @__PURE__ */ _interopDefault(MapLibreGeocoder);
34
+ const maplibregl__default = /* @__PURE__ */ _interopDefault(maplibregl);
35
+ const Map__default = /* @__PURE__ */ _interopDefault(Map);
36
+ var __assign = function() {
37
+ __assign = Object.assign || function __assign2(t) {
38
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
39
+ s = arguments[i];
40
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
41
+ }
42
+ return t;
43
+ };
44
+ return __assign.apply(this, arguments);
45
+ };
46
+ function __rest(s, e) {
47
+ var t = {};
48
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
49
+ t[p] = s[p];
50
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
51
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
52
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
53
+ t[p[i]] = s[p[i]];
54
+ }
55
+ return t;
56
+ }
57
+ typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
58
+ var e = new Error(message);
59
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
60
+ };
61
+ var reactIs$1 = { exports: {} };
62
+ var reactIs_production_min = {};
63
+ /** @license React v16.13.1
64
+ * react-is.production.min.js
65
+ *
66
+ * Copyright (c) Facebook, Inc. and its affiliates.
67
+ *
68
+ * This source code is licensed under the MIT license found in the
69
+ * LICENSE file in the root directory of this source tree.
70
+ */
71
+ var hasRequiredReactIs_production_min;
72
+ function requireReactIs_production_min() {
73
+ if (hasRequiredReactIs_production_min) return reactIs_production_min;
74
+ hasRequiredReactIs_production_min = 1;
75
+ var b = "function" === typeof Symbol && Symbol.for, c = b ? Symbol.for("react.element") : 60103, d = b ? Symbol.for("react.portal") : 60106, e = b ? Symbol.for("react.fragment") : 60107, f = b ? Symbol.for("react.strict_mode") : 60108, g = b ? Symbol.for("react.profiler") : 60114, h = b ? Symbol.for("react.provider") : 60109, k = b ? Symbol.for("react.context") : 60110, l = b ? Symbol.for("react.async_mode") : 60111, m = b ? Symbol.for("react.concurrent_mode") : 60111, n = b ? Symbol.for("react.forward_ref") : 60112, p = b ? Symbol.for("react.suspense") : 60113, q = b ? Symbol.for("react.suspense_list") : 60120, r = b ? Symbol.for("react.memo") : 60115, t = b ? Symbol.for("react.lazy") : 60116, v = b ? Symbol.for("react.block") : 60121, w = b ? Symbol.for("react.fundamental") : 60117, x = b ? Symbol.for("react.responder") : 60118, y = b ? Symbol.for("react.scope") : 60119;
76
+ function z(a) {
77
+ if ("object" === typeof a && null !== a) {
78
+ var u = a.$$typeof;
79
+ switch (u) {
80
+ case c:
81
+ switch (a = a.type, a) {
82
+ case l:
83
+ case m:
84
+ case e:
85
+ case g:
86
+ case f:
87
+ case p:
88
+ return a;
89
+ default:
90
+ switch (a = a && a.$$typeof, a) {
91
+ case k:
92
+ case n:
93
+ case t:
94
+ case r:
95
+ case h:
96
+ return a;
97
+ default:
98
+ return u;
99
+ }
100
+ }
101
+ case d:
102
+ return u;
103
+ }
104
+ }
105
+ }
106
+ function A(a) {
107
+ return z(a) === m;
108
+ }
109
+ reactIs_production_min.AsyncMode = l;
110
+ reactIs_production_min.ConcurrentMode = m;
111
+ reactIs_production_min.ContextConsumer = k;
112
+ reactIs_production_min.ContextProvider = h;
113
+ reactIs_production_min.Element = c;
114
+ reactIs_production_min.ForwardRef = n;
115
+ reactIs_production_min.Fragment = e;
116
+ reactIs_production_min.Lazy = t;
117
+ reactIs_production_min.Memo = r;
118
+ reactIs_production_min.Portal = d;
119
+ reactIs_production_min.Profiler = g;
120
+ reactIs_production_min.StrictMode = f;
121
+ reactIs_production_min.Suspense = p;
122
+ reactIs_production_min.isAsyncMode = function(a) {
123
+ return A(a) || z(a) === l;
124
+ };
125
+ reactIs_production_min.isConcurrentMode = A;
126
+ reactIs_production_min.isContextConsumer = function(a) {
127
+ return z(a) === k;
128
+ };
129
+ reactIs_production_min.isContextProvider = function(a) {
130
+ return z(a) === h;
131
+ };
132
+ reactIs_production_min.isElement = function(a) {
133
+ return "object" === typeof a && null !== a && a.$$typeof === c;
134
+ };
135
+ reactIs_production_min.isForwardRef = function(a) {
136
+ return z(a) === n;
137
+ };
138
+ reactIs_production_min.isFragment = function(a) {
139
+ return z(a) === e;
140
+ };
141
+ reactIs_production_min.isLazy = function(a) {
142
+ return z(a) === t;
143
+ };
144
+ reactIs_production_min.isMemo = function(a) {
145
+ return z(a) === r;
146
+ };
147
+ reactIs_production_min.isPortal = function(a) {
148
+ return z(a) === d;
149
+ };
150
+ reactIs_production_min.isProfiler = function(a) {
151
+ return z(a) === g;
152
+ };
153
+ reactIs_production_min.isStrictMode = function(a) {
154
+ return z(a) === f;
155
+ };
156
+ reactIs_production_min.isSuspense = function(a) {
157
+ return z(a) === p;
158
+ };
159
+ reactIs_production_min.isValidElementType = function(a) {
160
+ return "string" === typeof a || "function" === typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" === typeof a && null !== a && (a.$$typeof === t || a.$$typeof === r || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === w || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
161
+ };
162
+ reactIs_production_min.typeOf = z;
163
+ return reactIs_production_min;
164
+ }
165
+ var reactIs_development = {};
166
+ /** @license React v16.13.1
167
+ * react-is.development.js
168
+ *
169
+ * Copyright (c) Facebook, Inc. and its affiliates.
170
+ *
171
+ * This source code is licensed under the MIT license found in the
172
+ * LICENSE file in the root directory of this source tree.
173
+ */
174
+ var hasRequiredReactIs_development;
175
+ function requireReactIs_development() {
176
+ if (hasRequiredReactIs_development) return reactIs_development;
177
+ hasRequiredReactIs_development = 1;
178
+ if (process.env.NODE_ENV !== "production") {
179
+ (function() {
180
+ var hasSymbol = typeof Symbol === "function" && Symbol.for;
181
+ var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103;
182
+ var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106;
183
+ var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 60107;
184
+ var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for("react.strict_mode") : 60108;
185
+ var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 60114;
186
+ var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 60109;
187
+ var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 60110;
188
+ var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 60111;
189
+ var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 60111;
190
+ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112;
191
+ var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113;
192
+ var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for("react.suspense_list") : 60120;
193
+ var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115;
194
+ var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116;
195
+ var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121;
196
+ var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 60117;
197
+ var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 60118;
198
+ var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 60119;
199
+ function isValidElementType(type) {
200
+ return typeof type === "string" || typeof type === "function" || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
201
+ type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === "object" && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);
202
+ }
203
+ function typeOf(object) {
204
+ if (typeof object === "object" && object !== null) {
205
+ var $$typeof = object.$$typeof;
206
+ switch ($$typeof) {
207
+ case REACT_ELEMENT_TYPE:
208
+ var type = object.type;
209
+ switch (type) {
210
+ case REACT_ASYNC_MODE_TYPE:
211
+ case REACT_CONCURRENT_MODE_TYPE:
212
+ case REACT_FRAGMENT_TYPE:
213
+ case REACT_PROFILER_TYPE:
214
+ case REACT_STRICT_MODE_TYPE:
215
+ case REACT_SUSPENSE_TYPE:
216
+ return type;
217
+ default:
218
+ var $$typeofType = type && type.$$typeof;
219
+ switch ($$typeofType) {
220
+ case REACT_CONTEXT_TYPE:
221
+ case REACT_FORWARD_REF_TYPE:
222
+ case REACT_LAZY_TYPE:
223
+ case REACT_MEMO_TYPE:
224
+ case REACT_PROVIDER_TYPE:
225
+ return $$typeofType;
226
+ default:
227
+ return $$typeof;
228
+ }
229
+ }
230
+ case REACT_PORTAL_TYPE:
231
+ return $$typeof;
232
+ }
233
+ }
234
+ return void 0;
235
+ }
236
+ var AsyncMode = REACT_ASYNC_MODE_TYPE;
237
+ var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;
238
+ var ContextConsumer = REACT_CONTEXT_TYPE;
239
+ var ContextProvider = REACT_PROVIDER_TYPE;
240
+ var Element = REACT_ELEMENT_TYPE;
241
+ var ForwardRef = REACT_FORWARD_REF_TYPE;
242
+ var Fragment = REACT_FRAGMENT_TYPE;
243
+ var Lazy = REACT_LAZY_TYPE;
244
+ var Memo = REACT_MEMO_TYPE;
245
+ var Portal = REACT_PORTAL_TYPE;
246
+ var Profiler = REACT_PROFILER_TYPE;
247
+ var StrictMode = REACT_STRICT_MODE_TYPE;
248
+ var Suspense = REACT_SUSPENSE_TYPE;
249
+ var hasWarnedAboutDeprecatedIsAsyncMode = false;
250
+ function isAsyncMode(object) {
251
+ {
252
+ if (!hasWarnedAboutDeprecatedIsAsyncMode) {
253
+ hasWarnedAboutDeprecatedIsAsyncMode = true;
254
+ console["warn"]("The ReactIs.isAsyncMode() alias has been deprecated, and will be removed in React 17+. Update your code to use ReactIs.isConcurrentMode() instead. It has the exact same API.");
255
+ }
256
+ }
257
+ return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;
258
+ }
259
+ function isConcurrentMode(object) {
260
+ return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;
261
+ }
262
+ function isContextConsumer(object) {
263
+ return typeOf(object) === REACT_CONTEXT_TYPE;
264
+ }
265
+ function isContextProvider(object) {
266
+ return typeOf(object) === REACT_PROVIDER_TYPE;
267
+ }
268
+ function isElement(object) {
269
+ return typeof object === "object" && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
270
+ }
271
+ function isForwardRef(object) {
272
+ return typeOf(object) === REACT_FORWARD_REF_TYPE;
273
+ }
274
+ function isFragment(object) {
275
+ return typeOf(object) === REACT_FRAGMENT_TYPE;
276
+ }
277
+ function isLazy(object) {
278
+ return typeOf(object) === REACT_LAZY_TYPE;
279
+ }
280
+ function isMemo(object) {
281
+ return typeOf(object) === REACT_MEMO_TYPE;
282
+ }
283
+ function isPortal(object) {
284
+ return typeOf(object) === REACT_PORTAL_TYPE;
285
+ }
286
+ function isProfiler(object) {
287
+ return typeOf(object) === REACT_PROFILER_TYPE;
288
+ }
289
+ function isStrictMode(object) {
290
+ return typeOf(object) === REACT_STRICT_MODE_TYPE;
291
+ }
292
+ function isSuspense(object) {
293
+ return typeOf(object) === REACT_SUSPENSE_TYPE;
294
+ }
295
+ reactIs_development.AsyncMode = AsyncMode;
296
+ reactIs_development.ConcurrentMode = ConcurrentMode;
297
+ reactIs_development.ContextConsumer = ContextConsumer;
298
+ reactIs_development.ContextProvider = ContextProvider;
299
+ reactIs_development.Element = Element;
300
+ reactIs_development.ForwardRef = ForwardRef;
301
+ reactIs_development.Fragment = Fragment;
302
+ reactIs_development.Lazy = Lazy;
303
+ reactIs_development.Memo = Memo;
304
+ reactIs_development.Portal = Portal;
305
+ reactIs_development.Profiler = Profiler;
306
+ reactIs_development.StrictMode = StrictMode;
307
+ reactIs_development.Suspense = Suspense;
308
+ reactIs_development.isAsyncMode = isAsyncMode;
309
+ reactIs_development.isConcurrentMode = isConcurrentMode;
310
+ reactIs_development.isContextConsumer = isContextConsumer;
311
+ reactIs_development.isContextProvider = isContextProvider;
312
+ reactIs_development.isElement = isElement;
313
+ reactIs_development.isForwardRef = isForwardRef;
314
+ reactIs_development.isFragment = isFragment;
315
+ reactIs_development.isLazy = isLazy;
316
+ reactIs_development.isMemo = isMemo;
317
+ reactIs_development.isPortal = isPortal;
318
+ reactIs_development.isProfiler = isProfiler;
319
+ reactIs_development.isStrictMode = isStrictMode;
320
+ reactIs_development.isSuspense = isSuspense;
321
+ reactIs_development.isValidElementType = isValidElementType;
322
+ reactIs_development.typeOf = typeOf;
323
+ })();
324
+ }
325
+ return reactIs_development;
326
+ }
327
+ if (process.env.NODE_ENV === "production") {
328
+ reactIs$1.exports = requireReactIs_production_min();
329
+ } else {
330
+ reactIs$1.exports = requireReactIs_development();
331
+ }
332
+ var reactIsExports = reactIs$1.exports;
333
+ var reactIs = reactIsExports;
334
+ var FORWARD_REF_STATICS = {
335
+ "$$typeof": true,
336
+ render: true,
337
+ defaultProps: true,
338
+ displayName: true,
339
+ propTypes: true
340
+ };
341
+ var MEMO_STATICS = {
342
+ "$$typeof": true,
343
+ compare: true,
344
+ defaultProps: true,
345
+ displayName: true,
346
+ propTypes: true,
347
+ type: true
348
+ };
349
+ var TYPE_STATICS = {};
350
+ TYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;
351
+ TYPE_STATICS[reactIs.Memo] = MEMO_STATICS;
352
+ function invariant(condition, message, Err) {
353
+ if (Err === void 0) {
354
+ Err = Error;
355
+ }
356
+ if (!condition) {
357
+ throw new Err(message);
358
+ }
359
+ }
360
+ var defaultErrorHandler = function(error) {
361
+ if (process.env.NODE_ENV !== "production") {
362
+ console.error(error);
363
+ }
364
+ };
365
+ var defaultWarnHandler = function(warning) {
366
+ if (process.env.NODE_ENV !== "production") {
367
+ console.warn(warning);
368
+ }
369
+ };
370
+ var DEFAULT_INTL_CONFIG = {
371
+ formats: {},
372
+ messages: {},
373
+ timeZone: void 0,
374
+ defaultLocale: "en",
375
+ defaultFormats: {},
376
+ fallbackOnEmptyString: true,
377
+ onError: defaultErrorHandler,
378
+ onWarn: defaultWarnHandler
379
+ };
380
+ function invariantIntlContext(intl) {
381
+ invariant(intl, "[React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.");
382
+ }
383
+ __assign(__assign({}, DEFAULT_INTL_CONFIG), { textComponent: React__namespace.Fragment });
384
+ var IntlContext = typeof window !== "undefined" && !window.__REACT_INTL_BYPASS_GLOBAL_CONTEXT__ ? window.__REACT_INTL_CONTEXT__ || (window.__REACT_INTL_CONTEXT__ = React__namespace.createContext(null)) : React__namespace.createContext(null);
385
+ IntlContext.Consumer;
386
+ IntlContext.Provider;
387
+ var Context = IntlContext;
388
+ function useIntl() {
389
+ var intl = React__namespace.useContext(Context);
390
+ invariantIntlContext(intl);
391
+ return intl;
392
+ }
393
+ var DisplayName;
394
+ (function(DisplayName2) {
395
+ DisplayName2["formatDate"] = "FormattedDate";
396
+ DisplayName2["formatTime"] = "FormattedTime";
397
+ DisplayName2["formatNumber"] = "FormattedNumber";
398
+ DisplayName2["formatList"] = "FormattedList";
399
+ DisplayName2["formatDisplayName"] = "FormattedDisplayName";
400
+ })(DisplayName || (DisplayName = {}));
401
+ var DisplayNameParts;
402
+ (function(DisplayNameParts2) {
403
+ DisplayNameParts2["formatDate"] = "FormattedDateParts";
404
+ DisplayNameParts2["formatTime"] = "FormattedTimeParts";
405
+ DisplayNameParts2["formatNumber"] = "FormattedNumberParts";
406
+ DisplayNameParts2["formatList"] = "FormattedListParts";
407
+ })(DisplayNameParts || (DisplayNameParts = {}));
408
+ function createFormattedDateTimePartsComponent(name) {
409
+ var ComponentParts = function(props) {
410
+ var intl = useIntl();
411
+ var value = props.value, children = props.children, formatProps = __rest(props, ["value", "children"]);
412
+ var date = typeof value === "string" ? new Date(value || 0) : value;
413
+ var formattedParts = name === "formatDate" ? intl.formatDateToParts(date, formatProps) : intl.formatTimeToParts(date, formatProps);
414
+ return children(formattedParts);
415
+ };
416
+ ComponentParts.displayName = DisplayNameParts[name];
417
+ return ComponentParts;
418
+ }
419
+ function createFormattedComponent(name) {
420
+ var Component = function(props) {
421
+ var intl = useIntl();
422
+ var value = props.value, children = props.children, formatProps = __rest(
423
+ props,
424
+ ["value", "children"]
425
+ );
426
+ var formattedValue = intl[name](value, formatProps);
427
+ if (typeof children === "function") {
428
+ return children(formattedValue);
429
+ }
430
+ var Text = intl.textComponent || React__namespace.Fragment;
431
+ return React__namespace.createElement(Text, null, formattedValue);
432
+ };
433
+ Component.displayName = DisplayName[name];
434
+ return Component;
435
+ }
436
+ createFormattedComponent("formatDate");
437
+ createFormattedComponent("formatTime");
438
+ createFormattedComponent("formatNumber");
439
+ createFormattedComponent("formatList");
440
+ createFormattedComponent("formatDisplayName");
441
+ createFormattedDateTimePartsComponent("formatDate");
442
+ createFormattedDateTimePartsComponent("formatTime");
443
+ const DEFAULT_CONFIG = {
444
+ mapStyles: [
445
+ {
446
+ id: "default",
447
+ name: "Default",
448
+ url: "https://demotiles.maplibre.org/style.json",
449
+ isDefault: true
450
+ }
451
+ ],
452
+ defaultZoom: 4.5,
453
+ defaultCenter: [0, 0],
454
+ // Null Island - fallback if not configured
455
+ geocodingProvider: "nominatim",
456
+ nominatimUrl: "https://nominatim.openstreetmap.org"
457
+ };
458
+ const usePluginConfig = () => {
459
+ const [config, setConfig] = React.useState(DEFAULT_CONFIG);
460
+ const [loading, setLoading] = React.useState(true);
461
+ const { get } = admin.useFetchClient();
462
+ React.useEffect(() => {
463
+ const fetchConfig = async () => {
464
+ try {
465
+ const response = await get("/maplibre-field/config");
466
+ console.log("[MapLibre Hook] Fetched config from API:", response.data);
467
+ if (response.data) {
468
+ setConfig({ ...DEFAULT_CONFIG, ...response.data });
469
+ }
470
+ } catch (error) {
471
+ console.error("[MapLibre Hook] Failed to fetch config:", error);
472
+ } finally {
473
+ setLoading(false);
474
+ }
475
+ };
476
+ fetchConfig();
477
+ }, [get]);
478
+ if (loading) {
479
+ console.log("[MapLibre Hook] Loading config...");
480
+ }
481
+ return config;
482
+ };
483
+ const USER_AGENT$2 = "strapi-plugin-maplibre-field/1.0.0 (Strapi CMS)";
484
+ function createLocationFeature(coordinates, properties = {}) {
485
+ const cleanProperties = Object.fromEntries(
486
+ Object.entries(properties).filter(([, v]) => v != null && v !== "")
487
+ );
488
+ return {
489
+ type: "Feature",
490
+ geometry: {
491
+ type: "Point",
492
+ coordinates
493
+ },
494
+ properties: cleanProperties
495
+ };
496
+ }
497
+ function calculateDistance(coord1, coord2) {
498
+ const R = 6371e3;
499
+ const φ1 = coord1[1] * Math.PI / 180;
500
+ const φ2 = coord2[1] * Math.PI / 180;
501
+ const Δφ = (coord2[1] - coord1[1]) * Math.PI / 180;
502
+ const Δλ = (coord2[0] - coord1[0]) * Math.PI / 180;
503
+ const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
504
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
505
+ return R * c;
506
+ }
507
+ async function queryCustomAPI(apiUrl, searchQuery) {
508
+ try {
509
+ console.log(`[POI Service] Fetching from: ${apiUrl}`);
510
+ const response = await fetch(apiUrl);
511
+ if (!response.ok) {
512
+ console.error(`[POI Service] HTTP error for ${apiUrl}: ${response.status} ${response.statusText}`);
513
+ throw new Error(`HTTP error! status: ${response.status}`);
514
+ }
515
+ const data = await response.json();
516
+ if (!data || data.type !== "FeatureCollection" || !Array.isArray(data.features)) {
517
+ console.error(`[POI Service] Invalid GeoJSON from ${apiUrl}`);
518
+ throw new Error("Invalid GeoJSON response format");
519
+ }
520
+ console.log(`[POI Service] Loaded ${data.features.length} features from ${apiUrl}`);
521
+ let features = data.features;
522
+ if (searchQuery && searchQuery.trim()) {
523
+ const query = searchQuery.toLowerCase();
524
+ features = features.filter((feature) => {
525
+ const name = feature.properties?.name;
526
+ return name && name.toLowerCase().includes(query);
527
+ });
528
+ }
529
+ return features;
530
+ } catch (error) {
531
+ console.error(`[POI Service] Failed to load from ${apiUrl}:`, error);
532
+ return [];
533
+ }
534
+ }
535
+ async function queryNominatim(lat, lng, radius, nominatimUrl) {
536
+ try {
537
+ const url = `${nominatimUrl}/reverse?format=jsonv2&lat=${lat}&lon=${lng}&zoom=18&addressdetails=1`;
538
+ console.log("[Nominatim] Querying:", url);
539
+ const response = await fetch(url, {
540
+ headers: {
541
+ "User-Agent": USER_AGENT$2
542
+ }
543
+ });
544
+ if (!response.ok) {
545
+ throw new Error(`HTTP error! status: ${response.status}`);
546
+ }
547
+ const data = await response.json();
548
+ console.log("[Nominatim] Response:", data);
549
+ if (!data) {
550
+ console.log("[Nominatim] No data returned");
551
+ return [];
552
+ }
553
+ const coordinates = [parseFloat(data.lon), parseFloat(data.lat)];
554
+ const distance = calculateDistance([lng, lat], coordinates);
555
+ console.log("[Nominatim] Distance calculated:", distance, "meters (radius:", radius, "m)");
556
+ console.log("[Nominatim] Click coords:", [lng, lat], "Result coords:", coordinates);
557
+ if (distance > radius) {
558
+ console.log("[Nominatim] POI outside radius, rejecting");
559
+ return [];
560
+ }
561
+ let poiName = data.name || data.display_name || "Unknown Location";
562
+ if (data.namedetails) {
563
+ poiName = data.namedetails.name || poiName;
564
+ }
565
+ console.log("[Nominatim] POI found:", poiName, "type:", data.type || data.class);
566
+ const poi = {
567
+ id: `nominatim-${data.place_id || Date.now()}`,
568
+ name: poiName,
569
+ type: data.type || data.class || "address",
570
+ coordinates,
571
+ address: data.display_name || "",
572
+ distance,
573
+ metadata: {
574
+ osm_id: data.osm_id,
575
+ osm_type: data.osm_type,
576
+ place_id: data.place_id,
577
+ addresstype: data.addresstype,
578
+ class: data.class,
579
+ category: data.category
580
+ },
581
+ source: "nominatim"
582
+ };
583
+ return [poi];
584
+ } catch (error) {
585
+ console.error("Nominatim query error:", error);
586
+ return [];
587
+ }
588
+ }
589
+ function geoJSONFeatureToPOI(feature, clickCoords, mapName, layerId) {
590
+ if (!feature.geometry || feature.geometry.type !== "Point") {
591
+ return null;
592
+ }
593
+ const coordinates = feature.geometry.coordinates;
594
+ const properties = feature.properties || {};
595
+ const name = properties.name || "Unnamed Location";
596
+ const poi = {
597
+ id: feature.id?.toString() || `custom-${Date.now()}-${Math.random()}`,
598
+ name,
599
+ type: properties.type || properties.sport || properties.leisure || "poi",
600
+ coordinates,
601
+ address: properties.address || "",
602
+ // Leave empty if not provided
603
+ metadata: properties,
604
+ source: "custom",
605
+ mapName,
606
+ // Include the custom map name
607
+ layerId
608
+ // Include the layer ID
609
+ };
610
+ if (clickCoords) {
611
+ poi.distance = calculateDistance(clickCoords, coordinates);
612
+ }
613
+ return poi;
614
+ }
615
+ function filterByDistance(features, clickCoords, radius) {
616
+ return features.filter((feature) => {
617
+ if (!feature.geometry || feature.geometry.type !== "Point") {
618
+ return false;
619
+ }
620
+ const featureCoords = feature.geometry.coordinates;
621
+ const distance = calculateDistance(clickCoords, featureCoords);
622
+ return distance <= radius;
623
+ });
624
+ }
625
+ function findNearestPOI(clickCoordinates, pois) {
626
+ if (!pois || pois.length === 0) {
627
+ return null;
628
+ }
629
+ let nearest = null;
630
+ let minDistance = Infinity;
631
+ for (const poi of pois) {
632
+ const distance = poi.distance ?? calculateDistance(clickCoordinates, poi.coordinates);
633
+ if (distance < minDistance) {
634
+ minDistance = distance;
635
+ nearest = { ...poi, distance };
636
+ }
637
+ }
638
+ return nearest;
639
+ }
640
+ async function searchPOIsForGeocoder(query, config) {
641
+ const results = [];
642
+ try {
643
+ if (config.customApiUrl) {
644
+ try {
645
+ const customFeatures = await queryCustomAPI(config.customApiUrl, query);
646
+ const customPOIs = customFeatures.map((feature) => geoJSONFeatureToPOI(feature, void 0, config.mapName, config.layerId)).filter((poi) => poi !== null).slice(0, 5);
647
+ results.push(...customPOIs);
648
+ } catch (error) {
649
+ console.warn("Custom API search failed:", error);
650
+ }
651
+ }
652
+ return results;
653
+ } catch (error) {
654
+ console.error("Search POIs error:", error);
655
+ return results;
656
+ }
657
+ }
658
+ async function searchNearbyPOIsForSnap(lat, lng, config) {
659
+ const results = [];
660
+ try {
661
+ const nominatimPOIs = await queryNominatim(
662
+ lat,
663
+ lng,
664
+ config.radius,
665
+ config.nominatimUrl
666
+ );
667
+ results.push(...nominatimPOIs);
668
+ if (config.customApiUrl) {
669
+ try {
670
+ const customFeatures = await queryCustomAPI(config.customApiUrl);
671
+ const nearbyFeatures = filterByDistance(
672
+ customFeatures,
673
+ [lng, lat],
674
+ config.radius
675
+ );
676
+ const customPOIs = nearbyFeatures.map((feature) => geoJSONFeatureToPOI(feature, [lng, lat], config.mapName, config.layerId)).filter((poi) => poi !== null);
677
+ results.push(...customPOIs);
678
+ } catch (error) {
679
+ console.warn("Custom API query failed, continuing with Nominatim only:", error);
680
+ }
681
+ }
682
+ return results;
683
+ } catch (error) {
684
+ console.error("Search nearby POIs error:", error);
685
+ return results;
686
+ }
687
+ }
688
+ async function queryPOIsForViewport(bounds, center, maxDisplay, config) {
689
+ const results = [];
690
+ try {
691
+ if (config.customApiUrl) {
692
+ try {
693
+ const customFeatures = await queryCustomAPI(config.customApiUrl);
694
+ const viewportFeatures = customFeatures.filter((feature) => {
695
+ if (!feature.geometry || feature.geometry.type !== "Point") {
696
+ return false;
697
+ }
698
+ const [lng, lat] = feature.geometry.coordinates;
699
+ return lat >= bounds.south && lat <= bounds.north && lng >= bounds.west && lng <= bounds.east;
700
+ });
701
+ const customPOIs = viewportFeatures.map((feature) => geoJSONFeatureToPOI(feature, center, config.mapName, config.layerId)).filter((poi) => poi !== null);
702
+ results.push(...customPOIs);
703
+ } catch (error) {
704
+ console.warn("Custom API viewport query failed:", error);
705
+ }
706
+ }
707
+ results.sort((a, b) => {
708
+ const distA = a.distance ?? calculateDistance(center, a.coordinates);
709
+ const distB = b.distance ?? calculateDistance(center, b.coordinates);
710
+ return distA - distB;
711
+ });
712
+ return results.slice(0, maxDisplay);
713
+ } catch (error) {
714
+ console.error("Query POIs for viewport error:", error);
715
+ return results;
716
+ }
717
+ }
718
+ const USER_AGENT$1 = "strapi-plugin-maplibre-field/1.0.0 (Strapi CMS)";
719
+ const GeocoderControl = ({
720
+ mapRef,
721
+ position = "top-left",
722
+ onResult
723
+ }) => {
724
+ const geocoderRef = React.useRef(null);
725
+ const config = usePluginConfig();
726
+ React.useEffect(() => {
727
+ if (!mapRef.current) return;
728
+ const map = mapRef.current.getMap();
729
+ if (!map || geocoderRef.current) return;
730
+ const geocoderApi = {
731
+ forwardGeocode: async (geocoderConfig) => {
732
+ const query = geocoderConfig.query;
733
+ if (typeof query !== "string" || !query.trim()) {
734
+ return { type: "FeatureCollection", features: [] };
735
+ }
736
+ try {
737
+ const results = [];
738
+ if (config.poiSources && config.poiSearchEnabled) {
739
+ const enabledSources = config.poiSources.filter((source) => source.enabled !== false);
740
+ for (const source of enabledSources) {
741
+ try {
742
+ const customPOIs = await searchPOIsForGeocoder(
743
+ query,
744
+ {
745
+ nominatimUrl: config.nominatimUrl || "https://nominatim.openstreetmap.org",
746
+ customApiUrl: source.apiUrl,
747
+ mapName: source.name,
748
+ radius: 100,
749
+ categories: []
750
+ }
751
+ );
752
+ const customFeatures = customPOIs.filter((poi) => poi.source === "custom").slice(0, 5).map((poi) => ({
753
+ type: "Feature",
754
+ geometry: {
755
+ type: "Point",
756
+ coordinates: poi.coordinates
757
+ },
758
+ place_name: poi.name,
759
+ properties: {
760
+ ...poi,
761
+ source: "custom",
762
+ poi_source_id: source.id
763
+ // For color lookup in render function
764
+ },
765
+ text: poi.name,
766
+ place_type: ["poi"],
767
+ center: poi.coordinates
768
+ }));
769
+ results.push(...customFeatures);
770
+ } catch (error) {
771
+ console.warn(`Custom API search failed for ${source.name}, continuing:`, error);
772
+ }
773
+ }
774
+ }
775
+ const nominatimResponse = await fetch(
776
+ `${config.nominatimUrl}/search?q=${encodeURIComponent(query)}&format=json&addressdetails=1&limit=5`,
777
+ {
778
+ headers: {
779
+ "User-Agent": USER_AGENT$1
780
+ }
781
+ }
782
+ );
783
+ if (nominatimResponse.ok) {
784
+ const nominatimData = await nominatimResponse.json();
785
+ const nominatimFeatures = nominatimData.map((result) => ({
786
+ type: "Feature",
787
+ geometry: {
788
+ type: "Point",
789
+ coordinates: [parseFloat(result.lon), parseFloat(result.lat)]
790
+ },
791
+ place_name: result.display_name,
792
+ properties: { ...result, source: "nominatim" },
793
+ text: result.display_name,
794
+ place_type: ["place"],
795
+ center: [parseFloat(result.lon), parseFloat(result.lat)]
796
+ }));
797
+ results.push(...nominatimFeatures);
798
+ }
799
+ return {
800
+ type: "FeatureCollection",
801
+ features: results
802
+ };
803
+ } catch (error) {
804
+ console.error("Geocoding error:", error);
805
+ return { type: "FeatureCollection", features: [] };
806
+ }
807
+ },
808
+ maplibregl: maplibregl__default.default
809
+ };
810
+ const geocoderOptions = {
811
+ marker: false,
812
+ showResultsWhileTyping: false,
813
+ // Require Enter key for Nominatim policy compliance
814
+ render: (item) => {
815
+ const properties = "properties" in item ? item.properties : void 0;
816
+ const source = properties?.source;
817
+ let dotColor = "#6c757d";
818
+ if (source === "custom") {
819
+ const poiSourceId = properties?.poi_source_id;
820
+ const poiSource = config.poiSources?.find((s) => s.id === poiSourceId);
821
+ dotColor = poiSource?.color || "#cc0000";
822
+ }
823
+ const escapeHtml = (str) => {
824
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
825
+ };
826
+ const placeName = "place_name" in item ? item.place_name : void 0;
827
+ const displayText = escapeHtml(item.text || placeName || "");
828
+ return `
829
+ <div class="maplibregl-ctrl-geocoder--suggestion">
830
+ <div class="maplibregl-ctrl-geocoder--suggestion-icon">
831
+ <span style="display:inline-block;width:10px;height:10px;border-radius:50%;background-color:${dotColor};border:2px solid #ffffff;box-shadow:0 0 0 1px rgba(0,0,0,0.1);"></span>
832
+ </div>
833
+ <div class="maplibregl-ctrl-geocoder--suggestion-info">
834
+ <div class="maplibregl-ctrl-geocoder--suggestion-title">
835
+ ${displayText}
836
+ </div>
837
+ </div>
838
+ </div>
839
+ `;
840
+ }
841
+ };
842
+ const geocoder = new MapLibreGeocoder__default.default(geocoderApi, geocoderOptions);
843
+ if (onResult) {
844
+ geocoder.on("result", (evt) => {
845
+ onResult(evt);
846
+ });
847
+ }
848
+ map.addControl(geocoder, position);
849
+ geocoderRef.current = geocoder;
850
+ return () => {
851
+ if (geocoderRef.current && map) {
852
+ try {
853
+ map.removeControl(geocoderRef.current);
854
+ } catch (error) {
855
+ console.warn("Error removing geocoder control:", error);
856
+ }
857
+ geocoderRef.current = null;
858
+ }
859
+ };
860
+ }, [mapRef, position, onResult, config.nominatimUrl]);
861
+ return null;
862
+ };
863
+ class BasemapControl {
864
+ _map;
865
+ _container;
866
+ _styles;
867
+ _currentStyleUrl;
868
+ _onStyleChange;
869
+ constructor(styles, currentStyleUrl, onStyleChange) {
870
+ this._styles = styles;
871
+ this._currentStyleUrl = currentStyleUrl;
872
+ this._onStyleChange = onStyleChange;
873
+ }
874
+ onAdd(map) {
875
+ this._map = map;
876
+ this._container = document.createElement("div");
877
+ this._container.className = "maplibregl-ctrl maplibregl-ctrl-group";
878
+ this._container.style.display = "flex";
879
+ this._container.style.flexDirection = "row";
880
+ this._styles.forEach((style, index2) => {
881
+ const button = document.createElement("button");
882
+ button.type = "button";
883
+ button.title = style.name;
884
+ button.setAttribute("aria-label", style.name);
885
+ const span = document.createElement("span");
886
+ span.textContent = style.name;
887
+ span.style.padding = "0 8px";
888
+ button.appendChild(span);
889
+ button.className = "maplibregl-ctrl-icon";
890
+ button.style.width = "auto";
891
+ button.style.height = "29px";
892
+ button.style.display = "flex";
893
+ button.style.alignItems = "center";
894
+ button.style.justifyContent = "center";
895
+ if (style.url === this._currentStyleUrl) {
896
+ button.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
897
+ button.style.fontWeight = "bold";
898
+ }
899
+ if (index2 < this._styles.length - 1) {
900
+ button.style.borderRight = "1px solid rgba(0, 0, 0, 0.1)";
901
+ }
902
+ button.onclick = () => {
903
+ const buttons = this._container?.querySelectorAll("button");
904
+ buttons?.forEach((btn, btnIndex) => {
905
+ if (btnIndex === index2) {
906
+ btn.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
907
+ btn.style.fontWeight = "bold";
908
+ } else {
909
+ btn.style.backgroundColor = "";
910
+ btn.style.fontWeight = "";
911
+ }
912
+ });
913
+ this._onStyleChange(style.url);
914
+ };
915
+ this._container.appendChild(button);
916
+ });
917
+ return this._container;
918
+ }
919
+ onRemove() {
920
+ this._container?.parentNode?.removeChild(this._container);
921
+ this._map = void 0;
922
+ }
923
+ updateCurrentStyle(styleUrl) {
924
+ this._currentStyleUrl = styleUrl;
925
+ const buttons = this._container?.querySelectorAll("button");
926
+ buttons?.forEach((button, index2) => {
927
+ const btn = button;
928
+ if (this._styles[index2].url === styleUrl) {
929
+ btn.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
930
+ btn.style.fontWeight = "bold";
931
+ } else {
932
+ btn.style.backgroundColor = "";
933
+ btn.style.fontWeight = "";
934
+ }
935
+ });
936
+ }
937
+ }
938
+ function BasemapControlComponent({
939
+ mapStyles,
940
+ currentStyleUrl,
941
+ onStyleChange
942
+ }) {
943
+ const controlRef = Map.useControl(
944
+ () => new BasemapControl(mapStyles, currentStyleUrl, onStyleChange),
945
+ {
946
+ position: "bottom-left"
947
+ }
948
+ );
949
+ React.useEffect(() => {
950
+ if (controlRef && "updateCurrentStyle" in controlRef) {
951
+ controlRef.updateCurrentStyle(currentStyleUrl);
952
+ }
953
+ }, [currentStyleUrl, controlRef]);
954
+ return null;
955
+ }
956
+ class LayerControlImpl {
957
+ _map;
958
+ _container;
959
+ _layers;
960
+ _onToggle;
961
+ constructor(layers, onToggle) {
962
+ this._layers = layers;
963
+ this._onToggle = onToggle;
964
+ }
965
+ onAdd(map) {
966
+ this._map = map;
967
+ this._container = document.createElement("div");
968
+ this._container.className = "maplibregl-ctrl maplibregl-ctrl-group";
969
+ this._container.style.padding = "0";
970
+ this._render();
971
+ return this._container;
972
+ }
973
+ onRemove() {
974
+ if (this._container && this._container.parentNode) {
975
+ this._container.parentNode.removeChild(this._container);
976
+ }
977
+ this._map = void 0;
978
+ }
979
+ _render() {
980
+ if (!this._container) return;
981
+ this._container.innerHTML = "";
982
+ const button = document.createElement("button");
983
+ button.type = "button";
984
+ button.className = "maplibregl-ctrl-icon";
985
+ button.title = "Toggle Layers";
986
+ button.setAttribute("aria-label", "Toggle Layers");
987
+ button.innerHTML = `
988
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
989
+ <path d="M12 2L2 7l10 5 10-5-10-5z"/>
990
+ <path d="M2 17l10 5 10-5"/>
991
+ <path d="M2 12l10 5 10-5"/>
992
+ </svg>
993
+ `;
994
+ button.style.width = "29px";
995
+ button.style.height = "29px";
996
+ button.style.cursor = "pointer";
997
+ button.style.border = "none";
998
+ button.style.padding = "0";
999
+ button.style.display = "flex";
1000
+ button.style.alignItems = "center";
1001
+ button.style.justifyContent = "center";
1002
+ const panel = document.createElement("div");
1003
+ panel.className = "maplibregl-ctrl-layers-panel";
1004
+ panel.style.display = "none";
1005
+ panel.style.position = "absolute";
1006
+ panel.style.top = "0";
1007
+ panel.style.right = "40px";
1008
+ panel.style.background = "white";
1009
+ panel.style.borderRadius = "4px";
1010
+ panel.style.boxShadow = "0 0 0 2px rgba(0, 0, 0, 0.1)";
1011
+ panel.style.padding = "8px";
1012
+ panel.style.minWidth = "180px";
1013
+ panel.style.maxHeight = "300px";
1014
+ panel.style.overflowY = "auto";
1015
+ const title = document.createElement("div");
1016
+ title.textContent = "POI Layers";
1017
+ title.style.fontSize = "12px";
1018
+ title.style.fontWeight = "bold";
1019
+ title.style.marginBottom = "8px";
1020
+ title.style.color = "#333";
1021
+ title.style.fontFamily = "system-ui, -apple-system, sans-serif";
1022
+ panel.appendChild(title);
1023
+ this._layers.forEach((layer) => {
1024
+ const layerItem = document.createElement("div");
1025
+ layerItem.style.display = "flex";
1026
+ layerItem.style.alignItems = "center";
1027
+ layerItem.style.padding = "4px 0";
1028
+ layerItem.style.cursor = "pointer";
1029
+ layerItem.style.fontSize = "12px";
1030
+ layerItem.style.color = "#333";
1031
+ layerItem.style.fontFamily = "system-ui, -apple-system, sans-serif";
1032
+ const circle = document.createElement("div");
1033
+ circle.style.width = "12px";
1034
+ circle.style.height = "12px";
1035
+ circle.style.borderRadius = "50%";
1036
+ circle.style.marginRight = "8px";
1037
+ circle.style.cursor = "pointer";
1038
+ circle.style.flexShrink = "0";
1039
+ circle.style.transition = "all 0.2s ease";
1040
+ if (layer.enabled && layer.color) {
1041
+ circle.style.backgroundColor = layer.color;
1042
+ circle.style.border = "none";
1043
+ } else {
1044
+ circle.style.backgroundColor = "transparent";
1045
+ circle.style.border = "2px solid #999";
1046
+ }
1047
+ layerItem.addEventListener("click", (e) => {
1048
+ e.stopPropagation();
1049
+ this._onToggle(layer.id, !layer.enabled);
1050
+ });
1051
+ const labelText = document.createElement("span");
1052
+ labelText.textContent = layer.name;
1053
+ labelText.style.userSelect = "none";
1054
+ layerItem.appendChild(circle);
1055
+ layerItem.appendChild(labelText);
1056
+ panel.appendChild(layerItem);
1057
+ });
1058
+ let isPanelOpen = false;
1059
+ button.addEventListener("click", (e) => {
1060
+ e.stopPropagation();
1061
+ isPanelOpen = !isPanelOpen;
1062
+ panel.style.display = isPanelOpen ? "block" : "none";
1063
+ });
1064
+ document.addEventListener("click", (e) => {
1065
+ if (isPanelOpen && this._container && !this._container.contains(e.target)) {
1066
+ isPanelOpen = false;
1067
+ panel.style.display = "none";
1068
+ }
1069
+ });
1070
+ this._container.appendChild(button);
1071
+ this._container.appendChild(panel);
1072
+ }
1073
+ /**
1074
+ * Update layers (e.g., when toggled externally)
1075
+ */
1076
+ updateLayers(layers) {
1077
+ this._layers = layers;
1078
+ this._render();
1079
+ }
1080
+ }
1081
+ const LayerControl = ({ mapRef, layers, onLayerToggle }) => {
1082
+ const controlRef = React.useRef(null);
1083
+ React.useEffect(() => {
1084
+ if (!mapRef.current || layers.length === 0) return;
1085
+ const map = mapRef.current.getMap();
1086
+ const control = new LayerControlImpl(layers, onLayerToggle);
1087
+ controlRef.current = control;
1088
+ map.addControl(control, "top-right");
1089
+ return () => {
1090
+ if (controlRef.current) {
1091
+ map.removeControl(controlRef.current);
1092
+ controlRef.current = null;
1093
+ }
1094
+ };
1095
+ }, [mapRef, onLayerToggle]);
1096
+ React.useEffect(() => {
1097
+ if (controlRef.current) {
1098
+ controlRef.current.updateLayers(layers);
1099
+ }
1100
+ }, [layers]);
1101
+ return null;
1102
+ };
1103
+ class CreditsControlImpl {
1104
+ _map;
1105
+ _container;
1106
+ onAdd(map) {
1107
+ this._map = map;
1108
+ this._container = document.createElement("div");
1109
+ this._container.className = "maplibregl-ctrl maplibregl-ctrl-attrib maplibregl-compact";
1110
+ this._render();
1111
+ return this._container;
1112
+ }
1113
+ onRemove() {
1114
+ if (this._container && this._container.parentNode) {
1115
+ this._container.parentNode.removeChild(this._container);
1116
+ }
1117
+ this._map = void 0;
1118
+ }
1119
+ _render() {
1120
+ if (!this._container) return;
1121
+ this._container.innerHTML = "";
1122
+ const button = document.createElement("button");
1123
+ button.type = "button";
1124
+ button.className = "maplibregl-ctrl-attrib-button";
1125
+ button.title = "Toggle attribution";
1126
+ button.setAttribute("aria-label", "Toggle attribution");
1127
+ button.setAttribute("type", "button");
1128
+ button.setAttribute("aria-pressed", "false");
1129
+ const panel = document.createElement("div");
1130
+ panel.className = "maplibregl-ctrl-attrib maplibregl-compact";
1131
+ panel.style.display = "none";
1132
+ panel.style.background = "rgba(255, 255, 255, 0.5)";
1133
+ panel.style.fontSize = "11px";
1134
+ panel.style.padding = "0 5px";
1135
+ panel.style.margin = "0";
1136
+ panel.style.lineHeight = "20px";
1137
+ panel.style.color = "rgba(0, 0, 0, 0.75)";
1138
+ const content = document.createElement("div");
1139
+ content.innerHTML = `
1140
+ <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noopener noreferrer">© OpenStreetMap</a> |
1141
+ <a href="https://maplibre.org/" target="_blank" rel="noopener noreferrer">MapLibre</a>
1142
+ `;
1143
+ content.querySelectorAll("a").forEach((link) => {
1144
+ link.style.color = "rgba(0, 0, 0, 0.75)";
1145
+ link.style.textDecoration = "none";
1146
+ });
1147
+ panel.appendChild(content);
1148
+ let isPanelOpen = false;
1149
+ const togglePanel = (open) => {
1150
+ isPanelOpen = open;
1151
+ panel.style.display = isPanelOpen ? "block" : "none";
1152
+ button.setAttribute("aria-pressed", isPanelOpen ? "true" : "false");
1153
+ };
1154
+ button.addEventListener("click", (e) => {
1155
+ e.stopPropagation();
1156
+ togglePanel(!isPanelOpen);
1157
+ });
1158
+ document.addEventListener("click", (e) => {
1159
+ if (isPanelOpen && this._container && !this._container.contains(e.target)) {
1160
+ togglePanel(false);
1161
+ }
1162
+ });
1163
+ this._container.appendChild(button);
1164
+ this._container.appendChild(panel);
1165
+ }
1166
+ }
1167
+ const CreditsControl = ({ mapRef }) => {
1168
+ const controlRef = React.useRef(null);
1169
+ React.useEffect(() => {
1170
+ if (!mapRef.current) return;
1171
+ const map = mapRef.current.getMap();
1172
+ const control = new CreditsControlImpl();
1173
+ controlRef.current = control;
1174
+ map.addControl(control, "bottom-right");
1175
+ return () => {
1176
+ if (controlRef.current) {
1177
+ map.removeControl(controlRef.current);
1178
+ controlRef.current = null;
1179
+ }
1180
+ };
1181
+ }, [mapRef]);
1182
+ return null;
1183
+ };
1184
+ const getTrad = (id) => `${index.pluginId}.${id}`;
1185
+ const USER_AGENT = "strapi-plugin-maplibre-field/1.0.0 (Strapi CMS)";
1186
+ let protocol = new pmtiles.Protocol();
1187
+ maplibregl__default.default.addProtocol("pmtiles", protocol.tile);
1188
+ const MapField = ({ intlLabel, name, onChange, value }) => {
1189
+ const { formatMessage } = useIntl();
1190
+ const { toggleNotification } = admin.useNotification();
1191
+ const config = usePluginConfig();
1192
+ const mapRef = React.useRef(null);
1193
+ console.log("[MapLibre MapField] Using config:", config);
1194
+ const label = intlLabel || { id: "maplibre-field.label", defaultMessage: "Map" };
1195
+ let result = null;
1196
+ if (value) {
1197
+ try {
1198
+ const parsed = typeof value === "string" ? JSON.parse(value) : value;
1199
+ if (parsed && typeof parsed === "object" && parsed.geometry?.coordinates) {
1200
+ result = parsed;
1201
+ }
1202
+ } catch (error) {
1203
+ console.error("MapField: Invalid JSON value", error);
1204
+ }
1205
+ }
1206
+ const isDefaultViewState = result == null;
1207
+ let initialCoordinates = config.defaultCenter || [0, 0];
1208
+ if (result?.geometry?.coordinates && Array.isArray(result.geometry.coordinates)) {
1209
+ const [lng, lat] = result.geometry.coordinates;
1210
+ if (typeof lng === "number" && typeof lat === "number" && !isNaN(lng) && !isNaN(lat)) {
1211
+ initialCoordinates = [lng, lat];
1212
+ }
1213
+ }
1214
+ const isNullIsland = initialCoordinates[0] === 0 && initialCoordinates[1] === 0;
1215
+ const initialAddress = result?.properties?.name || result?.properties?.address || (isNullIsland ? "Null Island" : "");
1216
+ const [longitude, setLongitude] = React.useState(initialCoordinates[0]);
1217
+ const [latitude, setLatitude] = React.useState(initialCoordinates[1]);
1218
+ const [address, setAddress] = React.useState(initialAddress);
1219
+ const [viewState, setViewState] = React.useState({
1220
+ longitude: initialCoordinates[0],
1221
+ latitude: initialCoordinates[1],
1222
+ zoom: isDefaultViewState ? config.defaultZoom || 4.5 : 15
1223
+ // Use zoom 15 when coordinates are saved
1224
+ });
1225
+ const [currentStyleUrl, setCurrentStyleUrl] = React.useState(() => {
1226
+ if (config.mapStyles && config.mapStyles.length > 0) {
1227
+ const defaultStyle = config.mapStyles.find((s) => s.isDefault);
1228
+ return defaultStyle?.url || config.mapStyles[0].url;
1229
+ }
1230
+ return "";
1231
+ });
1232
+ const [displayedPOIs, setDisplayedPOIs] = React.useState([]);
1233
+ const [selectedPOI, setSelectedPOI] = React.useState(null);
1234
+ const [isUpdatingPOIs, setIsUpdatingPOIs] = React.useState(false);
1235
+ const updatePOITimerRef = React.useRef(null);
1236
+ const poiLayersRef = React.useRef([]);
1237
+ const [poiLayers, setPoiLayers] = React.useState(() => {
1238
+ if (!config.poiDisplayEnabled) return [];
1239
+ if (config.poiSources && config.poiSources.length > 0) {
1240
+ return config.poiSources.map((source) => ({
1241
+ id: source.id,
1242
+ name: source.name,
1243
+ enabled: source.enabled !== false,
1244
+ // Default to enabled if not specified
1245
+ color: source.color
1246
+ // Pass the color from config
1247
+ }));
1248
+ }
1249
+ return [];
1250
+ });
1251
+ React.useEffect(() => {
1252
+ poiLayersRef.current = poiLayers;
1253
+ }, [poiLayers]);
1254
+ React.useEffect(() => {
1255
+ if (config.defaultZoom && isDefaultViewState) {
1256
+ setViewState((prev) => ({
1257
+ ...prev,
1258
+ zoom: config.defaultZoom ?? prev.zoom
1259
+ }));
1260
+ }
1261
+ }, [config.defaultZoom, isDefaultViewState]);
1262
+ React.useEffect(() => {
1263
+ if (config.defaultCenter && isDefaultViewState) {
1264
+ const [lng, lat] = config.defaultCenter;
1265
+ const isNullIsland2 = lng === 0 && lat === 0;
1266
+ setLongitude(lng);
1267
+ setLatitude(lat);
1268
+ setAddress(isNullIsland2 ? "Null Island" : "");
1269
+ setViewState((prev) => ({
1270
+ ...prev,
1271
+ longitude: lng,
1272
+ latitude: lat
1273
+ }));
1274
+ }
1275
+ }, [config.defaultCenter, isDefaultViewState]);
1276
+ React.useEffect(() => {
1277
+ if (config.mapStyles && config.mapStyles.length > 0) {
1278
+ const defaultStyle = config.mapStyles.find((s) => s.isDefault);
1279
+ const newStyleUrl = defaultStyle?.url || config.mapStyles[0].url;
1280
+ if (newStyleUrl && newStyleUrl !== currentStyleUrl) {
1281
+ setCurrentStyleUrl(newStyleUrl);
1282
+ }
1283
+ }
1284
+ }, [config.mapStyles]);
1285
+ React.useEffect(() => {
1286
+ if (!config.poiDisplayEnabled) {
1287
+ setPoiLayers([]);
1288
+ return;
1289
+ }
1290
+ if (config.poiSources && config.poiSources.length > 0) {
1291
+ setPoiLayers(
1292
+ config.poiSources.map((source) => ({
1293
+ id: source.id,
1294
+ name: source.name,
1295
+ enabled: source.enabled !== false,
1296
+ color: source.color
1297
+ // Pass the color from config
1298
+ }))
1299
+ );
1300
+ return;
1301
+ }
1302
+ setPoiLayers([]);
1303
+ }, [config.poiDisplayEnabled, config.poiSources]);
1304
+ const handleStyleChange = (newStyleUrl) => {
1305
+ if (!mapRef.current) return;
1306
+ const map = mapRef.current.getMap();
1307
+ const currentCenter = map.getCenter();
1308
+ const currentZoom = map.getZoom();
1309
+ map.setStyle(newStyleUrl);
1310
+ map.once("styledata", () => {
1311
+ map.setCenter(currentCenter);
1312
+ map.setZoom(currentZoom);
1313
+ });
1314
+ setCurrentStyleUrl(newStyleUrl);
1315
+ };
1316
+ const handleLayerToggle = (layerId, enabled) => {
1317
+ setPoiLayers(
1318
+ (prevLayers) => prevLayers.map(
1319
+ (layer) => layer.id === layerId ? { ...layer, enabled } : layer
1320
+ )
1321
+ );
1322
+ };
1323
+ const updatePOIMarkers = async () => {
1324
+ if (updatePOITimerRef.current) {
1325
+ clearTimeout(updatePOITimerRef.current);
1326
+ }
1327
+ updatePOITimerRef.current = setTimeout(async () => {
1328
+ const currentPoiLayers = poiLayersRef.current;
1329
+ const hasEnabledLayers = currentPoiLayers.some((layer) => layer.enabled);
1330
+ if (!mapRef.current || !config.poiDisplayEnabled) {
1331
+ return;
1332
+ }
1333
+ if (!hasEnabledLayers) {
1334
+ setDisplayedPOIs([]);
1335
+ return;
1336
+ }
1337
+ if (isUpdatingPOIs) {
1338
+ return;
1339
+ }
1340
+ const map = mapRef.current.getMap();
1341
+ const zoom = map.getZoom();
1342
+ if (zoom < (config.poiMinZoom || 10)) {
1343
+ setDisplayedPOIs([]);
1344
+ return;
1345
+ }
1346
+ const bounds = map.getBounds();
1347
+ const center = map.getCenter();
1348
+ try {
1349
+ setIsUpdatingPOIs(true);
1350
+ const enabledLayers = currentPoiLayers.filter((layer) => layer.enabled);
1351
+ const allPOIs = [];
1352
+ for (const layer of enabledLayers) {
1353
+ let apiUrl = null;
1354
+ let mapName = layer.name;
1355
+ if (config.poiSources) {
1356
+ const source = config.poiSources.find((s) => s.id === layer.id);
1357
+ if (source) {
1358
+ apiUrl = source.apiUrl;
1359
+ mapName = source.name;
1360
+ }
1361
+ }
1362
+ if (apiUrl) {
1363
+ const pois = await queryPOIsForViewport(
1364
+ {
1365
+ north: bounds.getNorth(),
1366
+ south: bounds.getSouth(),
1367
+ east: bounds.getEast(),
1368
+ west: bounds.getWest()
1369
+ },
1370
+ [center.lng, center.lat],
1371
+ config.poiMaxDisplay || 100,
1372
+ {
1373
+ nominatimUrl: config.nominatimUrl || "https://nominatim.openstreetmap.org",
1374
+ customApiUrl: apiUrl,
1375
+ mapName,
1376
+ layerId: layer.id,
1377
+ // Pass the layer ID
1378
+ radius: 100,
1379
+ categories: []
1380
+ }
1381
+ );
1382
+ allPOIs.push(...pois);
1383
+ }
1384
+ }
1385
+ requestAnimationFrame(() => {
1386
+ setDisplayedPOIs(allPOIs);
1387
+ setIsUpdatingPOIs(false);
1388
+ });
1389
+ } catch (error) {
1390
+ console.error("Failed to load POIs:", error);
1391
+ setIsUpdatingPOIs(false);
1392
+ }
1393
+ }, 300);
1394
+ };
1395
+ const handlePOIClick = async (poi) => {
1396
+ setSelectedPOI(poi);
1397
+ let address2 = poi.address;
1398
+ if (!address2 || address2.trim() === "") {
1399
+ try {
1400
+ const [lng, lat] = poi.coordinates;
1401
+ const nominatimUrl = config.nominatimUrl || "https://nominatim.openstreetmap.org";
1402
+ const response = await fetch(
1403
+ `${nominatimUrl}/reverse?format=jsonv2&lat=${lat}&lon=${lng}`,
1404
+ {
1405
+ headers: {
1406
+ "User-Agent": USER_AGENT
1407
+ }
1408
+ }
1409
+ );
1410
+ if (response.ok) {
1411
+ const data = await response.json();
1412
+ address2 = data.display_name || "";
1413
+ }
1414
+ } catch (error) {
1415
+ console.warn("Reverse geocoding failed:", error);
1416
+ }
1417
+ }
1418
+ updateValues(createLocationFeature(poi.coordinates, {
1419
+ name: poi.name,
1420
+ address: address2,
1421
+ source: poi.source === "custom" ? poi.layerId : "nominatim",
1422
+ sourceId: poi.id,
1423
+ sourceLayer: poi.mapName,
1424
+ category: poi.type,
1425
+ inputMethod: "poi_click",
1426
+ metadata: poi.metadata
1427
+ }));
1428
+ toggleNotification({
1429
+ type: "success",
1430
+ message: poi.mapName ? `${poi.mapName} → ${poi.name}` : `Selected ${poi.name}`
1431
+ });
1432
+ };
1433
+ const handleMapClick = (evt) => {
1434
+ if (!mapRef.current) return;
1435
+ const map = mapRef.current.getMap();
1436
+ const poiLayer = map.getLayer("poi-circles");
1437
+ if (!poiLayer) {
1438
+ return;
1439
+ }
1440
+ const features = map.queryRenderedFeatures(evt.point, {
1441
+ layers: ["poi-circles"]
1442
+ });
1443
+ if (features && features.length > 0) {
1444
+ const feature = features[0];
1445
+ const featureName = feature.properties?.name;
1446
+ let clickedPOI = displayedPOIs.find((p) => p.name === featureName);
1447
+ if (!clickedPOI) {
1448
+ clickedPOI = displayedPOIs.find((p) => p.id === feature.id);
1449
+ }
1450
+ if (!clickedPOI && feature.id !== void 0) {
1451
+ clickedPOI = displayedPOIs.find((p) => p.id === String(feature.id));
1452
+ }
1453
+ if (clickedPOI) {
1454
+ handlePOIClick(clickedPOI);
1455
+ return;
1456
+ }
1457
+ }
1458
+ };
1459
+ const handleMapDoubleClick = async (evt) => {
1460
+ evt.preventDefault();
1461
+ const clickCoords = [evt.lngLat.lng, evt.lngLat.lat];
1462
+ const snapRadius = typeof config.poiSnapRadius === "number" ? config.poiSnapRadius : config.poiSnapRadius?.default ?? 5;
1463
+ try {
1464
+ const enabledLayers = poiLayers.filter((layer) => layer.enabled);
1465
+ const allNearbyPOIs = [];
1466
+ for (const layer of enabledLayers) {
1467
+ let apiUrl = null;
1468
+ let mapName = layer.name;
1469
+ if (config.poiSources) {
1470
+ const source = config.poiSources.find((s) => s.id === layer.id);
1471
+ if (source) {
1472
+ apiUrl = source.apiUrl;
1473
+ mapName = source.name;
1474
+ }
1475
+ }
1476
+ if (apiUrl) {
1477
+ const pois = await searchNearbyPOIsForSnap(
1478
+ clickCoords[1],
1479
+ // lat
1480
+ clickCoords[0],
1481
+ // lng
1482
+ {
1483
+ nominatimUrl: config.nominatimUrl || "https://nominatim.openstreetmap.org",
1484
+ customApiUrl: apiUrl,
1485
+ mapName,
1486
+ layerId: layer.id,
1487
+ // Pass the layer ID
1488
+ radius: snapRadius,
1489
+ categories: []
1490
+ }
1491
+ );
1492
+ allNearbyPOIs.push(...pois);
1493
+ }
1494
+ }
1495
+ const nearestPOI = findNearestPOI(clickCoords, allNearbyPOIs);
1496
+ if (nearestPOI && nearestPOI.distance !== void 0 && nearestPOI.distance <= snapRadius) {
1497
+ await handlePOIClick(nearestPOI);
1498
+ toggleNotification({
1499
+ type: "success",
1500
+ message: `${nearestPOI.name} (${Math.round(nearestPOI.distance)}m)`
1501
+ });
1502
+ } else {
1503
+ updateValues(createLocationFeature(clickCoords, {
1504
+ inputMethod: "map_click"
1505
+ }));
1506
+ toggleNotification({
1507
+ type: "info",
1508
+ message: formatMessage({
1509
+ id: getTrad("coordinates-saved"),
1510
+ defaultMessage: "Coordinates saved"
1511
+ })
1512
+ });
1513
+ }
1514
+ } catch (error) {
1515
+ console.error("Failed to search nearby POIs:", error);
1516
+ updateValues(createLocationFeature(clickCoords, {
1517
+ inputMethod: "map_click"
1518
+ }));
1519
+ toggleNotification({
1520
+ type: "info",
1521
+ message: formatMessage({
1522
+ id: getTrad("coordinates-saved"),
1523
+ defaultMessage: "Coordinates saved"
1524
+ })
1525
+ });
1526
+ }
1527
+ };
1528
+ const updateValues = (feature) => {
1529
+ if (!feature) return;
1530
+ const value2 = JSON.stringify(feature);
1531
+ setAddress(feature.properties.name || feature.properties.address || "");
1532
+ setLongitude(feature.geometry.coordinates[0]);
1533
+ setLatitude(feature.geometry.coordinates[1]);
1534
+ onChange({ target: { name, value: value2, type: "json" } });
1535
+ };
1536
+ const handleGeocoderResult = (evt) => {
1537
+ const { result: result2 } = evt;
1538
+ if (result2?.center) {
1539
+ const properties = result2.properties || {};
1540
+ const isCustomSource = properties.source === "custom";
1541
+ let name2 = result2.place_name || "";
1542
+ if (!isCustomSource && properties.display_name) {
1543
+ name2 = properties.name || properties.display_name.split(",")[0].trim();
1544
+ }
1545
+ updateValues(createLocationFeature(result2.center, {
1546
+ name: isCustomSource ? result2.place_name : name2,
1547
+ address: isCustomSource ? void 0 : result2.place_name,
1548
+ // Full address for Nominatim
1549
+ source: isCustomSource ? properties.poi_source_id : "nominatim",
1550
+ sourceId: isCustomSource ? properties.id : `nominatim-${properties.place_id}`,
1551
+ sourceLayer: isCustomSource ? properties.mapName : void 0,
1552
+ category: properties.type || properties.class,
1553
+ inputMethod: "search",
1554
+ metadata: isCustomSource ? properties.metadata : {
1555
+ osm_id: properties.osm_id,
1556
+ osm_type: properties.osm_type,
1557
+ place_id: properties.place_id,
1558
+ addresstype: properties.addresstype
1559
+ }
1560
+ }));
1561
+ }
1562
+ };
1563
+ React.useEffect(() => {
1564
+ if (!isDefaultViewState && mapRef.current) {
1565
+ const map = mapRef.current.getMap();
1566
+ map?.flyTo({ center: [longitude, latitude], zoom: 15 });
1567
+ }
1568
+ }, [longitude, latitude, isDefaultViewState]);
1569
+ React.useEffect(() => {
1570
+ let protocol2 = new pmtiles.Protocol();
1571
+ maplibregl__default.default.addProtocol("pmtiles", protocol2.tile);
1572
+ return () => {
1573
+ maplibregl__default.default.removeProtocol("pmtiles");
1574
+ };
1575
+ }, []);
1576
+ React.useEffect(() => {
1577
+ if (!mapRef.current || !config.poiDisplayEnabled) return;
1578
+ const map = mapRef.current.getMap();
1579
+ const handleMapUpdate = () => {
1580
+ updatePOIMarkers();
1581
+ };
1582
+ map.once("load", handleMapUpdate);
1583
+ map.on("moveend", handleMapUpdate);
1584
+ map.on("zoomend", handleMapUpdate);
1585
+ return () => {
1586
+ map.off("moveend", handleMapUpdate);
1587
+ map.off("zoomend", handleMapUpdate);
1588
+ if (updatePOITimerRef.current) {
1589
+ clearTimeout(updatePOITimerRef.current);
1590
+ }
1591
+ };
1592
+ }, [config.poiDisplayEnabled, config.poiMinZoom, config.poiMaxDisplay, config.poiSources]);
1593
+ React.useEffect(() => {
1594
+ if (!mapRef.current || !config.poiDisplayEnabled) return;
1595
+ updatePOIMarkers();
1596
+ }, [JSON.stringify(poiLayers.map((l) => ({ id: l.id, enabled: l.enabled })))]);
1597
+ React.useEffect(() => {
1598
+ if (!mapRef.current || !config.poiDisplayEnabled) return;
1599
+ const map = mapRef.current.getMap();
1600
+ const handleMouseEnter = () => {
1601
+ map.getCanvas().style.cursor = "pointer";
1602
+ };
1603
+ const handleMouseLeave = () => {
1604
+ map.getCanvas().style.cursor = "";
1605
+ };
1606
+ map.on("load", () => {
1607
+ map.on("mouseenter", "poi-circles", handleMouseEnter);
1608
+ map.on("mouseleave", "poi-circles", handleMouseLeave);
1609
+ });
1610
+ return () => {
1611
+ map.off("mouseenter", "poi-circles", handleMouseEnter);
1612
+ map.off("mouseleave", "poi-circles", handleMouseLeave);
1613
+ };
1614
+ }, [config.poiDisplayEnabled]);
1615
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
1616
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", variant: "pi", fontWeight: "bold", children: formatMessage(label) }),
1617
+ /* @__PURE__ */ jsxRuntime.jsx(
1618
+ designSystem.Flex,
1619
+ {
1620
+ direction: "column",
1621
+ alignItems: "stretch",
1622
+ style: {
1623
+ height: "500px",
1624
+ width: "100%",
1625
+ borderRadius: "4px",
1626
+ overflow: "hidden"
1627
+ },
1628
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1629
+ Map__default.default,
1630
+ {
1631
+ ref: mapRef,
1632
+ ...viewState,
1633
+ onMove: (evt) => setViewState(evt.viewState),
1634
+ onClick: handleMapClick,
1635
+ onDblClick: handleMapDoubleClick,
1636
+ mapStyle: currentStyleUrl,
1637
+ attributionControl: false,
1638
+ children: [
1639
+ /* @__PURE__ */ jsxRuntime.jsx(Map.FullscreenControl, {}),
1640
+ /* @__PURE__ */ jsxRuntime.jsx(Map.NavigationControl, {}),
1641
+ /* @__PURE__ */ jsxRuntime.jsx(Map.GeolocateControl, {}),
1642
+ /* @__PURE__ */ jsxRuntime.jsx(
1643
+ GeocoderControl,
1644
+ {
1645
+ mapRef,
1646
+ position: "top-left",
1647
+ onResult: handleGeocoderResult
1648
+ }
1649
+ ),
1650
+ config.mapStyles && config.mapStyles.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
1651
+ BasemapControlComponent,
1652
+ {
1653
+ mapStyles: config.mapStyles,
1654
+ currentStyleUrl,
1655
+ onStyleChange: handleStyleChange
1656
+ }
1657
+ ),
1658
+ poiLayers.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1659
+ LayerControl,
1660
+ {
1661
+ mapRef,
1662
+ layers: poiLayers,
1663
+ onLayerToggle: handleLayerToggle
1664
+ }
1665
+ ),
1666
+ /* @__PURE__ */ jsxRuntime.jsx(CreditsControl, { mapRef }),
1667
+ config.poiDisplayEnabled && displayedPOIs.length > 0 && (() => {
1668
+ const layerColorMap = {};
1669
+ poiLayers.forEach((layer) => {
1670
+ if (layer.color) {
1671
+ layerColorMap[layer.id] = layer.color;
1672
+ }
1673
+ });
1674
+ const colorMatchExpression = ["match", ["get", "layerId"]];
1675
+ Object.entries(layerColorMap).forEach(([layerId, color]) => {
1676
+ colorMatchExpression.push(layerId, color);
1677
+ });
1678
+ colorMatchExpression.push("#999999");
1679
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1680
+ Map.Source,
1681
+ {
1682
+ id: "poi-markers",
1683
+ type: "geojson",
1684
+ data: {
1685
+ type: "FeatureCollection",
1686
+ features: displayedPOIs.slice(0, 100).map((poi) => ({
1687
+ type: "Feature",
1688
+ id: poi.id,
1689
+ geometry: {
1690
+ type: "Point",
1691
+ coordinates: poi.coordinates
1692
+ },
1693
+ properties: {
1694
+ name: poi.name || "Unknown",
1695
+ type: poi.type || "poi",
1696
+ source: poi.source,
1697
+ layerId: poi.layerId || "",
1698
+ // Include layerId for color mapping
1699
+ isSelected: selectedPOI?.id === poi.id
1700
+ }
1701
+ }))
1702
+ },
1703
+ children: [
1704
+ /* @__PURE__ */ jsxRuntime.jsx(
1705
+ Map.Layer,
1706
+ {
1707
+ id: "poi-circles",
1708
+ type: "circle",
1709
+ paint: {
1710
+ "circle-radius": [
1711
+ "case",
1712
+ ["get", "isSelected"],
1713
+ 12,
1714
+ // Larger radius for selected
1715
+ 10
1716
+ // Regular radius
1717
+ ],
1718
+ "circle-color": colorMatchExpression,
1719
+ // Use dynamic color mapping based on layerId for all POIs
1720
+ "circle-stroke-width": 2,
1721
+ "circle-stroke-color": "#ffffff",
1722
+ "circle-opacity": [
1723
+ "case",
1724
+ ["get", "isSelected"],
1725
+ 0.8,
1726
+ // Selected POI opacity
1727
+ 1
1728
+ // Regular POI opacity
1729
+ ]
1730
+ }
1731
+ }
1732
+ ),
1733
+ /* @__PURE__ */ jsxRuntime.jsx(
1734
+ Map.Layer,
1735
+ {
1736
+ id: "poi-labels",
1737
+ type: "symbol",
1738
+ minzoom: 12,
1739
+ layout: {
1740
+ "text-field": ["get", "name"],
1741
+ "text-size": 12,
1742
+ "text-offset": [0, 1.5],
1743
+ "text-anchor": "top",
1744
+ "text-optional": true,
1745
+ "symbol-placement": "point",
1746
+ "text-allow-overlap": false,
1747
+ "text-ignore-placement": false
1748
+ },
1749
+ paint: {
1750
+ "text-color": "#333333",
1751
+ "text-halo-color": "#ffffff",
1752
+ "text-halo-width": 2
1753
+ }
1754
+ }
1755
+ )
1756
+ ]
1757
+ },
1758
+ `poi-source-${displayedPOIs.length}-${selectedPOI?.id || "none"}`
1759
+ );
1760
+ })(),
1761
+ /* @__PURE__ */ jsxRuntime.jsx(Map.Marker, { longitude, latitude, color: "#1da1f2" })
1762
+ ]
1763
+ }
1764
+ )
1765
+ }
1766
+ ),
1767
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { children: [
1768
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { padding: 1, col: 8, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
1769
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
1770
+ id: result?.properties?.sourceId ? getTrad("fields.poi-name") : getTrad("fields.address"),
1771
+ defaultMessage: result?.properties?.sourceId ? "POI Name" : "Address"
1772
+ }) }),
1773
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Input, { name: "place_name", value: address, disabled: true })
1774
+ ] }) }),
1775
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { padding: 1, col: 2, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
1776
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
1777
+ id: getTrad("fields.longitude"),
1778
+ defaultMessage: "Longitude"
1779
+ }) }),
1780
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Input, { name: "longitude", value: longitude, disabled: true })
1781
+ ] }) }),
1782
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { padding: 1, col: 2, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
1783
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
1784
+ id: getTrad("fields.latitude"),
1785
+ defaultMessage: "Latitude"
1786
+ }) }),
1787
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Input, { name: "latitude", value: latitude, disabled: true })
1788
+ ] }) }),
1789
+ result?.properties?.sourceId && result?.properties?.address && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { padding: 1, col: 12, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
1790
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
1791
+ id: getTrad("fields.poi-address"),
1792
+ defaultMessage: "Full Address"
1793
+ }) }),
1794
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Input, { name: "poi_address", value: result.properties.address, disabled: true })
1795
+ ] }) })
1796
+ ] })
1797
+ ] });
1798
+ };
1799
+ exports.default = MapField;