@eyeon/map 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +18 -1
  2. package/dist/assets/MapViewer.css +1 -1
  3. package/dist/assets/index.css +1 -1
  4. package/dist/chunks/MapViewer.js +1745 -356
  5. package/dist/chunks/MapViewer.js.map +1 -1
  6. package/dist/chunks/stacking.js +1321 -0
  7. package/dist/chunks/stacking.js.map +1 -0
  8. package/dist/core/geometry/index.d.ts +41 -4
  9. package/dist/core/geometry/index.d.ts.map +1 -1
  10. package/dist/core/hostChrome.d.ts +20 -0
  11. package/dist/core/hostChrome.d.ts.map +1 -0
  12. package/dist/core/import/index.d.ts +48 -3
  13. package/dist/core/import/index.d.ts.map +1 -1
  14. package/dist/core/import/svgStyle.d.ts +21 -0
  15. package/dist/core/import/svgStyle.d.ts.map +1 -0
  16. package/dist/core/import/svgTransform.d.ts +49 -0
  17. package/dist/core/import/svgTransform.d.ts.map +1 -0
  18. package/dist/core/index.d.ts +3 -0
  19. package/dist/core/index.d.ts.map +1 -1
  20. package/dist/core/index.js +207 -266
  21. package/dist/core/index.js.map +1 -1
  22. package/dist/core/layerStyles.d.ts +28 -0
  23. package/dist/core/layerStyles.d.ts.map +1 -0
  24. package/dist/core/publish/index.d.ts +8 -2
  25. package/dist/core/publish/index.d.ts.map +1 -1
  26. package/dist/core/routing/graph-tools.d.ts +5 -1
  27. package/dist/core/routing/graph-tools.d.ts.map +1 -1
  28. package/dist/core/stacking.d.ts +61 -0
  29. package/dist/core/stacking.d.ts.map +1 -0
  30. package/dist/core/types.d.ts +27 -0
  31. package/dist/core/types.d.ts.map +1 -1
  32. package/dist/editor/MapEditor.d.ts +28 -16
  33. package/dist/editor/MapEditor.d.ts.map +1 -1
  34. package/dist/editor/canvas/EditorCanvas.d.ts +15 -3
  35. package/dist/editor/canvas/EditorCanvas.d.ts.map +1 -1
  36. package/dist/editor/canvas/coords.d.ts +21 -0
  37. package/dist/editor/canvas/coords.d.ts.map +1 -0
  38. package/dist/editor/draftOps.d.ts +19 -0
  39. package/dist/editor/draftOps.d.ts.map +1 -0
  40. package/dist/editor/geometryEdit.d.ts +34 -0
  41. package/dist/editor/geometryEdit.d.ts.map +1 -0
  42. package/dist/editor/index.css +1281 -145
  43. package/dist/editor/index.d.ts +8 -2
  44. package/dist/editor/index.d.ts.map +1 -1
  45. package/dist/editor/index.js +2293 -585
  46. package/dist/editor/index.js.map +1 -1
  47. package/dist/editor/labels.d.ts +5 -0
  48. package/dist/editor/labels.d.ts.map +1 -0
  49. package/dist/editor/panels/FloorsPanel.d.ts +60 -0
  50. package/dist/editor/panels/FloorsPanel.d.ts.map +1 -0
  51. package/dist/editor/panels/ImportReviewPanel.d.ts +22 -0
  52. package/dist/editor/panels/ImportReviewPanel.d.ts.map +1 -0
  53. package/dist/editor/panels/Inspector.d.ts +4 -2
  54. package/dist/editor/panels/Inspector.d.ts.map +1 -1
  55. package/dist/editor/panels/LeftRail.d.ts +19 -6
  56. package/dist/editor/panels/LeftRail.d.ts.map +1 -1
  57. package/dist/editor/panels/PreviewOverlay.d.ts +11 -2
  58. package/dist/editor/panels/PreviewOverlay.d.ts.map +1 -1
  59. package/dist/editor/portalSurface.d.ts +11 -0
  60. package/dist/editor/portalSurface.d.ts.map +1 -0
  61. package/dist/editor/previewDocument.d.ts +9 -0
  62. package/dist/editor/previewDocument.d.ts.map +1 -0
  63. package/dist/editor/tools.d.ts +20 -0
  64. package/dist/editor/tools.d.ts.map +1 -0
  65. package/dist/test-maps/shops-at-south-town/BASE - Shops At South Town.ai +26780 -26
  66. package/dist/test-maps/shops-at-south-town/LF - Shops At South Town.ai +4487 -2
  67. package/dist/test-maps/shops-at-south-town/SVG/BASE - Shops At South Town.svg +567 -0
  68. package/dist/test-maps/shops-at-south-town/SVG/LF - Shops At South Town.svg +238 -0
  69. package/dist/test-maps/shops-at-south-town/SVG/UF - Shops At South Town.svg +276 -0
  70. package/dist/test-maps/shops-at-south-town/UF - Shops At South Town.ai +4228 -1
  71. package/dist/viewer/MapViewer.d.ts +14 -3
  72. package/dist/viewer/MapViewer.d.ts.map +1 -1
  73. package/dist/viewer/camera.d.ts +34 -0
  74. package/dist/viewer/camera.d.ts.map +1 -0
  75. package/dist/viewer/components/CameraRig.d.ts +18 -0
  76. package/dist/viewer/components/CameraRig.d.ts.map +1 -0
  77. package/dist/viewer/components/LevelMeshes.d.ts +6 -1
  78. package/dist/viewer/components/LevelMeshes.d.ts.map +1 -1
  79. package/dist/viewer/components/MapScene.d.ts +6 -1
  80. package/dist/viewer/components/MapScene.d.ts.map +1 -1
  81. package/dist/viewer/components/SvgVectorLayer.d.ts +18 -0
  82. package/dist/viewer/components/SvgVectorLayer.d.ts.map +1 -0
  83. package/dist/viewer/index.css +124 -35
  84. package/dist/viewer/index.d.ts +4 -0
  85. package/dist/viewer/index.d.ts.map +1 -1
  86. package/dist/viewer/index.js +9 -4
  87. package/dist/viewer/index.js.map +1 -1
  88. package/dist/viewer/ui/MapControls.d.ts +14 -0
  89. package/dist/viewer/ui/MapControls.d.ts.map +1 -0
  90. package/dist/viewer/ui/RuntimeChrome.d.ts +3 -3
  91. package/dist/viewer/ui/RuntimeChrome.d.ts.map +1 -1
  92. package/package.json +17 -7
  93. package/dist/chunks/graph-tools.js +0 -153
  94. package/dist/chunks/graph-tools.js.map +0 -1
  95. package/dist/chunks/pathfinding.js +0 -343
  96. package/dist/chunks/pathfinding.js.map +0 -1
@@ -1,734 +1,2442 @@
1
- import { jsxs as r, jsx as n, Fragment as q } from "react/jsx-runtime";
2
- import { useRef as z, useState as h, useMemo as V, useEffect as J, Suspense as Q, useCallback as ee } from "react";
3
- import { v as Z, e as le } from "../chunks/pathfinding.js";
4
- import { w as ne } from "../chunks/graph-tools.js";
5
- import { a as ie } from "../chunks/MapViewer.js";
6
- function F(i) {
7
- return i.map((l) => {
8
- if (l.length === 0) return "";
9
- let p = `M ${l[0].x} ${l[0].y}`;
10
- for (let d = 1; d < l.length; d++) p += ` L ${l[d].x} ${l[d].y}`;
11
- return p += " Z", p;
1
+ import { jsx as o, jsxs as s, Fragment as de } from "react/jsx-runtime";
2
+ import { useRef as he, useState as w, useEffect as ae, useMemo as se, useLayoutEffect as Ge, Suspense as Ke, useCallback as we } from "react";
3
+ import { ac as Ue, f as We, a9 as Ve, Z as Fe, K as je, o as Ye, w as Xe, x as ze, z as Re, X as He } from "../chunks/stacking.js";
4
+ import { createPortal as Je } from "react-dom";
5
+ import { b as Ze } from "../chunks/MapViewer.js";
6
+ function Ce(e) {
7
+ return e.map((n) => n.map((r) => ({ x: r.x, y: r.y })));
8
+ }
9
+ function qe(e) {
10
+ return e.map((n) => {
11
+ if (n.length === 0) return "";
12
+ let r = `M ${n[0].x} ${n[0].y}`;
13
+ for (let l = 1; l < n.length; l++)
14
+ r += ` L ${n[l].x} ${n[l].y}`;
15
+ return r += " Z", r;
12
16
  }).join(" ");
13
17
  }
14
- function ae({
15
- level: i,
16
- shapes: l,
17
- anchors: p,
18
- edges: d,
19
- theme: f,
20
- tool: y,
21
- baseAngle: K,
22
- selectedShapeId: D,
23
- selectedAnchorIds: _,
24
- baseSvgUrl: I,
25
- onSelectShape: C,
26
- onSelectAnchors: t,
27
- onCreateRoutePoint: u,
28
- onMoveAnchor: S,
29
- onCreateShape: O
18
+ function be(e) {
19
+ const n = e.map((r) => r.length > 1 && r[0].x === r[r.length - 1].x && r[0].y === r[r.length - 1].y ? r.slice(0, -1) : r).filter((r) => r.length >= 3);
20
+ return {
21
+ paths: n.map((r) => ({
22
+ d: qe([r]),
23
+ closed: !0
24
+ })),
25
+ polygons: n
26
+ };
27
+ }
28
+ function Me(e, n, r) {
29
+ const l = Ce(e.polygons).map(
30
+ (t) => t.map((c) => ({ x: c.x + n, y: c.y + r }))
31
+ );
32
+ return be(l);
33
+ }
34
+ function Qe(e, n, r, l) {
35
+ const t = Ce(e.polygons), c = t[n];
36
+ return !c || r < 0 || r >= c.length ? e : (c[r] = { x: l.x, y: l.y }, be(t));
37
+ }
38
+ function en(e, n, r, l) {
39
+ const t = Ce(e.polygons), c = t[n];
40
+ return !c || r < 0 || r >= c.length ? e : (c.splice(r + 1, 0, { x: l.x, y: l.y }), be(t));
41
+ }
42
+ function nn(e, n, r) {
43
+ const l = Ce(e.polygons), t = l[n];
44
+ return !t || t.length <= 3 || r < 0 || r >= t.length ? e : (t.splice(r, 1), be(l));
45
+ }
46
+ function rn(e, n, r) {
47
+ let l = null;
48
+ return e.polygons.forEach((t, c) => {
49
+ t.forEach((y, M) => {
50
+ const x = Math.hypot(y.x - n.x, y.y - n.y);
51
+ x <= r && (!l || x < l.distance) && (l = {
52
+ polygonIndex: c,
53
+ vertexIndex: M,
54
+ point: { x: y.x, y: y.y },
55
+ distance: x
56
+ });
57
+ });
58
+ }), l;
59
+ }
60
+ function on(e, n, r) {
61
+ let l = null;
62
+ return e.polygons.forEach((t, c) => {
63
+ if (!(t.length < 2))
64
+ for (let y = 0; y < t.length; y++) {
65
+ const M = t[y], x = t[(y + 1) % t.length], N = { x: (M.x + x.x) / 2, y: (M.y + x.y) / 2 }, T = Math.hypot(N.x - n.x, N.y - n.y);
66
+ T <= r && (!l || T < l.distance) && (l = {
67
+ polygonIndex: c,
68
+ afterVertexIndex: y,
69
+ point: N,
70
+ distance: T
71
+ });
72
+ }
73
+ }), l;
74
+ }
75
+ function tn(e, n, r) {
76
+ const l = e.a * e.d - e.b * e.c;
77
+ if (l === 0) return { x: 0, y: 0 };
78
+ const t = n - e.e, c = r - e.f;
79
+ return {
80
+ x: (e.d * t - e.c * c) / l,
81
+ y: (-e.b * t + e.a * c) / l
82
+ };
83
+ }
84
+ function xe(e, n, r) {
85
+ const l = e.getScreenCTM();
86
+ return l ? tn(l, n, r) : { x: 0, y: 0 };
87
+ }
88
+ function ln(e, n, r) {
89
+ const l = r === 0 ? 1 : r;
90
+ return {
91
+ x: (e.x - n.x) / l,
92
+ y: (e.y - n.y) / l
93
+ };
94
+ }
95
+ function an(e, n) {
96
+ return [
97
+ { x: e.x, y: e.y },
98
+ { x: n.x, y: e.y },
99
+ { x: n.x, y: n.y },
100
+ { x: e.x, y: n.y }
101
+ ];
102
+ }
103
+ function Ee(e, n) {
104
+ return Math.hypot(n.x - e.x, n.y - e.y);
105
+ }
106
+ function Oe(e) {
107
+ return e.map((n) => {
108
+ if (n.length === 0) return "";
109
+ let r = `M ${n[0].x} ${n[0].y}`;
110
+ for (let l = 1; l < n.length; l++) r += ` L ${n[l].x} ${n[l].y}`;
111
+ return r += " Z", r;
112
+ }).join(" ");
113
+ }
114
+ function sn(e, n) {
115
+ return e.orphanedAt ? !1 : n ? We.includes(e.kind) : !0;
116
+ }
117
+ function dn({
118
+ level: e,
119
+ shapes: n,
120
+ anchors: r,
121
+ edges: l,
122
+ theme: t,
123
+ tool: c,
124
+ baseAngle: y,
125
+ selectedShapeId: M,
126
+ selectedAnchorIds: x,
127
+ baseSvgUrl: N,
128
+ baseViewbox: T = null,
129
+ levelSvgUrl: J = null,
130
+ underlayShapes: b = [],
131
+ interactiveOnly: S = !1,
132
+ showGrid: P = !0,
133
+ onSelectShape: Q,
134
+ onSelectAnchors: ee,
135
+ onCreateRoutePoint: $,
136
+ onMoveAnchor: W,
137
+ onCreateShape: R,
138
+ onUpdateShapeGeometry: Z
30
139
  }) {
31
- const M = z(null), [b, E] = h({ x: 0, y: 0 }), [m, B] = h(1), [k, R] = h([]), [A, U] = h(null), [$, o] = h(null), g = z(null), v = (i == null ? void 0 : i.sourceViewbox) ?? { x: 0, y: 0, width: 1e3, height: 800 }, w = (e, c) => {
32
- const s = M.current;
33
- if (!s) return { x: 0, y: 0 };
34
- const L = s.getBoundingClientRect(), T = (e - L.left - b.x) / m, a = (c - L.top - b.y) / m;
35
- return { x: T + v.x, y: a + v.y };
36
- }, Y = V(
37
- () => new Map(p.map((e) => [e.id, e])),
38
- [p]
39
- ), X = (e) => {
40
- if (y === "pan" || e.button === 1) {
41
- g.current = { x: e.clientX, y: e.clientY, panX: b.x, panY: b.y };
140
+ const F = he(null), [j, B] = w({ x: 0, y: 0 }), [v, ne] = w(1), [_, G] = w([]), [V, u] = w([]), [K, U] = w(null), [ce, ue] = w(null), [H, q] = w(null), [te, A] = w({ x: 0, y: 0 }), [re, Y] = w(null), [E, le] = w(null), oe = he(null);
141
+ ae(() => {
142
+ G([]), u([]), ue(null), q(null), Y(null), A({ x: 0, y: 0 });
143
+ }, [c]), ae(() => {
144
+ le(null), q(null), Y(null), A({ x: 0, y: 0 });
145
+ }, [M]);
146
+ const X = Ue(e == null ? void 0 : e.sourceViewbox, T), me = J ?? ((e == null ? void 0 : e.kind) === "outdoor" ? N : null), g = se(
147
+ () => n.filter((i) => sn(i, S)),
148
+ [n, S]
149
+ ), C = g.find((i) => i.id === M) ?? null, L = se(() => C ? H && H.shapeId === C.id ? Me(H.originGeometry, te.x, te.y) : C.geometry : null, [C, H, te]), pe = (i, p) => {
150
+ const a = F.current;
151
+ return a ? ln(xe(a, i, p), j, v) : { x: 0, y: 0 };
152
+ }, z = se(
153
+ () => new Map(r.map((i) => [i.id, i])),
154
+ [r]
155
+ ), fe = () => {
156
+ if (V.length < 3) {
157
+ u([]);
42
158
  return;
43
159
  }
44
- const c = w(e.clientX, e.clientY);
45
- if (y === "draw-route") {
46
- const s = $ ? Z(Y.get($) ?? c, c, K) : c;
47
- u(s, $);
160
+ R("unit", be([V])), u([]);
161
+ };
162
+ ae(() => {
163
+ const i = (p) => {
164
+ if (c === "draw-polygon" && (p.key === "Enter" ? (p.preventDefault(), fe()) : p.key === "Escape" && u([])), (p.key === "Backspace" || p.key === "Delete") && C && E && c === "select") {
165
+ p.preventDefault();
166
+ const a = nn(
167
+ C.geometry,
168
+ E.polygonIndex,
169
+ E.vertexIndex
170
+ );
171
+ a !== C.geometry && (Z(C.id, a), le(null));
172
+ }
173
+ };
174
+ return window.addEventListener("keydown", i), () => window.removeEventListener("keydown", i);
175
+ }, [c, V, C, E]);
176
+ const ge = (i) => {
177
+ var a, m, k, I;
178
+ if (c === "pan" || i.button === 1) {
179
+ const O = F.current, d = O ? xe(O, i.clientX, i.clientY) : { x: i.clientX, y: i.clientY };
180
+ oe.current = { x: d.x, y: d.y, panX: j.x, panY: j.y };
48
181
  return;
49
182
  }
50
- y === "draw-unit" && R([c]);
51
- }, j = (e) => {
52
- if (g.current) {
53
- E({
54
- x: g.current.panX + (e.clientX - g.current.x),
55
- y: g.current.panY + (e.clientY - g.current.y)
56
- });
183
+ const p = pe(i.clientX, i.clientY);
184
+ if (c === "draw-polygon") {
185
+ if (V.length >= 3) {
186
+ const O = V[0];
187
+ if (Math.hypot(p.x - O.x, p.y - O.y) <= 6 / v) {
188
+ fe();
189
+ return;
190
+ }
191
+ }
192
+ u((O) => [...O, p]);
57
193
  return;
58
194
  }
59
- if (A != null) {
60
- const c = w(e.clientX, e.clientY);
61
- S(A, c.x, c.y);
195
+ if (c === "draw-route") {
196
+ const O = ce ? Ve(z.get(ce) ?? p, p, y) : p;
197
+ $(O, ce);
62
198
  return;
63
199
  }
64
- if (y === "draw-unit" && k.length > 0) {
65
- const c = w(e.clientX, e.clientY);
66
- R((s) => [...s.slice(0, -1), s[s.length - 1], c].slice(0, -0) || [...s.slice(0, -1), c]), R((s) => s.length === 0 ? s : [...s.slice(0, -1), c]);
200
+ if (c === "draw-unit" || c === "draw-line") {
201
+ (m = (a = i.currentTarget).setPointerCapture) == null || m.call(a, i.pointerId), G([p, p]);
202
+ return;
67
203
  }
68
- }, x = () => {
69
- if (g.current = null, A != null) {
70
- const e = p.find((c) => c.id === A);
71
- if (e) {
72
- const c = p.filter((s) => s.id !== e.id).filter((s) => Math.hypot(s.x - e.x, s.y - e.y) <= 2.5).map((s) => s.id);
73
- c.length && t([e.id, ...c]);
204
+ if (c === "select" && C && L) {
205
+ const O = 8 / v, d = rn(L, p, O);
206
+ if (d) {
207
+ le({
208
+ polygonIndex: d.polygonIndex,
209
+ vertexIndex: d.vertexIndex
210
+ }), Y({
211
+ shapeId: C.id,
212
+ polygonIndex: d.polygonIndex,
213
+ vertexIndex: d.vertexIndex
214
+ }), (I = (k = i.currentTarget).setPointerCapture) == null || I.call(k, i.pointerId);
215
+ return;
216
+ }
217
+ const h = on(L, p, O);
218
+ if (h && i.detail >= 2) {
219
+ const f = en(
220
+ C.geometry,
221
+ h.polygonIndex,
222
+ h.afterVertexIndex,
223
+ h.point
224
+ );
225
+ Z(C.id, f), le({
226
+ polygonIndex: h.polygonIndex,
227
+ vertexIndex: h.afterVertexIndex + 1
228
+ });
229
+ return;
74
230
  }
75
- U(null);
76
231
  }
77
- }, G = () => {
78
- if (k.length < 3) {
79
- R([]);
232
+ }, ye = (i) => {
233
+ if (oe.current) {
234
+ const p = F.current;
235
+ if (!p) return;
236
+ const a = xe(p, i.clientX, i.clientY);
237
+ B({
238
+ x: oe.current.panX + (a.x - oe.current.x),
239
+ y: oe.current.panY + (a.y - oe.current.y)
240
+ });
80
241
  return;
81
242
  }
82
- const e = {
83
- paths: [
84
- {
85
- d: F([k]),
86
- closed: !0
87
- }
88
- ],
89
- polygons: [k]
243
+ if (K != null) {
244
+ const p = pe(i.clientX, i.clientY);
245
+ W(K, p.x, p.y);
246
+ return;
247
+ }
248
+ if (re && C) {
249
+ const p = pe(i.clientX, i.clientY), a = Qe(
250
+ C.geometry,
251
+ re.polygonIndex,
252
+ re.vertexIndex,
253
+ p
254
+ );
255
+ Z(C.id, a);
256
+ return;
257
+ }
258
+ if (H) {
259
+ const p = pe(i.clientX, i.clientY);
260
+ A({
261
+ x: p.x - H.start.x,
262
+ y: p.y - H.start.y
263
+ });
264
+ return;
265
+ }
266
+ if ((c === "draw-unit" || c === "draw-line") && _.length > 0) {
267
+ const p = pe(i.clientX, i.clientY);
268
+ G((a) => a.length === 0 ? a : [a[0], p]);
269
+ }
270
+ }, ve = () => {
271
+ if (_.length < 2) {
272
+ G([]);
273
+ return;
274
+ }
275
+ const [i, p] = [_[0], _[_.length - 1]];
276
+ if (Ee(i, p) < 2) {
277
+ G([]);
278
+ return;
279
+ }
280
+ const a = an(i, p);
281
+ R("unit", be([a])), G([]);
282
+ }, ke = () => {
283
+ if (_.length < 2) {
284
+ G([]);
285
+ return;
286
+ }
287
+ const [i, p] = [_[0], _[_.length - 1]];
288
+ if (Ee(i, p) < 2) {
289
+ G([]);
290
+ return;
291
+ }
292
+ const a = {
293
+ paths: [{ d: `M ${i.x} ${i.y} L ${p.x} ${p.y}`, closed: !1 }],
294
+ polygons: []
90
295
  };
91
- O("unit", e), R([]);
92
- };
93
- return /* @__PURE__ */ r(
296
+ R("wall", a), G([]);
297
+ }, Ne = () => {
298
+ if (oe.current = null, re) {
299
+ Y(null);
300
+ return;
301
+ }
302
+ if (H && C) {
303
+ const i = Me(
304
+ H.originGeometry,
305
+ te.x,
306
+ te.y
307
+ );
308
+ Math.hypot(te.x, te.y) >= 0.5 && Z(C.id, i), q(null), A({ x: 0, y: 0 });
309
+ return;
310
+ }
311
+ if (K != null) {
312
+ const i = r.find((p) => p.id === K);
313
+ if (i) {
314
+ const p = r.filter((a) => a.id !== i.id).filter((a) => Math.hypot(a.x - i.x, a.y - i.y) <= 2.5).map((a) => a.id);
315
+ p.length && ee([i.id, ...p]);
316
+ }
317
+ U(null);
318
+ return;
319
+ }
320
+ c === "draw-unit" && ve(), c === "draw-line" && ke();
321
+ }, Ie = (i) => M === i.id && L && (H == null ? void 0 : H.shapeId) === i.id ? L.paths.map((p) => p.d).join(" ") || Oe(L.polygons) : i.geometry.paths.map((p) => p.d).join(" ") || Oe(i.geometry.polygons);
322
+ return e ? /* @__PURE__ */ o(
94
323
  "div",
95
324
  {
96
- className: "eyeon-map-canvas",
97
- onWheel: (e) => {
98
- e.preventDefault(), B((c) => Math.min(8, Math.max(0.2, c * (e.deltaY > 0 ? 0.9 : 1.1))));
325
+ className: `eyeon-map-canvas${P ? " eyeon-map-canvas--grid" : ""}`,
326
+ onWheel: (i) => {
327
+ i.preventDefault(), ne((p) => Math.min(8, Math.max(0.2, p * (i.deltaY > 0 ? 0.9 : 1.1))));
99
328
  },
100
- children: [
101
- /* @__PURE__ */ n(
102
- "svg",
103
- {
104
- ref: M,
105
- className: "eyeon-map-canvas__svg",
106
- viewBox: `${v.x} ${v.y} ${v.width} ${v.height}`,
107
- onPointerDown: X,
108
- onPointerMove: j,
109
- onPointerUp: x,
110
- onDoubleClick: () => {
111
- y === "draw-unit" && G();
112
- },
113
- children: /* @__PURE__ */ r("g", { transform: `translate(${b.x / m}, ${b.y / m}) scale(${m})`, children: [
114
- I && /* @__PURE__ */ n(
115
- "image",
116
- {
117
- href: I,
118
- x: v.x,
119
- y: v.y,
120
- width: v.width,
121
- height: v.height,
122
- opacity: 0.85
123
- }
124
- ),
125
- l.map((e) => /* @__PURE__ */ n(
126
- "path",
127
- {
128
- d: e.geometry.paths.map((c) => c.d).join(" ") || F(e.geometry.polygons),
129
- fill: e.style.fill ?? (e.kind === "walkable" ? f.WALKABLE_COLOR : e.kind === "unit" ? f.STORE_DEFAULT_COLOR : "#cbd5e1"),
130
- fillOpacity: e.kind === "amenity" ? 0.15 : 0.85,
131
- stroke: D === e.id ? f.ACCENT_COLOR : "#64748b",
132
- strokeWidth: D === e.id ? 2.5 / m : 1 / m,
133
- onClick: (c) => {
134
- c.stopPropagation(), y === "select" && C(e.id);
135
- },
136
- style: { cursor: y === "select" ? "pointer" : "default" }
329
+ children: /* @__PURE__ */ o(
330
+ "svg",
331
+ {
332
+ ref: F,
333
+ className: "eyeon-map-canvas__svg",
334
+ viewBox: `${X.x} ${X.y} ${X.width} ${X.height}`,
335
+ onPointerDown: ge,
336
+ onPointerMove: ye,
337
+ onPointerUp: Ne,
338
+ children: /* @__PURE__ */ s("g", { transform: `translate(${j.x}, ${j.y}) scale(${v})`, children: [
339
+ me && /* @__PURE__ */ o(
340
+ "image",
341
+ {
342
+ href: me,
343
+ x: (T ?? X).x,
344
+ y: (T ?? X).y,
345
+ width: (T ?? X).width,
346
+ height: (T ?? X).height,
347
+ opacity: 0.85,
348
+ pointerEvents: "none"
349
+ }
350
+ ),
351
+ b.map((i) => /* @__PURE__ */ o(
352
+ "path",
353
+ {
354
+ d: i.geometry.paths.map((p) => p.d).join(" ") || Oe(i.geometry.polygons),
355
+ fill: i.style.fill ?? (i.kind === "walkable" ? t.WALKABLE_COLOR : i.kind === "unit" ? t.STORE_DEFAULT_COLOR : "#cbd5e1"),
356
+ fillOpacity: 0.45,
357
+ stroke: "#94a3b8",
358
+ strokeWidth: 1 / v,
359
+ pointerEvents: "none"
360
+ },
361
+ `base-${i.id}`
362
+ )),
363
+ g.map((i) => /* @__PURE__ */ o(
364
+ "path",
365
+ {
366
+ d: Ie(i),
367
+ fill: i.style.fill ?? (i.kind === "walkable" ? t.WALKABLE_COLOR : i.kind === "unit" ? t.STORE_DEFAULT_COLOR : "#cbd5e1"),
368
+ fillOpacity: i.kind === "amenity" ? 0.15 : 0.85,
369
+ stroke: M === i.id ? t.ACCENT_COLOR : "#64748b",
370
+ strokeWidth: M === i.id ? 2.5 / v : 1 / v,
371
+ onPointerDown: (p) => {
372
+ var m, k;
373
+ if (c !== "select") return;
374
+ p.stopPropagation(), Q(i.id);
375
+ const a = pe(p.clientX, p.clientY);
376
+ q({
377
+ shapeId: i.id,
378
+ start: a,
379
+ originGeometry: i.geometry
380
+ }), A({ x: 0, y: 0 }), (k = (m = p.currentTarget).setPointerCapture) == null || k.call(m, p.pointerId);
137
381
  },
138
- e.id
139
- )),
140
- d.map((e) => {
141
- const c = Y.get(e.fromAnchorId), s = Y.get(e.toAnchorId);
142
- return !c || !s ? null : /* @__PURE__ */ n(
143
- "line",
144
- {
145
- x1: c.x,
146
- y1: c.y,
147
- x2: s.x,
148
- y2: s.y,
149
- stroke: f.ACCENT_COLOR,
150
- strokeWidth: 2 / m,
151
- strokeLinecap: "round"
152
- },
153
- e.id
154
- );
155
- }),
156
- p.map((e) => {
157
- const c = _.includes(e.id), s = c && _.some((L) => {
158
- if (L === e.id) return !1;
159
- const T = Y.get(L);
160
- return T && Math.hypot(T.x - e.x, T.y - e.y) <= 2.5;
161
- });
162
- return /* @__PURE__ */ n(
382
+ style: { cursor: c === "select" ? "grab" : "default" }
383
+ },
384
+ i.id
385
+ )),
386
+ C && (L ?? C.geometry).polygons.map(
387
+ (i, p) => i.map((a, m) => {
388
+ const k = (E == null ? void 0 : E.polygonIndex) === p && (E == null ? void 0 : E.vertexIndex) === m;
389
+ return /* @__PURE__ */ o(
163
390
  "circle",
164
391
  {
165
- cx: e.x,
166
- cy: e.y,
167
- r: (c ? 5 : 3.5) / m,
168
- fill: s ? "#22c55e" : c ? f.ACCENT_COLOR : "#0f172a",
169
- stroke: "#fff",
170
- strokeWidth: 1 / m,
171
- onPointerDown: (L) => {
172
- if (L.stopPropagation(), y === "draw-route") {
173
- o(e.id), u(e, $);
174
- return;
175
- }
176
- y === "select" && (t(
177
- L.shiftKey ? _.includes(e.id) ? _.filter((T) => T !== e.id) : [..._, e.id] : [e.id]
178
- ), U(e.id));
392
+ cx: a.x,
393
+ cy: a.y,
394
+ r: (k ? 6 : 5) / v,
395
+ fill: k ? t.ACCENT_COLOR : "#fff",
396
+ stroke: t.ACCENT_COLOR,
397
+ strokeWidth: 1.5 / v,
398
+ onPointerDown: (I) => {
399
+ var O, d;
400
+ c === "select" && (I.stopPropagation(), le({ polygonIndex: p, vertexIndex: m }), Y({
401
+ shapeId: C.id,
402
+ polygonIndex: p,
403
+ vertexIndex: m
404
+ }), (d = (O = I.currentTarget).setPointerCapture) == null || d.call(O, I.pointerId));
179
405
  },
180
- style: { cursor: "grab" }
406
+ style: { cursor: "crosshair" }
181
407
  },
182
- e.id
408
+ `v-${C.id}-${p}-${m}`
183
409
  );
184
- }),
185
- k.length > 1 && /* @__PURE__ */ n(
410
+ })
411
+ ),
412
+ l.map((i) => {
413
+ const p = z.get(i.fromAnchorId), a = z.get(i.toAnchorId);
414
+ return !p || !a ? null : /* @__PURE__ */ o(
415
+ "line",
416
+ {
417
+ x1: p.x,
418
+ y1: p.y,
419
+ x2: a.x,
420
+ y2: a.y,
421
+ stroke: t.ACCENT_COLOR,
422
+ strokeWidth: 2 / v,
423
+ strokeLinecap: "round"
424
+ },
425
+ i.id
426
+ );
427
+ }),
428
+ r.map((i) => {
429
+ const p = x.includes(i.id), a = p && x.some((m) => {
430
+ if (m === i.id) return !1;
431
+ const k = z.get(m);
432
+ return k && Math.hypot(k.x - i.x, k.y - i.y) <= 2.5;
433
+ });
434
+ return /* @__PURE__ */ o(
435
+ "circle",
436
+ {
437
+ cx: i.x,
438
+ cy: i.y,
439
+ r: (p ? 5 : 3.5) / v,
440
+ fill: a ? "#22c55e" : p ? t.ACCENT_COLOR : "#0f172a",
441
+ stroke: "#fff",
442
+ strokeWidth: 1 / v,
443
+ onPointerDown: (m) => {
444
+ if (m.stopPropagation(), c === "draw-route") {
445
+ ue(i.id), $(i, ce);
446
+ return;
447
+ }
448
+ c === "select" && (ee(
449
+ m.shiftKey ? x.includes(i.id) ? x.filter((k) => k !== i.id) : [...x, i.id] : [i.id]
450
+ ), U(i.id));
451
+ },
452
+ style: { cursor: "grab" }
453
+ },
454
+ i.id
455
+ );
456
+ }),
457
+ _.length > 1 && c === "draw-unit" && /* @__PURE__ */ o(
458
+ "rect",
459
+ {
460
+ x: Math.min(_[0].x, _[1].x),
461
+ y: Math.min(_[0].y, _[1].y),
462
+ width: Math.abs(_[1].x - _[0].x),
463
+ height: Math.abs(_[1].y - _[0].y),
464
+ fill: t.STORE_DEFAULT_COLOR,
465
+ fillOpacity: 0.2,
466
+ stroke: t.ACCENT_COLOR,
467
+ strokeWidth: 2 / v,
468
+ strokeDasharray: `${6 / v} ${4 / v}`
469
+ }
470
+ ),
471
+ _.length > 1 && c === "draw-line" && /* @__PURE__ */ o(
472
+ "line",
473
+ {
474
+ x1: _[0].x,
475
+ y1: _[0].y,
476
+ x2: _[1].x,
477
+ y2: _[1].y,
478
+ stroke: t.ACCENT_COLOR,
479
+ strokeWidth: 2 / v,
480
+ strokeDasharray: `${6 / v} ${4 / v}`,
481
+ strokeLinecap: "round"
482
+ }
483
+ ),
484
+ V.length > 0 && c === "draw-polygon" && /* @__PURE__ */ s(de, { children: [
485
+ /* @__PURE__ */ o(
186
486
  "polyline",
187
487
  {
188
- points: k.map((e) => `${e.x},${e.y}`).join(" "),
488
+ points: V.map((i) => `${i.x},${i.y}`).join(" "),
189
489
  fill: "none",
190
- stroke: f.ACCENT_COLOR,
191
- strokeWidth: 2 / m,
192
- strokeDasharray: `${6 / m} ${4 / m}`
490
+ stroke: t.ACCENT_COLOR,
491
+ strokeWidth: 2 / v,
492
+ strokeDasharray: `${6 / v} ${4 / v}`
193
493
  }
194
- )
494
+ ),
495
+ V.map((i, p) => /* @__PURE__ */ o(
496
+ "circle",
497
+ {
498
+ cx: i.x,
499
+ cy: i.y,
500
+ r: (p === 0 ? 5 : 3.5) / v,
501
+ fill: p === 0 ? t.ACCENT_COLOR : "#fff",
502
+ stroke: t.ACCENT_COLOR,
503
+ strokeWidth: 1 / v
504
+ },
505
+ `pp-${p}`
506
+ ))
195
507
  ] })
196
- }
197
- ),
198
- !i && /* @__PURE__ */ n("div", { className: "eyeon-map-canvas__empty", children: "Select or create a level to begin" })
508
+ ] })
509
+ }
510
+ )
511
+ }
512
+ ) : /* @__PURE__ */ o("div", { className: `eyeon-map-canvas${P ? " eyeon-map-canvas--grid" : ""}`, children: /* @__PURE__ */ o("div", { className: "eyeon-map-canvas__empty", children: "Choose a floor or Outdoor to edit" }) });
513
+ }
514
+ function cn(e) {
515
+ const n = ((e == null ? void 0 : e.polygons) ?? []).flat();
516
+ return Ye(n);
517
+ }
518
+ function Ae(e, n) {
519
+ const r = e.findIndex((t) => t.id === n.id);
520
+ if (r < 0) return [...e, n];
521
+ const l = e.slice();
522
+ return l[r] = n, l;
523
+ }
524
+ function un(e, n) {
525
+ switch (n.op) {
526
+ case "upsert_shape": {
527
+ const r = n.shape, l = r.id;
528
+ if (l == null) return e;
529
+ const t = e.shapes.find((M) => M.id === l), c = r.geometry ?? (t == null ? void 0 : t.geometry) ?? {
530
+ paths: [],
531
+ polygons: []
532
+ }, y = {
533
+ id: l,
534
+ levelId: r.levelId ?? (t == null ? void 0 : t.levelId) ?? 0,
535
+ key: r.key ?? (t == null ? void 0 : t.key) ?? `shape-${l}`,
536
+ kind: r.kind ?? (t == null ? void 0 : t.kind) ?? "unit",
537
+ geometry: c,
538
+ bbox: r.bbox ?? (t == null ? void 0 : t.bbox) ?? cn(c),
539
+ zIndex: r.zIndex ?? (t == null ? void 0 : t.zIndex) ?? 0,
540
+ style: r.style ?? (t == null ? void 0 : t.style) ?? {},
541
+ label: r.label ?? (t == null ? void 0 : t.label) ?? {},
542
+ sourceSvgId: r.sourceSvgId ?? (t == null ? void 0 : t.sourceSvgId) ?? null,
543
+ origin: r.origin ?? (t == null ? void 0 : t.origin) ?? "manual",
544
+ geometryLocked: r.geometryLocked ?? (r.geometry != null ? !0 : t == null ? void 0 : t.geometryLocked) ?? !1,
545
+ orphanedAt: r.orphanedAt ?? (t == null ? void 0 : t.orphanedAt) ?? null
546
+ };
547
+ return { ...e, shapes: Ae(e.shapes, y) };
548
+ }
549
+ case "delete_shape":
550
+ return {
551
+ ...e,
552
+ shapes: e.shapes.filter((r) => r.id !== n.shapeId),
553
+ assignments: e.assignments.filter((r) => r.shapeId !== n.shapeId)
554
+ };
555
+ case "upsert_assignment": {
556
+ const r = {
557
+ shapeId: n.assignment.shapeId,
558
+ targetType: n.assignment.targetType ?? "none",
559
+ retailerId: n.assignment.retailerId ?? null,
560
+ amenityId: n.assignment.amenityId ?? null,
561
+ kioskId: n.assignment.kioskId ?? null,
562
+ unitStatus: n.assignment.unitStatus ?? "vacant",
563
+ unitNumber: n.assignment.unitNumber ?? null,
564
+ customLabel: n.assignment.customLabel ?? null,
565
+ customImageKey: n.assignment.customImageKey ?? null
566
+ }, l = e.assignments.filter((t) => t.shapeId !== r.shapeId);
567
+ return { ...e, assignments: [...l, r] };
568
+ }
569
+ case "delete_assignment":
570
+ return {
571
+ ...e,
572
+ assignments: e.assignments.filter((r) => r.shapeId !== n.shapeId)
573
+ };
574
+ case "upsert_anchor": {
575
+ const r = n.anchor, l = r.id;
576
+ if (l == null) return e;
577
+ const t = e.anchors.find((y) => y.id === l), c = {
578
+ id: l,
579
+ levelId: r.levelId ?? (t == null ? void 0 : t.levelId) ?? 0,
580
+ shapeId: r.shapeId ?? (t == null ? void 0 : t.shapeId) ?? null,
581
+ kind: r.kind ?? (t == null ? void 0 : t.kind) ?? "junction",
582
+ x: r.x ?? (t == null ? void 0 : t.x) ?? 0,
583
+ y: r.y ?? (t == null ? void 0 : t.y) ?? 0,
584
+ connectorId: r.connectorId ?? (t == null ? void 0 : t.connectorId) ?? null
585
+ };
586
+ return { ...e, anchors: Ae(e.anchors, c) };
587
+ }
588
+ case "delete_anchor":
589
+ return {
590
+ ...e,
591
+ anchors: e.anchors.filter((r) => r.id !== n.anchorId),
592
+ edges: e.edges.filter(
593
+ (r) => r.fromAnchorId !== n.anchorId && r.toAnchorId !== n.anchorId
594
+ )
595
+ };
596
+ case "upsert_edge": {
597
+ const r = n.edge, l = r.id;
598
+ if (l == null) return e;
599
+ const t = e.edges.find((y) => y.id === l), c = {
600
+ id: l,
601
+ mapId: r.mapId ?? (t == null ? void 0 : t.mapId) ?? e.mapId,
602
+ fromAnchorId: r.fromAnchorId ?? (t == null ? void 0 : t.fromAnchorId) ?? 0,
603
+ toAnchorId: r.toAnchorId ?? (t == null ? void 0 : t.toAnchorId) ?? 0,
604
+ weight: r.weight ?? (t == null ? void 0 : t.weight) ?? null,
605
+ directed: r.directed ?? (t == null ? void 0 : t.directed) ?? !1,
606
+ accessible: r.accessible ?? (t == null ? void 0 : t.accessible) ?? !0,
607
+ kind: r.kind ?? (t == null ? void 0 : t.kind) ?? "walk"
608
+ };
609
+ return { ...e, edges: Ae(e.edges, c) };
610
+ }
611
+ case "delete_edge":
612
+ return { ...e, edges: e.edges.filter((r) => r.id !== n.edgeId) };
613
+ case "weld_anchors": {
614
+ const r = (n.anchorIds ?? []).filter((y) => Number.isFinite(y));
615
+ if (r.length < 2) return e;
616
+ const l = r[0], t = new Set(r.slice(1)), c = e.edges.map((y) => ({
617
+ ...y,
618
+ fromAnchorId: t.has(y.fromAnchorId) ? l : y.fromAnchorId,
619
+ toAnchorId: t.has(y.toAnchorId) ? l : y.toAnchorId
620
+ })).filter((y) => y.fromAnchorId !== y.toAnchorId);
621
+ return {
622
+ ...e,
623
+ anchors: e.anchors.filter((y) => !t.has(y.id)),
624
+ edges: c
625
+ };
626
+ }
627
+ case "update_theme":
628
+ return { ...e, theme: { ...e.theme, ...n.theme } };
629
+ default:
630
+ return e;
631
+ }
632
+ }
633
+ function pn(e, n) {
634
+ return n.reduce(un, hn(e));
635
+ }
636
+ function hn(e) {
637
+ let n = !1;
638
+ const r = e.shapes.map((l) => {
639
+ const t = Fe(l.geometry);
640
+ return t === l.geometry ? l : (n = !0, { ...l, geometry: t, bbox: je(t) });
641
+ });
642
+ return n ? { ...e, shapes: r } : e;
643
+ }
644
+ function mn(e, n) {
645
+ if (n.op === "update_theme") {
646
+ const r = e.filter((c) => c.op === "update_theme"), l = e.filter((c) => c.op !== "update_theme"), t = r.reduce(
647
+ (c, y) => y.op === "update_theme" ? { ...c, ...y.theme } : c,
648
+ {}
649
+ );
650
+ return [...l, { op: "update_theme", theme: { ...t, ...n.theme } }];
651
+ }
652
+ if (n.op === "upsert_shape" && n.shape.id != null) {
653
+ const r = e.findIndex(
654
+ (l) => l.op === "upsert_shape" && l.shape.id === n.shape.id
655
+ );
656
+ if (r >= 0 && e[r].op === "upsert_shape") {
657
+ const l = e.slice();
658
+ return l[r] = {
659
+ op: "upsert_shape",
660
+ shape: { ...e[r].shape, ...n.shape }
661
+ }, l;
662
+ }
663
+ }
664
+ if (n.op === "upsert_anchor" && n.anchor.id != null) {
665
+ const r = e.findIndex(
666
+ (l) => l.op === "upsert_anchor" && l.anchor.id === n.anchor.id
667
+ );
668
+ if (r >= 0 && e[r].op === "upsert_anchor") {
669
+ const l = e.slice();
670
+ return l[r] = {
671
+ op: "upsert_anchor",
672
+ anchor: { ...e[r].anchor, ...n.anchor }
673
+ }, l;
674
+ }
675
+ }
676
+ if (n.op === "upsert_assignment") {
677
+ const r = e.findIndex(
678
+ (l) => l.op === "upsert_assignment" && l.assignment.shapeId === n.assignment.shapeId
679
+ );
680
+ if (r >= 0 && e[r].op === "upsert_assignment") {
681
+ const l = e.slice();
682
+ return l[r] = { op: "upsert_assignment", assignment: n.assignment }, l;
683
+ }
684
+ }
685
+ return [...e, n];
686
+ }
687
+ const Te = {
688
+ unit: "Store",
689
+ amenity: "Amenity",
690
+ kiosk_screen: "Kiosk",
691
+ connector: "Connector",
692
+ entrance: "Entrance",
693
+ walkable: "Walkway",
694
+ void: "Opening",
695
+ wall: "Wall",
696
+ boundary: "Boundary",
697
+ floorplate: "Floor plate",
698
+ decor: "Decor",
699
+ label: "Label",
700
+ zone: "Zone",
701
+ parking_zone: "Parking",
702
+ green_area: "Green area",
703
+ water: "Water",
704
+ parking_icon: "Parking icon"
705
+ }, Be = {
706
+ occupied: "Occupied",
707
+ vacant: "Vacant",
708
+ coming_soon: "Coming soon",
709
+ under_renovation: "Under renovation"
710
+ };
711
+ function yn(e) {
712
+ return Te[e] ?? e;
713
+ }
714
+ function fn(e, n) {
715
+ if (e.mode === "add-base") return "Add Outdoor SVG";
716
+ if (e.mode === "add-floor") return "Add Floor";
717
+ if (e.mode === "edit") {
718
+ const r = n.find((l) => l.id === e.levelId);
719
+ return (r == null ? void 0 : r.kind) === "outdoor" ? "Edit Outdoor" : "Edit Floor";
720
+ }
721
+ return "Floors";
722
+ }
723
+ function _n(e) {
724
+ return e.filter((n) => n.kind === "floor").length;
725
+ }
726
+ function gn(e, n, r) {
727
+ if (e.indexOf(n) < 0) return e;
728
+ const t = e.filter((M) => M !== n), c = Math.max(0, Math.min(r, t.length)), y = [...t];
729
+ return y.splice(c, 0, n), y;
730
+ }
731
+ function Le(e, n) {
732
+ return e.length === n.length && e.every((r, l) => r === n[l]);
733
+ }
734
+ function Se(e) {
735
+ return e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} KB` : `${(e / (1024 * 1024)).toFixed(1)} MB`;
736
+ }
737
+ function vn(e) {
738
+ var r;
739
+ return e && ((r = e.split("/").pop()) == null ? void 0 : r.trim()) || null;
740
+ }
741
+ function kn(e) {
742
+ return e.name.toLowerCase().endsWith(".svg") || e.type === "image/svg+xml";
743
+ }
744
+ function $e() {
745
+ return /* @__PURE__ */ o("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": "true", children: /* @__PURE__ */ o(
746
+ "path",
747
+ {
748
+ d: "M3 5h12M3 9h12M3 13h12",
749
+ fill: "none",
750
+ stroke: "currentColor",
751
+ strokeWidth: "2",
752
+ strokeLinecap: "round"
753
+ }
754
+ ) });
755
+ }
756
+ function De() {
757
+ return /* @__PURE__ */ s(
758
+ "svg",
759
+ {
760
+ width: "18",
761
+ height: "18",
762
+ viewBox: "0 0 24 24",
763
+ fill: "none",
764
+ stroke: "currentColor",
765
+ strokeWidth: "2",
766
+ strokeLinecap: "round",
767
+ strokeLinejoin: "round",
768
+ "aria-hidden": "true",
769
+ children: [
770
+ /* @__PURE__ */ o("polyline", { points: "3 6 5 6 21 6" }),
771
+ /* @__PURE__ */ o("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }),
772
+ /* @__PURE__ */ o("line", { x1: "10", y1: "11", x2: "10", y2: "17" }),
773
+ /* @__PURE__ */ o("line", { x1: "14", y1: "11", x2: "14", y2: "17" })
199
774
  ]
200
775
  }
201
776
  );
202
777
  }
203
- const te = [
204
- { id: "levels", label: "Levels" },
205
- { id: "shapes", label: "Shapes" },
206
- { id: "routes", label: "Routes" },
207
- { id: "amenities", label: "Amenities" },
208
- { id: "kiosks", label: "Kiosks" },
209
- { id: "theme", label: "Theme" }
210
- ];
211
- function re({
212
- tab: i,
213
- onTabChange: l,
214
- draft: p,
215
- activeLevelId: d,
216
- onSelectLevel: f,
217
- canFloors: y,
218
- canSettings: K,
219
- onImportSvg: D,
220
- onAutoroute: _,
221
- theme: I,
222
- onThemeChange: C
778
+ function bn(e, n = 0) {
779
+ const r = e.kind === "outdoor", l = n === 1 ? "1 shape" : `${n} shapes`;
780
+ return {
781
+ title: r ? "Delete Outdoor SVG?" : `Delete “${e.name}”?`,
782
+ body: r ? `The stored outdoor SVG, its ${l} and every assignment on them are removed. Building floors are not affected.` : `This floor and its ${l} are removed, along with the retailer, amenity and kiosk assignments on them.`,
783
+ action: r ? "Delete Outdoor" : "Delete floor"
784
+ };
785
+ }
786
+ function Nn({
787
+ levels: e,
788
+ buildings: n,
789
+ levelShapeCounts: r,
790
+ canFloors: l,
791
+ screen: t,
792
+ onScreenChange: c,
793
+ onCreateLevel: y,
794
+ onUpdateLevel: M,
795
+ onDeleteLevel: x,
796
+ onReorderLevels: N
223
797
  }) {
224
- return /* @__PURE__ */ r("aside", { className: "eyeon-map-rail", children: [
225
- /* @__PURE__ */ n("nav", { className: "eyeon-map-rail__tabs", children: te.map((t) => /* @__PURE__ */ n(
226
- "button",
227
- {
228
- type: "button",
229
- className: i === t.id ? "is-active" : "",
230
- onClick: () => l(t.id),
231
- children: t.label
798
+ const [T, J] = w(""), [b, S] = w(null), [P, Q] = w(!1), [ee, $] = w(null), [W, R] = w(null), [Z, F] = w(!1), [j, B] = w(null), [v, ne] = w(!1), [_, G] = w(null), [V, u] = w(null), [K, U] = w(!1), [ce, ue] = w(null), H = he(null), q = he(null), te = he(/* @__PURE__ */ new Map()), A = he(null), re = he(null), Y = se(
799
+ () => e.find((a) => a.kind === "outdoor") ?? null,
800
+ [e]
801
+ ), E = !!(Y != null && Y.sourceSvgKey || Y != null && Y.sourceSvgUrl), le = (a) => (r == null ? void 0 : r[a]) ?? 0, oe = se(
802
+ () => e.filter((a) => a.kind === "floor").slice().sort(Xe),
803
+ [e]
804
+ ), X = se(
805
+ () => oe.map((a) => a.id),
806
+ [oe]
807
+ ), me = se(() => {
808
+ const a = V ?? X, m = new Map(oe.map((k) => [k.id, k]));
809
+ return a.map((k) => m.get(k)).filter((k) => k != null);
810
+ }, [oe, X, V]), g = t.mode === "edit" ? e.find((a) => a.id === t.levelId) ?? null : null, C = t.mode === "add-base" || (g == null ? void 0 : g.kind) === "outdoor", L = l && !!y && !!M, pe = L && !!N && oe.length > 1;
811
+ ae(() => {
812
+ t.mode === "add-base" || (g == null ? void 0 : g.kind) === "outdoor" ? (J("Outdoor"), S(null)) : t.mode === "add-floor" ? (J(""), S(null)) : t.mode === "edit" && g && (J(g.name), S(null)), $(null), B(null), ne(!1), R(null), U(!1);
813
+ }, [t, g == null ? void 0 : g.id, g == null ? void 0 : g.kind, g == null ? void 0 : g.name]), ae(() => {
814
+ if (j == null) return;
815
+ const a = (m) => {
816
+ m.key === "Escape" && !v && B(null);
817
+ };
818
+ return window.addEventListener("keydown", a), () => window.removeEventListener("keydown", a);
819
+ }, [j, v]), ae(() => {
820
+ if (!b) {
821
+ ue(null);
822
+ return;
823
+ }
824
+ const a = URL.createObjectURL(b);
825
+ return ue(a), U(!1), () => URL.revokeObjectURL(a);
826
+ }, [b]), A.current = V, re.current = _, ae(() => {
827
+ _ != null || V == null || Le(X, V) && u(null);
828
+ }, [X, _, V]), Ge(() => {
829
+ const a = q.current;
830
+ if (!a) return;
831
+ const m = a.querySelectorAll("[data-floor-id]"), k = /* @__PURE__ */ new Map();
832
+ m.forEach((I) => {
833
+ const O = Number(I.dataset.floorId);
834
+ if (!Number.isFinite(O)) return;
835
+ const d = I.getBoundingClientRect().top;
836
+ k.set(O, d);
837
+ const h = te.current.get(O);
838
+ if (h == null || _ == null) return;
839
+ const f = h - d;
840
+ Math.abs(f) < 1 || (I.style.transition = "none", I.style.transform = `translateY(${f}px)`, requestAnimationFrame(() => {
841
+ I.style.transition = "transform 180ms ease", I.style.transform = "";
842
+ }));
843
+ }), te.current = k;
844
+ }, [me, _]);
845
+ const z = (a) => {
846
+ if (a) {
847
+ if (!kn(a)) {
848
+ $("Choose an SVG file.");
849
+ return;
850
+ }
851
+ $(null), S(a);
852
+ }
853
+ }, fe = (a) => {
854
+ c({ mode: "edit", levelId: a.id });
855
+ }, ge = async (a) => {
856
+ var k;
857
+ const m = b;
858
+ if (C) {
859
+ if (!m && (t.mode === "add-base" || !(g != null && g.sourceSvgKey))) {
860
+ $("Choose an SVG file.");
861
+ return;
862
+ }
863
+ } else if (!T.trim()) {
864
+ $("Enter a title.");
865
+ return;
866
+ }
867
+ if (t.mode === "add-floor" && !m) {
868
+ $("Choose an SVG file.");
869
+ return;
870
+ }
871
+ Q(!0), $(null), m && R(0);
872
+ try {
873
+ t.mode === "add-base" ? await (y == null ? void 0 : y({
874
+ name: "Outdoor",
875
+ kind: "outdoor",
876
+ file: m ?? void 0,
877
+ onProgress: R
878
+ })) : t.mode === "add-floor" ? await (y == null ? void 0 : y({
879
+ name: T.trim(),
880
+ kind: "floor",
881
+ buildingId: ((k = n[0]) == null ? void 0 : k.id) ?? null,
882
+ file: m ?? void 0,
883
+ onProgress: R
884
+ })) : t.mode === "edit" && g && await (M == null ? void 0 : M({
885
+ levelId: g.id,
886
+ name: g.kind === "outdoor" ? "Outdoor" : T.trim(),
887
+ file: m ?? void 0,
888
+ onProgress: R
889
+ })), R(100), c({ mode: "list" });
890
+ } catch (I) {
891
+ $(I instanceof Error ? I.message : "Could not save floor."), R(null);
892
+ } finally {
893
+ Q(!1);
894
+ }
895
+ }, ye = async (a) => {
896
+ if (!(!x || v)) {
897
+ ne(!0), $(null);
898
+ try {
899
+ await x(a.id), B(null), c({ mode: "list" });
900
+ } catch (m) {
901
+ $(m instanceof Error ? m.message : "Could not delete floor.");
902
+ } finally {
903
+ ne(!1);
904
+ }
905
+ }
906
+ }, ve = () => {
907
+ const a = e.find((k) => k.id === j);
908
+ if (!a) return null;
909
+ const m = bn(a, le(a.id));
910
+ return /* @__PURE__ */ s("div", { className: "eyeon-map-modal", role: "presentation", children: [
911
+ /* @__PURE__ */ o(
912
+ "div",
913
+ {
914
+ className: "eyeon-map-modal__backdrop",
915
+ onClick: () => v ? void 0 : B(null)
916
+ }
917
+ ),
918
+ /* @__PURE__ */ s(
919
+ "div",
920
+ {
921
+ className: "eyeon-map-modal__card",
922
+ role: "alertdialog",
923
+ "aria-modal": "true",
924
+ "aria-labelledby": "eyeon-map-delete-title",
925
+ "aria-describedby": "eyeon-map-delete-body",
926
+ children: [
927
+ /* @__PURE__ */ o("h3", { className: "eyeon-map-modal__title", id: "eyeon-map-delete-title", children: m.title }),
928
+ /* @__PURE__ */ s("p", { className: "eyeon-map-modal__body", id: "eyeon-map-delete-body", children: [
929
+ m.body,
930
+ " This cannot be undone."
931
+ ] }),
932
+ ee ? /* @__PURE__ */ o("div", { className: "eyeon-map-floors__error", children: ee }) : null,
933
+ /* @__PURE__ */ s("div", { className: "eyeon-map-modal__actions", children: [
934
+ /* @__PURE__ */ o(
935
+ "button",
936
+ {
937
+ type: "button",
938
+ className: "eyeon-map-modal__cancel",
939
+ disabled: v,
940
+ onClick: () => B(null),
941
+ children: "Cancel"
942
+ }
943
+ ),
944
+ /* @__PURE__ */ o(
945
+ "button",
946
+ {
947
+ type: "button",
948
+ className: "eyeon-map-floors__danger",
949
+ disabled: v,
950
+ autoFocus: !0,
951
+ onClick: () => void ye(a),
952
+ children: v ? /* @__PURE__ */ s(de, { children: [
953
+ /* @__PURE__ */ o("span", { className: "eyeon-map-floors__spinner", "aria-hidden": "true" }),
954
+ "Deleting…"
955
+ ] }) : m.action
956
+ }
957
+ )
958
+ ] })
959
+ ]
960
+ }
961
+ )
962
+ ] });
963
+ }, ke = (a) => !L || !x ? null : /* @__PURE__ */ o(
964
+ "button",
965
+ {
966
+ type: "button",
967
+ className: "eyeon-map-floors__icon-danger",
968
+ title: `Delete ${a.kind === "outdoor" ? "Outdoor SVG" : a.name}`,
969
+ "aria-label": `Delete ${a.kind === "outdoor" ? "Outdoor SVG" : a.name}`,
970
+ disabled: P || v,
971
+ onClick: (m) => {
972
+ m.stopPropagation(), B(a.id);
232
973
  },
233
- t.id
234
- )) }),
235
- /* @__PURE__ */ r("div", { className: "eyeon-map-rail__body", children: [
236
- i === "levels" && /* @__PURE__ */ r("div", { className: "eyeon-map-rail__section", children: [
237
- /* @__PURE__ */ n("div", { className: "eyeon-map-rail__heading", children: "Buildings" }),
238
- p.buildings.map((t) => /* @__PURE__ */ r("div", { className: "eyeon-map-rail__group", children: [
239
- /* @__PURE__ */ n("div", { className: "eyeon-map-rail__group-title", children: t.name }),
240
- p.levels.filter((u) => u.buildingId === t.id).map((u) => /* @__PURE__ */ n(
974
+ children: /* @__PURE__ */ o(De, {})
975
+ }
976
+ ), Ne = (a) => {
977
+ const m = re.current, k = q.current;
978
+ if (!m || !k) return;
979
+ const I = A.current ?? X, O = I.filter((f) => f !== m.id);
980
+ let d = O.length;
981
+ for (let f = 0; f < O.length; f += 1) {
982
+ const D = k.querySelector(`[data-floor-id="${O[f]}"]`);
983
+ if (!D) continue;
984
+ const ie = D.getBoundingClientRect();
985
+ if (a < ie.top + ie.height / 2) {
986
+ d = f;
987
+ break;
988
+ }
989
+ }
990
+ const h = gn(I, m.id, d);
991
+ Le(I, h) || u(h);
992
+ }, Ie = async () => {
993
+ const a = A.current;
994
+ if (!(!N || a == null)) {
995
+ if (Le(a, X)) {
996
+ u(null);
997
+ return;
998
+ }
999
+ try {
1000
+ await N(a);
1001
+ } catch (m) {
1002
+ u(null), $(m instanceof Error ? m.message : "Could not reorder floors.");
1003
+ }
1004
+ }
1005
+ }, i = () => {
1006
+ re.current && (re.current = null, G(null), Ie());
1007
+ };
1008
+ ae(() => {
1009
+ if (!_) return;
1010
+ const a = (k) => {
1011
+ const I = re.current;
1012
+ if (!I || k.pointerId !== I.pointerId) return;
1013
+ const O = {
1014
+ ...I,
1015
+ x: k.clientX - I.offsetX,
1016
+ y: k.clientY - I.offsetY
1017
+ };
1018
+ re.current = O, G(O), Ne(k.clientY);
1019
+ }, m = (k) => {
1020
+ const I = re.current;
1021
+ !I || k.pointerId !== I.pointerId || i();
1022
+ };
1023
+ return window.addEventListener("pointermove", a), window.addEventListener("pointerup", m), window.addEventListener("pointercancel", m), () => {
1024
+ window.removeEventListener("pointermove", a), window.removeEventListener("pointerup", m), window.removeEventListener("pointercancel", m);
1025
+ };
1026
+ }, [!!_]);
1027
+ const p = (a, m) => {
1028
+ const k = m.currentTarget.closest(".eyeon-map-floors__row");
1029
+ if (!(k instanceof HTMLElement)) return;
1030
+ const I = k.getBoundingClientRect();
1031
+ m.preventDefault(), m.stopPropagation(), m.currentTarget.setPointerCapture(m.pointerId);
1032
+ const O = {
1033
+ id: a.id,
1034
+ pointerId: m.pointerId,
1035
+ offsetX: m.clientX - I.left,
1036
+ offsetY: m.clientY - I.top,
1037
+ width: I.width,
1038
+ height: I.height,
1039
+ name: a.name,
1040
+ x: I.left,
1041
+ y: I.top
1042
+ };
1043
+ re.current = O, G(O), u(X);
1044
+ };
1045
+ if (t.mode !== "list") {
1046
+ const a = !!(g != null && g.sourceSvgKey || g != null && g.sourceSvgUrl), m = t.mode === "edit" && a, k = ce ?? (m ? (g == null ? void 0 : g.sourceSvgUrl) ?? null : null), I = (b == null ? void 0 : b.name) ?? vn(g == null ? void 0 : g.sourceSvgKey) ?? "SVG on file", O = g ? le(g.id) : 0, d = !C && t.mode === "edit" && O > 0, h = C ? "Upload" : "Import", f = C ? "Uploading" : "Importing";
1047
+ return /* @__PURE__ */ s("div", { className: "eyeon-map-floors", children: [
1048
+ !C && /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1049
+ "Title",
1050
+ /* @__PURE__ */ o(
1051
+ "input",
1052
+ {
1053
+ value: T,
1054
+ disabled: P || !L,
1055
+ onChange: (D) => J(D.target.value)
1056
+ }
1057
+ )
1058
+ ] }),
1059
+ m ? /* @__PURE__ */ s("div", { className: "eyeon-map-rail__field eyeon-map-floors__svg-field", children: [
1060
+ "SVG",
1061
+ /* @__PURE__ */ o("div", { className: "eyeon-map-floors__preview-card", children: k && !K ? /* @__PURE__ */ o(
1062
+ "img",
1063
+ {
1064
+ className: "eyeon-map-floors__preview-img",
1065
+ src: k,
1066
+ alt: (b == null ? void 0 : b.name) ?? (g == null ? void 0 : g.name) ?? "SVG preview",
1067
+ onError: () => U(!0)
1068
+ }
1069
+ ) : /* @__PURE__ */ o("div", { className: "eyeon-map-floors__preview-fallback", children: I }) }),
1070
+ b ? /* @__PURE__ */ s("span", { className: "eyeon-map-floors__drop-meta", children: [
1071
+ b.name,
1072
+ C ? ` · ${Se(b.size)} · Ready to upload` : ` · ${Se(b.size)}`
1073
+ ] }) : null,
1074
+ C ? /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "The outdoor SVG is stored and drawn live, so decoration stays designer-owned. Only its interactive polygons are imported." }) : /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Floor SVGs are read for geometry only — no copy of the file is kept." }),
1075
+ /* @__PURE__ */ o(
1076
+ "input",
1077
+ {
1078
+ ref: H,
1079
+ hidden: !0,
1080
+ type: "file",
1081
+ accept: ".svg,image/svg+xml",
1082
+ disabled: P || v || !L,
1083
+ onChange: (D) => {
1084
+ var ie;
1085
+ z(((ie = D.target.files) == null ? void 0 : ie[0]) ?? null), D.target.value = "";
1086
+ }
1087
+ }
1088
+ ),
1089
+ /* @__PURE__ */ o(
1090
+ "button",
1091
+ {
1092
+ type: "button",
1093
+ className: "eyeon-map-floors__change",
1094
+ disabled: P || v || !L,
1095
+ onClick: () => {
1096
+ var D;
1097
+ return (D = H.current) == null ? void 0 : D.click();
1098
+ },
1099
+ children: C ? "Replace SVG" : "Re-import SVG"
1100
+ }
1101
+ )
1102
+ ] }) : /* @__PURE__ */ s("div", { className: "eyeon-map-rail__field", children: [
1103
+ C ? "SVG file" : "Floor SVG to import",
1104
+ /* @__PURE__ */ s(
1105
+ "label",
1106
+ {
1107
+ className: [
1108
+ "eyeon-map-floors__drop",
1109
+ Z ? "is-over" : "",
1110
+ b ? "has-file" : "",
1111
+ P ? "is-busy" : ""
1112
+ ].filter(Boolean).join(" "),
1113
+ onDragOver: (D) => {
1114
+ D.preventDefault(), P || F(!0);
1115
+ },
1116
+ onDragLeave: () => F(!1),
1117
+ onDrop: (D) => {
1118
+ var ie;
1119
+ D.preventDefault(), F(!1), !(P || !L) && z((ie = D.dataTransfer.files) == null ? void 0 : ie[0]);
1120
+ },
1121
+ children: [
1122
+ /* @__PURE__ */ o(
1123
+ "input",
1124
+ {
1125
+ type: "file",
1126
+ accept: ".svg,image/svg+xml",
1127
+ disabled: P || v || !L,
1128
+ onChange: (D) => {
1129
+ var ie;
1130
+ z(((ie = D.target.files) == null ? void 0 : ie[0]) ?? null), D.target.value = "";
1131
+ }
1132
+ }
1133
+ ),
1134
+ /* @__PURE__ */ o("span", { className: "eyeon-map-floors__drop-title", children: b ? b.name : "Choose SVG or drop it here" }),
1135
+ /* @__PURE__ */ o("span", { className: "eyeon-map-floors__drop-meta", children: b ? C ? `${Se(b.size)} · Ready to upload` : `${Se(b.size)} · Ready to import` : "SVG only" })
1136
+ ]
1137
+ }
1138
+ ),
1139
+ !C && !d ? /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "The file is read for geometry only. Shapes, layer names and walking paths go into the database; the SVG itself is not stored." }) : null
1140
+ ] }),
1141
+ d ? /* @__PURE__ */ s("div", { className: "eyeon-map-floors__notice", children: [
1142
+ /* @__PURE__ */ s("p", { className: "eyeon-map-floors__notice-title", children: [
1143
+ "Re-importing replaces the ",
1144
+ O,
1145
+ " shape",
1146
+ O === 1 ? "" : "s",
1147
+ " on this floor"
1148
+ ] }),
1149
+ /* @__PURE__ */ s("ul", { className: "eyeon-map-floors__notice-list", children: [
1150
+ /* @__PURE__ */ o("li", { children: "Layers that keep the same Illustrator ID are redrawn from the new file and keep their retailer, amenity and kiosk assignments." }),
1151
+ /* @__PURE__ */ o("li", { children: "Shapes you reshaped in Edit Map keep your geometry — the new file is ignored for those." }),
1152
+ /* @__PURE__ */ o("li", { children: "IDs missing from the new file are hidden rather than deleted, so you can move their assignments onto a renamed layer." }),
1153
+ /* @__PURE__ */ s("li", { children: [
1154
+ "New IDs come in unassigned, and ",
1155
+ /* @__PURE__ */ o("code", { children: "route-path" }),
1156
+ " layers replace this floor’s walking paths."
1157
+ ] }),
1158
+ /* @__PURE__ */ o("li", { children: "The artboard must stay the same size, otherwise the import is rejected." })
1159
+ ] })
1160
+ ] }) : null,
1161
+ W != null && /* @__PURE__ */ s(
1162
+ "div",
1163
+ {
1164
+ className: "eyeon-map-floors__progress",
1165
+ role: "progressbar",
1166
+ "aria-valuemin": 0,
1167
+ "aria-valuemax": 100,
1168
+ "aria-valuenow": W,
1169
+ children: [
1170
+ /* @__PURE__ */ o("div", { className: "eyeon-map-floors__progress-track", children: /* @__PURE__ */ o(
1171
+ "div",
1172
+ {
1173
+ className: "eyeon-map-floors__progress-bar",
1174
+ style: { width: `${Math.min(100, Math.max(0, W))}%` }
1175
+ }
1176
+ ) }),
1177
+ /* @__PURE__ */ s("span", { className: "eyeon-map-floors__progress-label", children: [
1178
+ W,
1179
+ "%"
1180
+ ] })
1181
+ ]
1182
+ }
1183
+ ),
1184
+ ee ? /* @__PURE__ */ o("div", { className: "eyeon-map-floors__error", children: ee }) : null,
1185
+ t.mode === "edit" && g ? /* @__PURE__ */ o("div", { className: "eyeon-map-floors__edit-actions", children: /* @__PURE__ */ s("div", { className: "eyeon-map-floors__edit-row", children: [
1186
+ x && L ? /* @__PURE__ */ o(
1187
+ "button",
1188
+ {
1189
+ type: "button",
1190
+ className: "eyeon-map-floors__danger",
1191
+ disabled: P || v,
1192
+ onClick: () => B(g.id),
1193
+ children: "Delete"
1194
+ }
1195
+ ) : null,
1196
+ /* @__PURE__ */ o(
1197
+ "button",
1198
+ {
1199
+ type: "button",
1200
+ className: "eyeon-map-floors__primary",
1201
+ disabled: P || v || !L || g.kind !== "outdoor" && !T.trim(),
1202
+ onClick: () => void ge(),
1203
+ children: P ? W != null ? `${f} ${W}%` : "Saving…" : b ? C ? "Upload & Save" : "Import & Save" : "Save Changes"
1204
+ }
1205
+ )
1206
+ ] }) }) : /* @__PURE__ */ o("div", { className: "eyeon-map-rail__actions", children: /* @__PURE__ */ o(
1207
+ "button",
1208
+ {
1209
+ type: "button",
1210
+ className: "eyeon-map-floors__primary",
1211
+ disabled: P || v || !L || (C ? !b : !T.trim() || !b),
1212
+ onClick: () => void ge(),
1213
+ children: P ? W != null ? `${f} ${W}%` : `${f}…` : h
1214
+ }
1215
+ ) }),
1216
+ ve()
1217
+ ] });
1218
+ }
1219
+ return /* @__PURE__ */ s("div", { className: ["eyeon-map-floors", _ ? "is-reordering" : ""].filter(Boolean).join(" "), children: [
1220
+ /* @__PURE__ */ s("div", { className: "eyeon-map-floors__block", children: [
1221
+ L && /* @__PURE__ */ o(
1222
+ "button",
1223
+ {
1224
+ type: "button",
1225
+ className: "eyeon-map-floors__add",
1226
+ onClick: () => c({ mode: "add-floor" }),
1227
+ children: "Add Floor"
1228
+ }
1229
+ ),
1230
+ me.length === 0 ? /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "No floors yet." }) : /* @__PURE__ */ o("div", { ref: q, className: "eyeon-map-floors__list", children: me.map((a) => /* @__PURE__ */ o(
1231
+ "div",
1232
+ {
1233
+ "data-floor-id": a.id,
1234
+ className: "eyeon-map-floors__entry",
1235
+ children: /* @__PURE__ */ s(
1236
+ "div",
1237
+ {
1238
+ className: [
1239
+ "eyeon-map-floors__row",
1240
+ (_ == null ? void 0 : _.id) === a.id ? "is-placeholder" : "",
1241
+ j === a.id ? "is-confirm" : ""
1242
+ ].filter(Boolean).join(" "),
1243
+ children: [
1244
+ pe ? /* @__PURE__ */ o(
1245
+ "button",
1246
+ {
1247
+ type: "button",
1248
+ className: "eyeon-map-floors__grip",
1249
+ title: "Drag to reorder",
1250
+ "aria-label": `Reorder ${a.name}`,
1251
+ onClick: (m) => m.stopPropagation(),
1252
+ onPointerDown: (m) => {
1253
+ m.button === 0 && p(a, m);
1254
+ },
1255
+ children: /* @__PURE__ */ o($e, {})
1256
+ }
1257
+ ) : null,
1258
+ /* @__PURE__ */ o(
1259
+ "button",
1260
+ {
1261
+ type: "button",
1262
+ className: "eyeon-map-floors__item",
1263
+ onClick: () => {
1264
+ _ || fe(a);
1265
+ },
1266
+ children: a.name
1267
+ }
1268
+ ),
1269
+ ke(a)
1270
+ ]
1271
+ }
1272
+ )
1273
+ },
1274
+ a.id
1275
+ )) })
1276
+ ] }),
1277
+ /* @__PURE__ */ o("div", { className: "eyeon-map-floors__block", children: E && Y ? /* @__PURE__ */ o("div", { className: "eyeon-map-floors__entry", children: /* @__PURE__ */ s(
1278
+ "div",
1279
+ {
1280
+ className: [
1281
+ "eyeon-map-floors__row",
1282
+ j === Y.id ? "is-confirm" : ""
1283
+ ].filter(Boolean).join(" "),
1284
+ children: [
1285
+ /* @__PURE__ */ o(
241
1286
  "button",
242
1287
  {
243
1288
  type: "button",
244
- className: u.id === d ? "eyeon-map-rail__row is-active" : "eyeon-map-rail__row",
245
- onClick: () => f(u.id),
246
- children: u.name
247
- },
248
- u.id
249
- ))
250
- ] }, t.id)),
251
- /* @__PURE__ */ n("div", { className: "eyeon-map-rail__heading", children: "Outdoor" }),
252
- p.levels.filter((t) => t.kind === "outdoor").map((t) => /* @__PURE__ */ n(
1289
+ className: "eyeon-map-floors__item",
1290
+ onClick: () => fe(Y),
1291
+ children: "Outdoor SVG"
1292
+ }
1293
+ ),
1294
+ ke(Y)
1295
+ ]
1296
+ }
1297
+ ) }) : L ? /* @__PURE__ */ o(
1298
+ "button",
1299
+ {
1300
+ type: "button",
1301
+ className: "eyeon-map-floors__add",
1302
+ onClick: () => c({ mode: "add-base" }),
1303
+ children: "Add Outdoor SVG"
1304
+ }
1305
+ ) : null }),
1306
+ ee ? /* @__PURE__ */ o("div", { className: "eyeon-map-floors__error", children: ee }) : null,
1307
+ ve(),
1308
+ _ ? Je(
1309
+ /* @__PURE__ */ s(
1310
+ "div",
1311
+ {
1312
+ className: "eyeon-map-floors__row eyeon-map-floors__row--ghost",
1313
+ style: {
1314
+ left: _.x,
1315
+ top: _.y,
1316
+ width: _.width,
1317
+ height: _.height
1318
+ },
1319
+ children: [
1320
+ /* @__PURE__ */ o("span", { className: "eyeon-map-floors__grip", "aria-hidden": "true", children: /* @__PURE__ */ o($e, {}) }),
1321
+ /* @__PURE__ */ o("span", { className: "eyeon-map-floors__item", children: _.name }),
1322
+ /* @__PURE__ */ o("span", { className: "eyeon-map-floors__icon-danger", "aria-hidden": "true", children: /* @__PURE__ */ o(De, {}) })
1323
+ ]
1324
+ }
1325
+ ),
1326
+ document.body
1327
+ ) : null
1328
+ ] });
1329
+ }
1330
+ const In = [
1331
+ {
1332
+ id: "floors",
1333
+ label: "Floors",
1334
+ description: "Building floors and Outdoor SVG",
1335
+ countKey: "floors"
1336
+ },
1337
+ {
1338
+ id: "kiosks",
1339
+ label: "Kiosks",
1340
+ description: "Link kiosk screens to devices",
1341
+ countKey: "kiosks"
1342
+ },
1343
+ {
1344
+ id: "style",
1345
+ label: "Style",
1346
+ description: "Colors and 2D / 3D look"
1347
+ }
1348
+ ], wn = {
1349
+ floors: "Floors",
1350
+ stores: "Stores",
1351
+ amenities: "Amenities",
1352
+ kiosks: "Kiosks",
1353
+ paths: "Walking paths",
1354
+ style: "Style",
1355
+ selection: "Selected",
1356
+ "edit-map": "Edit Map"
1357
+ };
1358
+ function Sn() {
1359
+ return /* @__PURE__ */ o("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ o(
1360
+ "path",
1361
+ {
1362
+ d: "M10.2 2.6 4.8 8l5.4 5.4",
1363
+ fill: "none",
1364
+ stroke: "currentColor",
1365
+ strokeWidth: "1.8",
1366
+ strokeLinecap: "round",
1367
+ strokeLinejoin: "round"
1368
+ }
1369
+ ) });
1370
+ }
1371
+ function Cn() {
1372
+ return /* @__PURE__ */ o("svg", { width: "14", height: "14", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ o(
1373
+ "path",
1374
+ {
1375
+ d: "M5.8 2.6 11.2 8l-5.4 5.4",
1376
+ fill: "none",
1377
+ stroke: "currentColor",
1378
+ strokeWidth: "1.8",
1379
+ strokeLinecap: "round",
1380
+ strokeLinejoin: "round"
1381
+ }
1382
+ ) });
1383
+ }
1384
+ function xn({
1385
+ section: e,
1386
+ onSectionChange: n,
1387
+ draft: r,
1388
+ activeLevelId: l,
1389
+ selectedShapeId: t,
1390
+ onSelectShape: c,
1391
+ canFloors: y,
1392
+ canSettings: M,
1393
+ onCreateLevel: x,
1394
+ onUpdateLevel: N,
1395
+ onDeleteLevel: T,
1396
+ onReorderLevels: J,
1397
+ onAutoroute: b,
1398
+ theme: S,
1399
+ onThemeChange: P,
1400
+ assignPanel: Q,
1401
+ editMapPanel: ee,
1402
+ footer: $
1403
+ }) {
1404
+ const [W, R] = w({ mode: "list" });
1405
+ ae(() => {
1406
+ e !== "floors" && R({ mode: "list" });
1407
+ }, [e]);
1408
+ const Z = r.shapes.filter((u) => u.levelId === l), F = Z.filter(
1409
+ (u) => u.kind === "unit" || u.kind === "parking_zone"
1410
+ ), j = Z.filter((u) => u.kind === "amenity"), B = Z.filter((u) => u.kind === "kiosk_screen"), v = r.levels.find((u) => u.id === l), ne = r.anchors.filter((u) => u.levelId === l).length, _ = se(() => {
1411
+ const u = {};
1412
+ for (const K of r.shapes)
1413
+ K.orphanedAt || (u[K.levelId] = (u[K.levelId] ?? 0) + 1);
1414
+ return u;
1415
+ }, [r.shapes]), G = {
1416
+ floors: _n(r.levels),
1417
+ kiosks: B.length
1418
+ }, V = (u, K) => u.length === 0 ? /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: K }) : u.map((U) => /* @__PURE__ */ s(
1419
+ "button",
1420
+ {
1421
+ type: "button",
1422
+ className: U.id === t ? "eyeon-map-rail__row is-active" : "eyeon-map-rail__row",
1423
+ onClick: () => c(U.id),
1424
+ children: [
1425
+ /* @__PURE__ */ o("span", { children: U.key }),
1426
+ /* @__PURE__ */ o("span", { className: "eyeon-map-rail__muted", children: yn(U.kind) })
1427
+ ]
1428
+ },
1429
+ U.id
1430
+ ));
1431
+ return /* @__PURE__ */ s("aside", { className: "eyeon-map-rail", children: [
1432
+ e ? /* @__PURE__ */ s("div", { className: "eyeon-map-rail__header", children: [
1433
+ /* @__PURE__ */ o(
1434
+ "button",
1435
+ {
1436
+ type: "button",
1437
+ className: "eyeon-map-rail__back",
1438
+ onClick: () => {
1439
+ if (e === "floors" && W.mode !== "list") {
1440
+ R({ mode: "list" });
1441
+ return;
1442
+ }
1443
+ n(null);
1444
+ },
1445
+ "aria-label": "Back",
1446
+ children: /* @__PURE__ */ o(Sn, {})
1447
+ }
1448
+ ),
1449
+ /* @__PURE__ */ o("div", { className: "eyeon-map-rail__header-title", children: e === "floors" ? fn(W, r.levels) : wn[e] })
1450
+ ] }) : /* @__PURE__ */ o("div", { className: "eyeon-map-rail__header", children: /* @__PURE__ */ o("div", { className: "eyeon-map-rail__header-title", children: "Map options" }) }),
1451
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__body", children: [
1452
+ !e && /* @__PURE__ */ s("nav", { className: "eyeon-map-rail__nav", "aria-label": "Map options", children: [
1453
+ /* @__PURE__ */ o(
253
1454
  "button",
254
1455
  {
255
1456
  type: "button",
256
- className: t.id === d ? "eyeon-map-rail__row is-active" : "eyeon-map-rail__row",
257
- onClick: () => f(t.id),
258
- children: t.name
1457
+ className: "eyeon-map-rail__edit-map",
1458
+ onClick: () => n("edit-map"),
1459
+ children: "Edit Map"
1460
+ }
1461
+ ),
1462
+ In.map((u) => /* @__PURE__ */ s(
1463
+ "button",
1464
+ {
1465
+ type: "button",
1466
+ className: "eyeon-map-rail__nav-item",
1467
+ onClick: () => n(u.id),
1468
+ children: [
1469
+ /* @__PURE__ */ s("span", { className: "eyeon-map-rail__nav-copy", children: [
1470
+ /* @__PURE__ */ o("span", { className: "eyeon-map-rail__nav-title", children: u.label }),
1471
+ /* @__PURE__ */ o("span", { className: "eyeon-map-rail__nav-desc", children: u.description })
1472
+ ] }),
1473
+ /* @__PURE__ */ s("span", { className: "eyeon-map-rail__nav-meta", children: [
1474
+ u.countKey != null ? /* @__PURE__ */ o("span", { className: "eyeon-map-rail__nav-count", children: G[u.countKey] }) : null,
1475
+ /* @__PURE__ */ o(Cn, {})
1476
+ ] })
1477
+ ]
259
1478
  },
260
- t.id
261
- )),
262
- y && d != null && /* @__PURE__ */ r("div", { className: "eyeon-map-rail__actions", children: [
263
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__file", children: [
264
- "Import SVG",
265
- /* @__PURE__ */ n(
266
- "input",
267
- {
268
- type: "file",
269
- accept: ".svg,image/svg+xml",
270
- onChange: (t) => {
271
- var S;
272
- const u = (S = t.target.files) == null ? void 0 : S[0];
273
- u && D && D(d, u);
274
- }
275
- }
276
- )
277
- ] }),
278
- /* @__PURE__ */ n("button", { type: "button", onClick: () => _ == null ? void 0 : _(d), children: "Auto-route" })
279
- ] })
1479
+ u.id
1480
+ ))
280
1481
  ] }),
281
- i === "shapes" && /* @__PURE__ */ r("div", { className: "eyeon-map-rail__section", children: [
282
- /* @__PURE__ */ r("div", { className: "eyeon-map-rail__heading", children: [
283
- "Shapes (",
284
- p.shapes.filter((t) => t.levelId === d).length,
1482
+ e === "edit-map" && /* @__PURE__ */ o("div", { className: "eyeon-map-rail__section", children: ee }),
1483
+ e === "floors" && /* @__PURE__ */ o(
1484
+ Nn,
1485
+ {
1486
+ levels: r.levels,
1487
+ buildings: r.buildings,
1488
+ levelShapeCounts: _,
1489
+ canFloors: y,
1490
+ screen: W,
1491
+ onScreenChange: R,
1492
+ onCreateLevel: x,
1493
+ onUpdateLevel: N,
1494
+ onDeleteLevel: T,
1495
+ onReorderLevels: J
1496
+ }
1497
+ ),
1498
+ e === "stores" && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__section", children: [
1499
+ v ? /* @__PURE__ */ s("p", { className: "eyeon-map-rail__hint", children: [
1500
+ "Stores on ",
1501
+ v.name,
1502
+ ". Click one here or on the map to assign a retailer."
1503
+ ] }) : null,
1504
+ Q,
1505
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__heading", children: [
1506
+ "On this floor (",
1507
+ F.length,
285
1508
  ")"
286
1509
  ] }),
287
- p.shapes.filter((t) => t.levelId === d).map((t) => /* @__PURE__ */ r("div", { className: "eyeon-map-rail__row", children: [
288
- /* @__PURE__ */ n("span", { className: "eyeon-map-rail__muted", children: t.kind }),
289
- " ",
290
- t.key
291
- ] }, t.id))
1510
+ V(F, "No store spaces on this floor yet.")
292
1511
  ] }),
293
- i === "routes" && /* @__PURE__ */ r("div", { className: "eyeon-map-rail__section", children: [
294
- /* @__PURE__ */ n("div", { className: "eyeon-map-rail__heading", children: "Anchors / Edges" }),
295
- /* @__PURE__ */ n("p", { className: "eyeon-map-rail__hint", children: "Draw routes on the canvas. Drag anchors onto each other to weld. Green highlight means a weld is available." }),
296
- /* @__PURE__ */ r("div", { className: "eyeon-map-rail__stat", children: [
297
- p.anchors.filter((t) => t.levelId === d).length,
298
- " anchors ·",
299
- " ",
300
- p.edges.length,
301
- " edges"
1512
+ e === "amenities" && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__section", children: [
1513
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Click an amenity on the map to link it, or browse the catalog below." }),
1514
+ Q,
1515
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__heading", children: [
1516
+ "On this floor (",
1517
+ j.length,
1518
+ ")"
1519
+ ] }),
1520
+ V(j, "No amenity shapes on this floor yet."),
1521
+ r.amenities.length > 0 && /* @__PURE__ */ s(de, { children: [
1522
+ /* @__PURE__ */ o("div", { className: "eyeon-map-rail__heading", children: "Amenity catalog" }),
1523
+ r.amenities.map((u) => /* @__PURE__ */ s("div", { className: "eyeon-map-rail__row", children: [
1524
+ /* @__PURE__ */ o("span", { children: u.name }),
1525
+ /* @__PURE__ */ o("span", { className: "eyeon-map-rail__muted", children: u.code })
1526
+ ] }, u.id))
302
1527
  ] })
303
1528
  ] }),
304
- i === "amenities" && /* @__PURE__ */ r("div", { className: "eyeon-map-rail__section", children: [
305
- /* @__PURE__ */ n("div", { className: "eyeon-map-rail__heading", children: "Amenity catalog" }),
306
- p.amenities.map((t) => /* @__PURE__ */ r("div", { className: "eyeon-map-rail__row", children: [
307
- t.name,
308
- /* @__PURE__ */ n("span", { className: "eyeon-map-rail__muted", children: t.code })
309
- ] }, t.id))
1529
+ e === "kiosks" && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__section", children: [
1530
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Select a kiosk screen on the map, then enter its device ID." }),
1531
+ Q,
1532
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__heading", children: [
1533
+ "On this floor (",
1534
+ B.length,
1535
+ ")"
1536
+ ] }),
1537
+ V(B, "No kiosk screens on this floor yet.")
310
1538
  ] }),
311
- i === "kiosks" && /* @__PURE__ */ n("div", { className: "eyeon-map-rail__section", children: /* @__PURE__ */ n("p", { className: "eyeon-map-rail__hint", children: "Assign a kiosk_screen shape to a display_kiosks device in the inspector." }) }),
312
- i === "theme" && K && /* @__PURE__ */ r("div", { className: "eyeon-map-rail__section", children: [
313
- /* @__PURE__ */ n("div", { className: "eyeon-map-rail__heading", children: "Theme" }),
314
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
315
- "Style",
316
- /* @__PURE__ */ r(
1539
+ e === "paths" && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__section", children: [
1540
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Use Routes / wayfinding in Edit Map, then click the map to place points. Drag two points together and choose Join points to connect them." }),
1541
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__stat", children: [
1542
+ ne,
1543
+ " path points · ",
1544
+ r.edges.length,
1545
+ " connections"
1546
+ ] }),
1547
+ y && l != null && /* @__PURE__ */ o("div", { className: "eyeon-map-rail__actions", children: /* @__PURE__ */ o("button", { type: "button", onClick: () => b == null ? void 0 : b(l), children: "Suggest walking paths" }) })
1548
+ ] }),
1549
+ e === "style" && /* @__PURE__ */ o("div", { className: "eyeon-map-rail__section", children: M ? /* @__PURE__ */ s(de, { children: [
1550
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "These colors apply on the public map after Save Changes." }),
1551
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1552
+ "View",
1553
+ /* @__PURE__ */ s(
317
1554
  "select",
318
1555
  {
319
- value: I.MAP_STYLE,
320
- onChange: (t) => C({ MAP_STYLE: t.target.value }),
1556
+ value: S.MAP_STYLE,
1557
+ onChange: (u) => P({ MAP_STYLE: u.target.value }),
321
1558
  children: [
322
- /* @__PURE__ */ n("option", { value: "2D", children: "2D" }),
323
- /* @__PURE__ */ n("option", { value: "3D", children: "3D" })
1559
+ /* @__PURE__ */ o("option", { value: "2D", children: "2D" }),
1560
+ /* @__PURE__ */ o("option", { value: "3D", children: "3D" })
324
1561
  ]
325
1562
  }
326
1563
  )
327
1564
  ] }),
328
1565
  [
329
- ["ACCENT_COLOR", "Accent"],
330
- ["STORE_DEFAULT_COLOR", "Store fill"],
1566
+ ["ACCENT_COLOR", "Highlight"],
1567
+ ["STORE_DEFAULT_COLOR", "Stores"],
331
1568
  ["MAP_BACKGROUND_COLOR", "Background"],
332
- ["WALL_COLOR", "Walls"],
333
- ["PARKING_ZONE_COLOR", "Parking"],
334
- ["GREEN_AREA_COLOR", "Green"],
335
- ["WATER_COLOR", "Water"]
336
- ].map(([t, u]) => /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
337
- u,
338
- /* @__PURE__ */ n(
1569
+ ["WALL_COLOR", "Walls"]
1570
+ ].map(([u, K]) => /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field eyeon-map-rail__field--color", children: [
1571
+ K,
1572
+ /* @__PURE__ */ o(
339
1573
  "input",
340
1574
  {
341
1575
  type: "color",
342
- value: I[t],
343
- onChange: (S) => C({ [t]: S.target.value })
1576
+ value: S[u],
1577
+ onChange: (U) => P({ [u]: U.target.value })
344
1578
  }
345
1579
  )
346
- ] }, t))
1580
+ ] }, u)),
1581
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Green areas, parking lanes, and walking paths use fixed house colors from the map library — not editable here." })
1582
+ ] }) : /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "You do not have permission to change map colors." }) }),
1583
+ e === "selection" && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__section", children: [
1584
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: v ? `Editing a shape on ${v.name}.` : "Editing the selected shape." }),
1585
+ Q
347
1586
  ] })
348
- ] })
1587
+ ] }),
1588
+ $ ? /* @__PURE__ */ o("div", { className: "eyeon-map-rail__footer", children: $ }) : null
349
1589
  ] });
350
1590
  }
351
- const oe = [
352
- "unit",
353
- "amenity",
354
- "kiosk_screen",
355
- "connector",
356
- "entrance",
357
- "walkable",
358
- "void",
359
- "wall",
360
- "boundary",
361
- "floorplate",
362
- "decor",
363
- "label",
364
- "zone",
365
- "parking_zone",
366
- "green_area",
367
- "water",
368
- "parking_icon"
369
- ], ce = [
370
- "occupied",
371
- "vacant",
372
- "coming_soon",
373
- "under_renovation"
374
- ];
375
- function de({
376
- shape: i,
377
- assignment: l,
378
- amenities: p,
379
- canEdit: d,
380
- onRename: f,
1591
+ const On = Object.keys(Te), An = Object.keys(Be);
1592
+ function Ln({
1593
+ shape: e,
1594
+ assignment: n,
1595
+ amenities: r,
1596
+ levelShapeKeys: l = [],
1597
+ canEdit: t,
1598
+ onRename: c,
381
1599
  onChangeKind: y,
382
- onSaveAssignment: K,
383
- undoCount: D
1600
+ onDelete: M,
1601
+ onSaveAssignment: x
384
1602
  }) {
385
- var A, U, $;
386
- const [_, I] = h((i == null ? void 0 : i.key) ?? ""), [C, t] = h(
387
- ((A = l == null ? void 0 : l.retailerId) == null ? void 0 : A.toString()) ?? ""
388
- ), [u, S] = h(
389
- ((U = l == null ? void 0 : l.amenityId) == null ? void 0 : U.toString()) ?? ""
390
- ), [O, M] = h(
391
- (($ = l == null ? void 0 : l.kioskId) == null ? void 0 : $.toString()) ?? ""
392
- ), [b, E] = h(
393
- (l == null ? void 0 : l.unitStatus) ?? "vacant"
394
- ), [m, B] = h((l == null ? void 0 : l.unitNumber) ?? ""), [k, R] = h((l == null ? void 0 : l.customLabel) ?? "");
395
- return J(() => {
396
- var o, g, v;
397
- I((i == null ? void 0 : i.key) ?? ""), t(((o = l == null ? void 0 : l.retailerId) == null ? void 0 : o.toString()) ?? ""), S(((g = l == null ? void 0 : l.amenityId) == null ? void 0 : g.toString()) ?? ""), M(((v = l == null ? void 0 : l.kioskId) == null ? void 0 : v.toString()) ?? ""), E((l == null ? void 0 : l.unitStatus) ?? "vacant"), B((l == null ? void 0 : l.unitNumber) ?? ""), R((l == null ? void 0 : l.customLabel) ?? "");
398
- }, [i, l]), i ? /* @__PURE__ */ r("aside", { className: "eyeon-map-inspector", children: [
399
- /* @__PURE__ */ n("div", { className: "eyeon-map-inspector__heading", children: "Shape" }),
400
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
401
- "Key / ID",
402
- /* @__PURE__ */ n(
1603
+ var _, G, V;
1604
+ const [N, T] = w((e == null ? void 0 : e.key) ?? ""), [J, b] = w(null), [S, P] = w(
1605
+ ((_ = n == null ? void 0 : n.retailerId) == null ? void 0 : _.toString()) ?? ""
1606
+ ), [Q, ee] = w(
1607
+ ((G = n == null ? void 0 : n.amenityId) == null ? void 0 : G.toString()) ?? ""
1608
+ ), [$, W] = w(
1609
+ ((V = n == null ? void 0 : n.kioskId) == null ? void 0 : V.toString()) ?? ""
1610
+ ), [R, Z] = w(
1611
+ (n == null ? void 0 : n.unitStatus) ?? "vacant"
1612
+ ), [F, j] = w((n == null ? void 0 : n.unitNumber) ?? ""), [B, v] = w((n == null ? void 0 : n.customLabel) ?? "");
1613
+ return ae(() => {
1614
+ var u, K, U;
1615
+ T((e == null ? void 0 : e.key) ?? ""), b(null), P(((u = n == null ? void 0 : n.retailerId) == null ? void 0 : u.toString()) ?? ""), ee(((K = n == null ? void 0 : n.amenityId) == null ? void 0 : K.toString()) ?? ""), W(((U = n == null ? void 0 : n.kioskId) == null ? void 0 : U.toString()) ?? ""), Z((n == null ? void 0 : n.unitStatus) ?? "vacant"), j((n == null ? void 0 : n.unitNumber) ?? ""), v((n == null ? void 0 : n.customLabel) ?? "");
1616
+ }, [e, n]), e ? /* @__PURE__ */ s("div", { className: "eyeon-map-inspector", children: [
1617
+ /* @__PURE__ */ o("div", { className: "eyeon-map-inspector__heading", children: "Selected" }),
1618
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1619
+ "Name",
1620
+ /* @__PURE__ */ o(
403
1621
  "input",
404
1622
  {
405
- value: _,
406
- disabled: !d,
407
- onChange: (o) => I(o.target.value),
1623
+ value: N,
1624
+ disabled: !t,
1625
+ onChange: (u) => {
1626
+ T(u.target.value), b(null);
1627
+ },
408
1628
  onBlur: () => {
409
- _ && _ !== i.key && f(_);
1629
+ if (!N || N === e.key) {
1630
+ b(null);
1631
+ return;
1632
+ }
1633
+ if (l.includes(N)) {
1634
+ b("That name is already used on this level.");
1635
+ return;
1636
+ }
1637
+ b(null), c(N);
410
1638
  }
411
1639
  }
412
1640
  )
413
1641
  ] }),
414
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
415
- "Kind",
416
- /* @__PURE__ */ n(
1642
+ J ? /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", style: { color: "#b91c1c" }, children: J }) : null,
1643
+ e.geometryLocked ? /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Geometry locked — outdoor re-uploads will not overwrite this shape." }) : null,
1644
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1645
+ "Type",
1646
+ /* @__PURE__ */ o(
417
1647
  "select",
418
1648
  {
419
- value: i.kind,
420
- disabled: !d,
421
- onChange: (o) => y(o.target.value),
422
- children: oe.map((o) => /* @__PURE__ */ n("option", { value: o, children: o }, o))
1649
+ value: e.kind,
1650
+ disabled: !t,
1651
+ onChange: (u) => y(u.target.value),
1652
+ children: On.map((u) => /* @__PURE__ */ o("option", { value: u, children: Te[u] }, u))
423
1653
  }
424
1654
  )
425
1655
  ] }),
426
- /* @__PURE__ */ n("div", { className: "eyeon-map-inspector__heading", children: "Assignment" }),
427
- (i.kind === "unit" || i.kind === "parking_zone") && /* @__PURE__ */ r(q, { children: [
428
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
1656
+ (e.kind === "unit" || e.kind === "parking_zone") && /* @__PURE__ */ s(de, { children: [
1657
+ /* @__PURE__ */ o("div", { className: "eyeon-map-inspector__heading", children: "Store" }),
1658
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
429
1659
  "Retailer ID",
430
- /* @__PURE__ */ n(
1660
+ /* @__PURE__ */ o(
431
1661
  "input",
432
1662
  {
433
- value: C,
434
- disabled: !d,
435
- onChange: (o) => t(o.target.value)
1663
+ value: S,
1664
+ disabled: !t,
1665
+ onChange: (u) => P(u.target.value)
436
1666
  }
437
1667
  )
438
1668
  ] }),
439
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
1669
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
440
1670
  "Status",
441
- /* @__PURE__ */ n(
1671
+ /* @__PURE__ */ o(
442
1672
  "select",
443
1673
  {
444
- value: b,
445
- disabled: !d,
446
- onChange: (o) => E(o.target.value),
447
- children: ce.map((o) => /* @__PURE__ */ n("option", { value: o, children: o }, o))
1674
+ value: R,
1675
+ disabled: !t,
1676
+ onChange: (u) => Z(u.target.value),
1677
+ children: An.map((u) => /* @__PURE__ */ o("option", { value: u, children: Be[u] }, u))
448
1678
  }
449
1679
  )
450
1680
  ] }),
451
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
1681
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
452
1682
  "Unit number",
453
- /* @__PURE__ */ n(
1683
+ /* @__PURE__ */ o(
454
1684
  "input",
455
1685
  {
456
- value: m,
457
- disabled: !d,
458
- onChange: (o) => B(o.target.value)
1686
+ value: F,
1687
+ disabled: !t,
1688
+ onChange: (u) => j(u.target.value)
459
1689
  }
460
1690
  )
461
1691
  ] })
462
1692
  ] }),
463
- i.kind === "amenity" && /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
464
- "Amenity",
465
- /* @__PURE__ */ r(
466
- "select",
467
- {
468
- value: u,
469
- disabled: !d,
470
- onChange: (o) => S(o.target.value),
471
- children: [
472
- /* @__PURE__ */ n("option", { value: "", children: "—" }),
473
- p.map((o) => /* @__PURE__ */ n("option", { value: o.id, children: o.name }, o.id))
474
- ]
475
- }
476
- )
1693
+ e.kind === "amenity" && /* @__PURE__ */ s(de, { children: [
1694
+ /* @__PURE__ */ o("div", { className: "eyeon-map-inspector__heading", children: "Amenity" }),
1695
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1696
+ "Linked amenity",
1697
+ /* @__PURE__ */ s(
1698
+ "select",
1699
+ {
1700
+ value: Q,
1701
+ disabled: !t,
1702
+ onChange: (u) => ee(u.target.value),
1703
+ children: [
1704
+ /* @__PURE__ */ o("option", { value: "", children: "Not assigned" }),
1705
+ r.map((u) => /* @__PURE__ */ o("option", { value: u.id, children: u.name }, u.id))
1706
+ ]
1707
+ }
1708
+ )
1709
+ ] })
1710
+ ] }),
1711
+ e.kind === "kiosk_screen" && /* @__PURE__ */ s(de, { children: [
1712
+ /* @__PURE__ */ o("div", { className: "eyeon-map-inspector__heading", children: "Kiosk" }),
1713
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1714
+ "Kiosk device ID",
1715
+ /* @__PURE__ */ o(
1716
+ "input",
1717
+ {
1718
+ value: $,
1719
+ disabled: !t,
1720
+ onChange: (u) => W(u.target.value)
1721
+ }
1722
+ )
1723
+ ] })
477
1724
  ] }),
478
- i.kind === "kiosk_screen" && /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
479
- "Kiosk device ID",
480
- /* @__PURE__ */ n(
1725
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
1726
+ "Label on map",
1727
+ /* @__PURE__ */ o(
481
1728
  "input",
482
1729
  {
483
- value: O,
484
- disabled: !d,
485
- onChange: (o) => M(o.target.value)
1730
+ value: B,
1731
+ disabled: !t,
1732
+ placeholder: "Optional",
1733
+ onChange: (u) => v(u.target.value)
486
1734
  }
487
1735
  )
488
1736
  ] }),
489
- /* @__PURE__ */ r("label", { className: "eyeon-map-rail__field", children: [
490
- "Custom label",
491
- /* @__PURE__ */ n(
492
- "input",
1737
+ t && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__actions", children: [
1738
+ /* @__PURE__ */ o(
1739
+ "button",
493
1740
  {
494
- value: k,
495
- disabled: !d,
496
- onChange: (o) => R(o.target.value)
1741
+ type: "button",
1742
+ className: "eyeon-map-inspector__save",
1743
+ onClick: () => x({
1744
+ shapeId: e.id,
1745
+ targetType: S ? "retailer" : Q ? "amenity" : $ ? "kiosk" : "none",
1746
+ retailerId: S ? Number(S) : null,
1747
+ amenityId: Q ? Number(Q) : null,
1748
+ kioskId: $ ? Number($) : null,
1749
+ unitStatus: R,
1750
+ unitNumber: F || null,
1751
+ customLabel: B || null,
1752
+ customImageKey: (n == null ? void 0 : n.customImageKey) ?? null
1753
+ }),
1754
+ children: "Save"
497
1755
  }
498
- )
499
- ] }),
500
- d && /* @__PURE__ */ n(
1756
+ ),
1757
+ M ? /* @__PURE__ */ o(
1758
+ "button",
1759
+ {
1760
+ type: "button",
1761
+ className: "eyeon-map-inspector__delete",
1762
+ onClick: () => {
1763
+ window.confirm(`Delete shape “${e.key}”?`) && M();
1764
+ },
1765
+ children: "Delete"
1766
+ }
1767
+ ) : null
1768
+ ] })
1769
+ ] }) : /* @__PURE__ */ o("div", { className: "eyeon-map-inspector__empty", children: "Pick an item from the list below, or click it on the map." });
1770
+ }
1771
+ function Tn({
1772
+ document: e,
1773
+ host: n = "PORTAL_ASSIGN",
1774
+ onSelectShape: r,
1775
+ activeLevelId: l,
1776
+ onActiveLevelChange: t,
1777
+ routeOnSelect: c,
1778
+ imageProxyUrl: y
1779
+ }) {
1780
+ return /* @__PURE__ */ o("div", { className: "eyeon-map-preview", children: /* @__PURE__ */ o(Ke, { fallback: /* @__PURE__ */ o("div", { className: "eyeon-map-preview__loading", children: "Loading preview…" }), children: /* @__PURE__ */ o(
1781
+ Ze,
1782
+ {
1783
+ document: e,
1784
+ host: n,
1785
+ onSelectShape: r,
1786
+ activeLevelId: l,
1787
+ onActiveLevelChange: t,
1788
+ routeOnSelect: c,
1789
+ imageProxyUrl: y
1790
+ }
1791
+ ) }) });
1792
+ }
1793
+ function Rn(e, n) {
1794
+ const r = e.levels.find((l) => l.kind === "outdoor");
1795
+ return ze({
1796
+ revisionId: (n == null ? void 0 : n.revisionId) ?? 0,
1797
+ revisionNumber: (n == null ? void 0 : n.revisionNumber) ?? 0,
1798
+ centerId: e.centerId,
1799
+ mapId: e.mapId,
1800
+ theme: e.theme,
1801
+ baseSvgUrl: e.baseSvgUrl ?? (r == null ? void 0 : r.sourceSvgUrl) ?? null,
1802
+ baseViewbox: (r == null ? void 0 : r.sourceViewbox) ?? null,
1803
+ buildings: e.buildings,
1804
+ levels: e.levels,
1805
+ shapes: e.shapes.filter((l) => !l.orphanedAt),
1806
+ assignments: e.assignments,
1807
+ anchors: e.anchors,
1808
+ edges: e.edges,
1809
+ connectors: (n == null ? void 0 : n.connectors) ?? [],
1810
+ amenities: e.amenities,
1811
+ responsiveOverrides: [],
1812
+ publishedAt: n == null ? void 0 : n.publishedAt,
1813
+ /** Prefer already-resolved CDN URLs on draft levels (outdoor SVG). */
1814
+ resolveSvgUrl: (l) => {
1815
+ if (!l) return null;
1816
+ const t = e.levels.find(
1817
+ (c) => c.sourceSvgKey === l || c.sourceSvgUrl === l
1818
+ );
1819
+ return (t == null ? void 0 : t.sourceSvgUrl) ?? l;
1820
+ }
1821
+ });
1822
+ }
1823
+ function Mn(e, n) {
1824
+ return e === "PORTAL" && n !== "edit-map" ? "viewer" : "editor";
1825
+ }
1826
+ const En = [
1827
+ { id: "select", label: "Select" },
1828
+ { id: "pan", label: "Pan" },
1829
+ { id: "draw-unit", label: "Draw rectangle", draw: !0 },
1830
+ { id: "draw-polygon", label: "Draw polygon", draw: !0 },
1831
+ { id: "draw-line", label: "Draw line", draw: !0 },
1832
+ { id: "draw-route", label: "Routes / wayfinding", draw: !0 }
1833
+ ], _e = {
1834
+ width: 16,
1835
+ height: 16,
1836
+ viewBox: "0 0 16 16",
1837
+ fill: "none",
1838
+ "aria-hidden": !0
1839
+ };
1840
+ function $n() {
1841
+ return /* @__PURE__ */ o("svg", { ..._e, children: /* @__PURE__ */ o(
1842
+ "path",
1843
+ {
1844
+ d: "M3.2 2.4 12.4 8.1l-4.1.6 1.8 4.6-1.8.7-1.8-4.6-2.6 2.4z",
1845
+ fill: "currentColor"
1846
+ }
1847
+ ) });
1848
+ }
1849
+ function Dn() {
1850
+ return /* @__PURE__ */ o("svg", { ..._e, children: /* @__PURE__ */ o(
1851
+ "path",
1852
+ {
1853
+ d: "M4.15 8.05V6.7a.95.95 0 0 1 1.9 0V8.15M6.05 7.2V4.1a.95.95 0 1 1 1.9 0V7.05M7.95 6.9V3.2a.95.95 0 1 1 1.9 0V6.95M9.85 7V3.9a.95.95 0 1 1 1.9 0v5.05c0 2.05-1.5 3.4-3.6 3.4-1.75 0-3.15-1.05-3.35-2.75",
1854
+ stroke: "currentColor",
1855
+ strokeWidth: "1.45",
1856
+ strokeLinecap: "round",
1857
+ strokeLinejoin: "round"
1858
+ }
1859
+ ) });
1860
+ }
1861
+ function Pn() {
1862
+ return /* @__PURE__ */ o("svg", { ..._e, children: /* @__PURE__ */ o(
1863
+ "rect",
1864
+ {
1865
+ x: "2.5",
1866
+ y: "3.5",
1867
+ width: "11",
1868
+ height: "9",
1869
+ rx: "1",
1870
+ stroke: "currentColor",
1871
+ strokeWidth: "1.6"
1872
+ }
1873
+ ) });
1874
+ }
1875
+ function Vn() {
1876
+ return /* @__PURE__ */ o("svg", { ..._e, children: /* @__PURE__ */ o(
1877
+ "path",
1878
+ {
1879
+ d: "M8 2.5 13.2 6.2 11.2 12.5H4.8L2.8 6.2Z",
1880
+ stroke: "currentColor",
1881
+ strokeWidth: "1.5",
1882
+ strokeLinejoin: "round"
1883
+ }
1884
+ ) });
1885
+ }
1886
+ function Bn() {
1887
+ return /* @__PURE__ */ s("svg", { ..._e, children: [
1888
+ /* @__PURE__ */ o(
1889
+ "path",
1890
+ {
1891
+ d: "M3 12.5 13 3.5",
1892
+ stroke: "currentColor",
1893
+ strokeWidth: "1.6",
1894
+ strokeLinecap: "round"
1895
+ }
1896
+ ),
1897
+ /* @__PURE__ */ o("circle", { cx: "3", cy: "12.5", r: "1.4", fill: "currentColor" }),
1898
+ /* @__PURE__ */ o("circle", { cx: "13", cy: "3.5", r: "1.4", fill: "currentColor" })
1899
+ ] });
1900
+ }
1901
+ function Gn() {
1902
+ return /* @__PURE__ */ s("svg", { ..._e, children: [
1903
+ /* @__PURE__ */ o(
1904
+ "path",
1905
+ {
1906
+ d: "M3.5 12.5c2.2-3.4 3.2-3.6 4.5-3.6 1.6 0 2.2 1.8 4.5 1.8",
1907
+ stroke: "currentColor",
1908
+ strokeWidth: "1.6",
1909
+ strokeLinecap: "round"
1910
+ }
1911
+ ),
1912
+ /* @__PURE__ */ o("circle", { cx: "3.5", cy: "12.5", r: "1.5", fill: "currentColor" }),
1913
+ /* @__PURE__ */ o("circle", { cx: "8", cy: "8.9", r: "1.5", fill: "currentColor" }),
1914
+ /* @__PURE__ */ o("circle", { cx: "12.5", cy: "10.7", r: "1.5", fill: "currentColor" })
1915
+ ] });
1916
+ }
1917
+ function Kn() {
1918
+ return /* @__PURE__ */ s("svg", { ..._e, children: [
1919
+ /* @__PURE__ */ o("circle", { cx: "4", cy: "8", r: "2", stroke: "currentColor", strokeWidth: "1.5" }),
1920
+ /* @__PURE__ */ o("circle", { cx: "12", cy: "8", r: "2", stroke: "currentColor", strokeWidth: "1.5" }),
1921
+ /* @__PURE__ */ o("path", { d: "M6 8h4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
1922
+ ] });
1923
+ }
1924
+ const Un = {
1925
+ select: $n,
1926
+ pan: Dn,
1927
+ "draw-unit": Pn,
1928
+ "draw-polygon": Vn,
1929
+ "draw-line": Bn,
1930
+ "draw-route": Gn
1931
+ };
1932
+ function Wn(e) {
1933
+ switch (e) {
1934
+ case "pan":
1935
+ return "Drag the map to move around.";
1936
+ case "draw-unit":
1937
+ return "Click and drag to draw a store rectangle.";
1938
+ case "draw-polygon":
1939
+ return "Click to place points. Click the first point or press Enter to close. Esc cancels.";
1940
+ case "draw-line":
1941
+ return "Click and drag to draw a line.";
1942
+ case "draw-route":
1943
+ return "Click the map to place path points. Drag two points together, then Join points, to connect them.";
1944
+ default:
1945
+ return "Click a shape to select it. Drag to move; drag anchors to reshape.";
1946
+ }
1947
+ }
1948
+ function Pe({
1949
+ tool: e,
1950
+ onToolChange: n,
1951
+ canEdit: r
1952
+ }) {
1953
+ return /* @__PURE__ */ o("div", { className: "eyeon-map-editor__tool-icons", role: "toolbar", "aria-label": "Map tools", children: En.map((l) => {
1954
+ const t = Un[l.id];
1955
+ return /* @__PURE__ */ o(
501
1956
  "button",
502
1957
  {
503
1958
  type: "button",
504
- className: "eyeon-map-inspector__save",
505
- onClick: () => K({
506
- shapeId: i.id,
507
- targetType: C ? "retailer" : u ? "amenity" : O ? "kiosk" : "none",
508
- retailerId: C ? Number(C) : null,
509
- amenityId: u ? Number(u) : null,
510
- kioskId: O ? Number(O) : null,
511
- unitStatus: b,
512
- unitNumber: m || null,
513
- customLabel: k || null,
514
- customImageKey: (l == null ? void 0 : l.customImageKey) ?? null
515
- }),
516
- children: "Save assignment"
517
- }
518
- )
519
- ] }) : /* @__PURE__ */ n("aside", { className: "eyeon-map-inspector", children: /* @__PURE__ */ r("div", { className: "eyeon-map-inspector__empty", children: [
520
- "Select a shape or anchor",
521
- /* @__PURE__ */ r("div", { className: "eyeon-map-rail__muted", children: [
522
- "Undo stack: ",
523
- D
524
- ] })
525
- ] }) });
1959
+ className: `eyeon-map-editor__tool-icon${e === l.id ? " is-active" : ""}`,
1960
+ "data-tooltip": l.label,
1961
+ "aria-label": l.label,
1962
+ "aria-pressed": e === l.id,
1963
+ onClick: () => n(l.id),
1964
+ disabled: !r && l.draw,
1965
+ children: /* @__PURE__ */ o(t, {})
1966
+ },
1967
+ l.id
1968
+ );
1969
+ }) });
526
1970
  }
527
- function se({ document: i }) {
528
- return /* @__PURE__ */ n("div", { className: "eyeon-map-preview", children: /* @__PURE__ */ n(Q, { fallback: /* @__PURE__ */ n("div", { className: "eyeon-map-preview__loading", children: "Loading preview…" }), children: /* @__PURE__ */ n(ie, { document: i, role: "PORTAL_PREVIEW" }) }) });
1971
+ function Fn({ disabled: e, onClick: n }) {
1972
+ return /* @__PURE__ */ o(
1973
+ "button",
1974
+ {
1975
+ type: "button",
1976
+ className: "eyeon-map-editor__tool-icon",
1977
+ "data-tooltip": "Join points",
1978
+ "aria-label": "Join points",
1979
+ onClick: n,
1980
+ disabled: e,
1981
+ children: /* @__PURE__ */ o(Kn, {})
1982
+ }
1983
+ );
529
1984
  }
530
- function _e({
531
- draft: i,
532
- canEdit: l = !0,
533
- canFloors: p = !0,
534
- canSettings: d = !0,
535
- onBatch: f,
1985
+ function Zn({
1986
+ host: e = "PORTAL",
1987
+ draft: n,
1988
+ canEdit: r = !0,
1989
+ canFloors: l = !0,
1990
+ canSettings: t = !0,
1991
+ onBatch: c,
536
1992
  onPublish: y,
537
- onImportSvg: K,
538
- onAutoroute: D,
539
- previewDocument: _,
540
- className: I
1993
+ onImportSvg: M,
1994
+ onCreateLevel: x,
1995
+ onUpdateLevel: N,
1996
+ onDeleteLevel: T,
1997
+ onReorderLevels: J,
1998
+ onAutoroute: b,
1999
+ previewDocument: S,
2000
+ imageProxyUrl: P,
2001
+ className: Q,
2002
+ sidebarFooter: ee
541
2003
  }) {
542
- var T;
543
- const [C, t] = h("levels"), [u, S] = h(
544
- ((T = i.levels[0]) == null ? void 0 : T.id) ?? null
545
- ), [O, M] = h(null), [b, E] = h([]), [m, B] = h("select"), [k, R] = h(!1), [A, U] = h(0), [$, o] = h([]), g = z([]), v = V(
546
- () => ({ ...le, ...i.theme }),
547
- [i.theme]
548
- ), w = i.levels.find((a) => a.id === u) ?? null, Y = i.shapes.filter((a) => a.levelId === u), X = i.anchors.filter((a) => a.levelId === u), j = i.edges.filter((a) => {
549
- const N = i.anchors.find((P) => P.id === a.fromAnchorId);
550
- return (N == null ? void 0 : N.levelId) === u;
551
- }), x = Y.find((a) => a.id === O) ?? null, G = i.assignments.find((a) => a.shapeId === O) ?? null, e = ee(
552
- async (a) => {
553
- !a.length || !f || (o((N) => [...N, a]), await f(a), g.current = []);
2004
+ var O;
2005
+ const [$, W] = w(null), [R, Z] = w(
2006
+ Re(n.levels) ?? ((O = n.levels[0]) == null ? void 0 : O.id) ?? null
2007
+ ), [F, j] = w(null), [B, v] = w([]), [ne, _] = w("select"), [G, V] = w(0), [u, K] = w(0), [U, ce] = w(!1), [ue, H] = w(!1), q = he([]), te = he(-1);
2008
+ ae(() => {
2009
+ q.current = [], K(0), ce(!1);
2010
+ }, [n.mapId, n.centerId]), ae(() => {
2011
+ var d;
2012
+ n.levels.some((h) => h.id === R) || Z(Re(n.levels) ?? ((d = n.levels[0]) == null ? void 0 : d.id) ?? null);
2013
+ }, [n.levels, R]);
2014
+ const A = se(
2015
+ () => pn(n, q.current),
2016
+ [n, u]
2017
+ ), re = se(
2018
+ () => He(A.theme),
2019
+ [A.theme]
2020
+ ), Y = q.current.length > 0 || U, E = A.levels.find((d) => d.id === R) ?? null, le = A.levels.find((d) => d.kind === "outdoor") ?? null, oe = le && (E == null ? void 0 : E.kind) === "floor" ? A.shapes.filter((d) => d.levelId === le.id) : [], X = A.shapes.filter((d) => d.levelId === R), me = se(
2021
+ () => Rn(A, {
2022
+ revisionId: S == null ? void 0 : S.revisionId,
2023
+ revisionNumber: S == null ? void 0 : S.revisionNumber,
2024
+ connectors: S == null ? void 0 : S.connectors,
2025
+ publishedAt: S == null ? void 0 : S.publishedAt
2026
+ }),
2027
+ [A, S]
2028
+ ), g = A.anchors.filter((d) => d.levelId === R), C = A.edges.filter((d) => {
2029
+ const h = A.anchors.find((f) => f.id === d.fromAnchorId);
2030
+ return (h == null ? void 0 : h.levelId) === R;
2031
+ }), L = A.shapes.find((d) => d.id === F) ?? null, pe = A.assignments.find((d) => d.shapeId === F) ?? null, z = we((d) => {
2032
+ let h = d;
2033
+ if (h.op === "upsert_shape" && h.shape.id == null) {
2034
+ const f = te.current--;
2035
+ h = { ...h, shape: { ...h.shape, id: f } };
2036
+ }
2037
+ if (h.op === "upsert_anchor" && h.anchor.id == null) {
2038
+ const f = te.current--;
2039
+ h = { ...h, anchor: { ...h.anchor, id: f } };
2040
+ }
2041
+ if (h.op === "upsert_edge" && h.edge.id == null) {
2042
+ const f = te.current--;
2043
+ h = { ...h, edge: { ...h.edge, id: f } };
2044
+ }
2045
+ return q.current = mn(q.current, h), K((f) => f + 1), h.op === "upsert_shape" ? h.shape.id ?? null : h.op === "upsert_anchor" ? h.anchor.id ?? null : h.op === "upsert_edge" ? h.edge.id ?? null : null;
2046
+ }, []), fe = we(async () => {
2047
+ if (!r || ue) return;
2048
+ const d = q.current;
2049
+ if (!d.length && !U) return;
2050
+ q.current = [], K((f) => f + 1), H(!0);
2051
+ let h = !d.length;
2052
+ try {
2053
+ d.length && c && (await c(d), h = !0), await (y == null ? void 0 : y()), ce(!1);
2054
+ } catch {
2055
+ h ? ce(!0) : (q.current = d, K((f) => f + 1));
2056
+ } finally {
2057
+ H(!1);
2058
+ }
2059
+ }, [r, U, c, y, ue]), ge = we(
2060
+ (d) => {
2061
+ $ === "edit-map" && d !== "edit-map" && _("select"), W(d);
554
2062
  },
555
- [f]
556
- ), c = async () => {
557
- if (b.length < 2) return;
558
- const a = X.map((W) => ({ ...W })), N = i.edges.map((W) => ({ ...W })), P = ne(a, N, b);
559
- P && (await e([
560
- {
561
- op: "weld_anchors",
562
- anchorIds: b
2063
+ [$]
2064
+ ), ye = we(
2065
+ (d) => {
2066
+ if (j(d), d == null) return;
2067
+ const h = A.shapes.find((f) => f.id === d);
2068
+ h && Z(h.levelId), W((f) => f === "edit-map" ? f : (h == null ? void 0 : h.kind) === "unit" || (h == null ? void 0 : h.kind) === "parking_zone" ? "stores" : (h == null ? void 0 : h.kind) === "amenity" ? "amenities" : (h == null ? void 0 : h.kind) === "kiosk_screen" ? "kiosks" : "selection");
2069
+ },
2070
+ [A.shapes]
2071
+ ), ve = () => {
2072
+ B.length < 2 || (z({
2073
+ op: "weld_anchors",
2074
+ anchorIds: B
2075
+ }), v([B[0]]));
2076
+ }, ke = (d) => {
2077
+ !L || !r || A.shapes.some(
2078
+ (f) => f.id !== L.id && f.levelId === L.levelId && f.key === d && !f.orphanedAt
2079
+ ) || z({
2080
+ op: "upsert_shape",
2081
+ shape: {
2082
+ id: L.id,
2083
+ levelId: L.levelId,
2084
+ key: d,
2085
+ kind: L.kind
563
2086
  }
564
- ]), E([P.survivingAnchorId]));
565
- }, s = async (a) => {
566
- !x || !l || await e([
567
- {
568
- op: "upsert_shape",
569
- shape: {
570
- id: x.id,
571
- levelId: x.levelId,
572
- key: a,
573
- kind: x.kind
574
- }
2087
+ });
2088
+ }, Ne = () => {
2089
+ !L || !r || (z({ op: "delete_shape", shapeId: L.id }), j(null));
2090
+ }, Ie = (d, h) => {
2091
+ if (!r) return;
2092
+ const f = A.shapes.find((D) => D.id === d);
2093
+ f && z({
2094
+ op: "upsert_shape",
2095
+ shape: {
2096
+ id: f.id,
2097
+ levelId: f.levelId,
2098
+ key: f.key,
2099
+ kind: f.kind,
2100
+ geometry: h,
2101
+ geometryLocked: !0
575
2102
  }
576
- ]);
577
- }, L = async (a) => {
578
- !x || !l || await e([
579
- {
580
- op: "upsert_shape",
581
- shape: {
582
- id: x.id,
583
- levelId: x.levelId,
584
- key: x.key,
585
- kind: a
586
- }
2103
+ });
2104
+ }, i = (d) => {
2105
+ !L || !r || z({
2106
+ op: "upsert_shape",
2107
+ shape: {
2108
+ id: L.id,
2109
+ levelId: L.levelId,
2110
+ key: L.key,
2111
+ kind: d
587
2112
  }
588
- ]);
589
- };
590
- return /* @__PURE__ */ r("div", { className: `eyeon-map-editor ${I ?? ""}`, children: [
591
- /* @__PURE__ */ n(
592
- re,
2113
+ });
2114
+ }, p = e === "PORTAL", a = Mn(e, $), m = a === "editor", k = /* @__PURE__ */ o(
2115
+ Ln,
2116
+ {
2117
+ shape: L,
2118
+ assignment: pe,
2119
+ amenities: A.amenities,
2120
+ levelShapeKeys: X.filter((d) => d.id !== F).map((d) => d.key),
2121
+ canEdit: r,
2122
+ onRename: ke,
2123
+ onChangeKind: i,
2124
+ onDelete: Ne,
2125
+ onSaveAssignment: (d) => {
2126
+ r && z({ op: "upsert_assignment", assignment: d });
2127
+ }
2128
+ }
2129
+ ), I = () => /* @__PURE__ */ s(de, { children: [
2130
+ /* @__PURE__ */ o(
2131
+ Fn,
593
2132
  {
594
- tab: C,
595
- onTabChange: t,
596
- draft: i,
597
- activeLevelId: u,
598
- onSelectLevel: S,
599
- canFloors: p,
600
- canSettings: d,
601
- onImportSvg: K,
602
- onAutoroute: D,
603
- theme: v,
604
- onThemeChange: async (a) => {
605
- d && await e([{ op: "update_theme", theme: a }]);
606
- }
2133
+ disabled: B.length < 2,
2134
+ onClick: ve
607
2135
  }
608
2136
  ),
609
- /* @__PURE__ */ r("div", { className: "eyeon-map-editor__center", children: [
610
- /* @__PURE__ */ r("div", { className: "eyeon-map-editor__toolbar", children: [
611
- /* @__PURE__ */ r("div", { className: "eyeon-map-editor__tools", children: [
612
- ["select", "pan", "draw-unit", "draw-route"].map((a) => /* @__PURE__ */ n(
613
- "button",
614
- {
615
- type: "button",
616
- className: m === a ? "is-active" : "",
617
- onClick: () => B(a),
618
- disabled: !l && a.startsWith("draw"),
619
- children: a
620
- },
621
- a
622
- )),
623
- /* @__PURE__ */ n("button", { type: "button", onClick: c, disabled: b.length < 2, children: "Weld anchors" }),
624
- /* @__PURE__ */ r("label", { className: "eyeon-map-editor__angle", children: [
625
- "Base °",
626
- /* @__PURE__ */ n(
627
- "input",
2137
+ /* @__PURE__ */ s("label", { className: "eyeon-map-editor__angle", children: [
2138
+ "Snap °",
2139
+ /* @__PURE__ */ o(
2140
+ "input",
2141
+ {
2142
+ type: "number",
2143
+ value: G,
2144
+ onChange: (d) => V(Number(d.target.value) || 0)
2145
+ }
2146
+ )
2147
+ ] })
2148
+ ] });
2149
+ return /* @__PURE__ */ s("div", { className: `eyeon-map-editor eyeon-map-editor--${e} ${Q ?? ""}`, children: [
2150
+ p ? /* @__PURE__ */ o(
2151
+ xn,
2152
+ {
2153
+ section: $,
2154
+ onSectionChange: ge,
2155
+ draft: A,
2156
+ activeLevelId: R,
2157
+ selectedShapeId: F,
2158
+ onSelectShape: (d) => ye(d),
2159
+ canFloors: l,
2160
+ canSettings: t,
2161
+ onImportSvg: M,
2162
+ onCreateLevel: x,
2163
+ onUpdateLevel: N,
2164
+ onDeleteLevel: T,
2165
+ onReorderLevels: J,
2166
+ onAutoroute: b,
2167
+ theme: re,
2168
+ onThemeChange: (d) => {
2169
+ t && z({ op: "update_theme", theme: { ...A.theme, ...d } });
2170
+ },
2171
+ footer: ee,
2172
+ assignPanel: k,
2173
+ editMapPanel: /* @__PURE__ */ s(de, { children: [
2174
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
2175
+ "Level to edit",
2176
+ /* @__PURE__ */ s(
2177
+ "select",
628
2178
  {
629
- type: "number",
630
- value: A,
631
- onChange: (a) => U(Number(a.target.value) || 0)
2179
+ value: R ?? "",
2180
+ onChange: (d) => Z(d.target.value ? Number(d.target.value) : null),
2181
+ children: [
2182
+ /* @__PURE__ */ o("option", { value: "", children: "Choose floor or Outdoor…" }),
2183
+ A.levels.map((d) => /* @__PURE__ */ o("option", { value: d.id, children: d.kind === "outdoor" ? `Outdoor — ${d.name}` : d.name }, d.id))
2184
+ ]
632
2185
  }
633
2186
  )
634
- ] })
635
- ] }),
636
- /* @__PURE__ */ r("div", { className: "eyeon-map-editor__actions", children: [
637
- /* @__PURE__ */ n("button", { type: "button", onClick: () => R((a) => !a), children: k ? "Edit" : "Preview" }),
638
- /* @__PURE__ */ n(
2187
+ ] }),
2188
+ /* @__PURE__ */ o(Pe, { tool: ne, onToolChange: _, canEdit: r }),
2189
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: Wn(ne) }),
2190
+ ne === "draw-route" && /* @__PURE__ */ s("div", { className: "eyeon-map-rail__tool-extras", children: [
2191
+ I(),
2192
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__stat", children: [
2193
+ g.length,
2194
+ " path points · ",
2195
+ C.length,
2196
+ " connections"
2197
+ ] }),
2198
+ l && R != null && /* @__PURE__ */ o("div", { className: "eyeon-map-rail__actions", children: /* @__PURE__ */ o("button", { type: "button", onClick: () => b == null ? void 0 : b(R), children: "Suggest walking paths" }) })
2199
+ ] }),
2200
+ k
2201
+ ] })
2202
+ }
2203
+ ) : null,
2204
+ /* @__PURE__ */ s("div", { className: "eyeon-map-editor__center", children: [
2205
+ /* @__PURE__ */ s("div", { className: "eyeon-map-editor__toolbar", children: [
2206
+ /* @__PURE__ */ o("div", { className: "eyeon-map-editor__tools", children: m ? /* @__PURE__ */ s(de, { children: [
2207
+ /* @__PURE__ */ o(
2208
+ Pe,
2209
+ {
2210
+ tool: ne,
2211
+ onToolChange: _,
2212
+ canEdit: r
2213
+ }
2214
+ ),
2215
+ ne === "draw-route" ? I() : null
2216
+ ] }) : null }),
2217
+ /* @__PURE__ */ s("div", { className: "eyeon-map-editor__actions", children: [
2218
+ Y && /* @__PURE__ */ o("span", { className: "eyeon-map-editor__unsaved", children: "Unsaved changes" }),
2219
+ /* @__PURE__ */ o(
639
2220
  "button",
640
2221
  {
641
2222
  type: "button",
642
- className: "eyeon-map-editor__publish",
643
- onClick: () => y == null ? void 0 : y(),
644
- disabled: !l,
645
- children: "Publish"
2223
+ className: "eyeon-map-editor__save",
2224
+ onClick: () => void fe(),
2225
+ disabled: !r || !Y || ue,
2226
+ children: ue ? "Saving…" : "Save Changes"
646
2227
  }
647
2228
  )
648
2229
  ] })
649
2230
  ] }),
650
- /* @__PURE__ */ n("div", { className: "eyeon-map-editor__canvas-wrap", children: k && _ ? /* @__PURE__ */ n(se, { document: _ }) : /* @__PURE__ */ n(
651
- ae,
2231
+ a === "viewer" ? /* @__PURE__ */ o(
2232
+ Tn,
652
2233
  {
653
- level: w,
654
- shapes: Y,
655
- anchors: X,
656
- edges: j,
657
- assignments: i.assignments,
658
- theme: v,
659
- tool: m,
660
- baseAngle: A,
661
- selectedShapeId: O,
662
- selectedAnchorIds: b,
663
- baseSvgUrl: (w == null ? void 0 : w.kind) === "outdoor" ? i.baseSvgUrl ?? null : null,
664
- onSelectShape: M,
665
- onSelectAnchors: E,
666
- onCreateRoutePoint: async (a, N) => {
667
- if (!w || !l) return;
668
- const P = N ? Z(
669
- X.find((W) => W.id === N) ?? a,
670
- a,
671
- A
672
- ) : a;
673
- await e([
674
- {
2234
+ document: me,
2235
+ host: "PORTAL_ASSIGN",
2236
+ onSelectShape: ye,
2237
+ routeOnSelect: !1,
2238
+ imageProxyUrl: P
2239
+ }
2240
+ ) : /* @__PURE__ */ s(de, { children: [
2241
+ m && ne === "draw-route" && /* @__PURE__ */ o("div", { className: "eyeon-map-editor__hint", children: "Click the map to place path points. Drag two points together, then Join points, to connect them." }),
2242
+ /* @__PURE__ */ o("div", { className: "eyeon-map-editor__canvas-wrap", children: /* @__PURE__ */ o(
2243
+ dn,
2244
+ {
2245
+ level: E,
2246
+ shapes: X.filter((d) => !d.orphanedAt),
2247
+ underlayShapes: oe.filter((d) => !d.orphanedAt),
2248
+ anchors: g,
2249
+ edges: C,
2250
+ assignments: A.assignments,
2251
+ theme: re,
2252
+ tool: ne,
2253
+ baseAngle: G,
2254
+ selectedShapeId: F,
2255
+ selectedAnchorIds: B,
2256
+ baseSvgUrl: A.baseSvgUrl ?? null,
2257
+ baseViewbox: (le == null ? void 0 : le.sourceViewbox) ?? null,
2258
+ levelSvgUrl: (E == null ? void 0 : E.kind) === "outdoor" ? E.sourceSvgUrl ?? A.baseSvgUrl ?? null : null,
2259
+ interactiveOnly: (E == null ? void 0 : E.kind) === "outdoor",
2260
+ showGrid: !0,
2261
+ onSelectShape: ye,
2262
+ onSelectAnchors: v,
2263
+ onCreateRoutePoint: (d, h) => {
2264
+ if (!E || !r) return;
2265
+ const f = h ? Ve(
2266
+ g.find((D) => D.id === h) ?? d,
2267
+ d,
2268
+ G
2269
+ ) : d;
2270
+ z({
675
2271
  op: "upsert_anchor",
676
2272
  anchor: {
677
- levelId: w.id,
678
- x: P.x,
679
- y: P.y,
2273
+ levelId: E.id,
2274
+ x: f.x,
2275
+ y: f.y,
680
2276
  kind: "junction"
681
2277
  }
682
- }
683
- ]);
684
- },
685
- onMoveAnchor: async (a, N, P) => {
686
- if (!l) return;
687
- const W = X.find((H) => H.id === a);
688
- W && await e([
689
- {
2278
+ });
2279
+ },
2280
+ onMoveAnchor: (d, h, f) => {
2281
+ if (!r) return;
2282
+ const D = g.find((ie) => ie.id === d);
2283
+ D && z({
690
2284
  op: "upsert_anchor",
691
- anchor: { ...W, x: N, y: P }
692
- }
693
- ]);
694
- },
695
- onCreateShape: async (a, N) => {
696
- !w || !l || await e([
697
- {
2285
+ anchor: { ...D, x: h, y: f }
2286
+ });
2287
+ },
2288
+ onCreateShape: (d, h) => {
2289
+ if (!E || !r) return;
2290
+ const f = z({
698
2291
  op: "upsert_shape",
699
2292
  shape: {
700
- levelId: w.id,
701
- key: `${a}-${Date.now()}`,
702
- kind: a,
703
- geometry: N
2293
+ levelId: E.id,
2294
+ key: `${d}-${Date.now()}`,
2295
+ kind: d,
2296
+ geometry: h,
2297
+ origin: "manual",
2298
+ geometryLocked: !0
704
2299
  }
705
- }
706
- ]);
2300
+ });
2301
+ f != null && ye(f);
2302
+ },
2303
+ onUpdateShapeGeometry: Ie
707
2304
  }
708
- }
709
- ) })
2305
+ ) })
2306
+ ] })
2307
+ ] })
2308
+ ] });
2309
+ }
2310
+ function jn(e) {
2311
+ switch (e) {
2312
+ case "added":
2313
+ return "Added";
2314
+ case "removed":
2315
+ return "Orphaned";
2316
+ case "moved":
2317
+ return "Moved";
2318
+ case "kind_changed":
2319
+ return "Kind changed";
2320
+ default:
2321
+ return "Unchanged";
2322
+ }
2323
+ }
2324
+ function qn({
2325
+ diff: e,
2326
+ viewBoxChanged: n = !1,
2327
+ blockedMessage: r,
2328
+ busy: l = !1,
2329
+ onApply: t,
2330
+ onCancel: c
2331
+ }) {
2332
+ const [y, M] = w({}), x = se(() => {
2333
+ const N = e.items.filter((S) => S.change === "added"), T = e.items.filter((S) => S.change === "removed"), J = e.items.filter(
2334
+ (S) => S.geometryLocked && S.change !== "removed" && S.change !== "added"
2335
+ ), b = e.items.filter((S) => S.change === "moved");
2336
+ return { added: N, orphaned: T, locked: J, moved: b };
2337
+ }, [e.items]);
2338
+ return n ? /* @__PURE__ */ s("div", { className: "eyeon-map-import-review", children: [
2339
+ /* @__PURE__ */ o("div", { className: "eyeon-map-floors__error", children: r ?? "SVG viewBox changed — restore the original artboard before re-uploading." }),
2340
+ c ? /* @__PURE__ */ o("button", { type: "button", onClick: c, disabled: l, children: "Close" }) : null
2341
+ ] }) : /* @__PURE__ */ s("div", { className: "eyeon-map-import-review", children: [
2342
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Review changes before applying. Orphaned shapes keep their retailer assignments — remap them onto a newly added id if the designer renamed a store." }),
2343
+ x.added.length > 0 && /* @__PURE__ */ s("section", { children: [
2344
+ /* @__PURE__ */ s("div", { className: "eyeon-map-inspector__heading", children: [
2345
+ "Added (",
2346
+ x.added.length,
2347
+ ")"
2348
+ ] }),
2349
+ x.added.map((N) => /* @__PURE__ */ s("div", { className: "eyeon-map-rail__row", children: [
2350
+ /* @__PURE__ */ o("span", { children: N.sourceSvgId }),
2351
+ /* @__PURE__ */ o("span", { className: "eyeon-map-rail__muted", children: N.newKind })
2352
+ ] }, N.sourceSvgId))
710
2353
  ] }),
711
- /* @__PURE__ */ n(
712
- de,
713
- {
714
- shape: x,
715
- assignment: G,
716
- amenities: i.amenities,
717
- canEdit: l,
718
- onRename: s,
719
- onChangeKind: L,
720
- onSaveAssignment: async (a) => {
721
- l && await e([{ op: "upsert_assignment", assignment: a }]);
722
- },
723
- undoCount: $.length
724
- }
725
- )
2354
+ x.orphaned.length > 0 && /* @__PURE__ */ s("section", { children: [
2355
+ /* @__PURE__ */ s("div", { className: "eyeon-map-inspector__heading", children: [
2356
+ "Orphaned (",
2357
+ x.orphaned.length,
2358
+ ")"
2359
+ ] }),
2360
+ x.orphaned.map((N) => /* @__PURE__ */ s("div", { className: "eyeon-map-rail__row eyeon-map-import-review__remap", children: [
2361
+ /* @__PURE__ */ o("span", { children: N.sourceSvgId }),
2362
+ /* @__PURE__ */ s("label", { className: "eyeon-map-rail__field", children: [
2363
+ "Remap to",
2364
+ /* @__PURE__ */ s(
2365
+ "select",
2366
+ {
2367
+ value: y[N.existingShapeId] ?? "",
2368
+ disabled: l || x.added.length === 0,
2369
+ onChange: (T) => M((J) => ({
2370
+ ...J,
2371
+ [N.existingShapeId]: T.target.value
2372
+ })),
2373
+ children: [
2374
+ /* @__PURE__ */ o("option", { value: "", children: "Keep orphaned" }),
2375
+ x.added.map((T) => /* @__PURE__ */ o("option", { value: T.sourceSvgId, children: T.sourceSvgId }, T.sourceSvgId))
2376
+ ]
2377
+ }
2378
+ )
2379
+ ] })
2380
+ ] }, N.sourceSvgId))
2381
+ ] }),
2382
+ x.locked.length > 0 && /* @__PURE__ */ s("section", { children: [
2383
+ /* @__PURE__ */ s("div", { className: "eyeon-map-inspector__heading", children: [
2384
+ "Geometry locked (",
2385
+ x.locked.length,
2386
+ ")"
2387
+ ] }),
2388
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Portal edits win — kind/style may update, geometry will not." }),
2389
+ x.locked.map((N) => /* @__PURE__ */ s("div", { className: "eyeon-map-rail__row", children: [
2390
+ /* @__PURE__ */ o("span", { children: N.sourceSvgId }),
2391
+ /* @__PURE__ */ o("span", { className: "eyeon-map-rail__muted", children: jn(N.change) })
2392
+ ] }, N.sourceSvgId))
2393
+ ] }),
2394
+ x.moved.length > 0 && /* @__PURE__ */ s("section", { children: [
2395
+ /* @__PURE__ */ s("div", { className: "eyeon-map-inspector__heading", children: [
2396
+ "Moved (",
2397
+ x.moved.length,
2398
+ ")"
2399
+ ] }),
2400
+ /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "Centroid drifted — check nearby walking paths after apply." }),
2401
+ x.moved.map((N) => /* @__PURE__ */ o("div", { className: "eyeon-map-rail__row", children: /* @__PURE__ */ o("span", { children: N.sourceSvgId }) }, N.sourceSvgId))
2402
+ ] }),
2403
+ e.items.length === 0 && /* @__PURE__ */ o("p", { className: "eyeon-map-rail__hint", children: "No shape changes detected." }),
2404
+ /* @__PURE__ */ s("div", { className: "eyeon-map-rail__actions", children: [
2405
+ c ? /* @__PURE__ */ o("button", { type: "button", disabled: l, onClick: c, children: "Cancel" }) : null,
2406
+ /* @__PURE__ */ o(
2407
+ "button",
2408
+ {
2409
+ type: "button",
2410
+ className: "eyeon-map-floors__primary",
2411
+ disabled: l,
2412
+ onClick: () => void t({
2413
+ acceptAll: !0,
2414
+ remap: Object.entries(y).filter(([, N]) => !!N).map(([N, T]) => ({
2415
+ fromShapeId: Number(N),
2416
+ toSourceSvgId: T
2417
+ }))
2418
+ }),
2419
+ children: l ? "Applying…" : "Apply import"
2420
+ }
2421
+ )
2422
+ ] })
726
2423
  ] });
727
2424
  }
728
2425
  export {
729
- ae as EditorCanvas,
730
- de as Inspector,
731
- re as LeftRail,
732
- _e as MapEditor
2426
+ dn as EditorCanvas,
2427
+ Nn as FloorsPanel,
2428
+ qn as ImportReviewPanel,
2429
+ Ln as Inspector,
2430
+ xn as LeftRail,
2431
+ Zn as MapEditor,
2432
+ fn as floorsScreenTitle,
2433
+ rn as hitTestVertex,
2434
+ en as insertVertex,
2435
+ Qe as moveVertex,
2436
+ be as polygonsToGeometry,
2437
+ Mn as portalCenterSurface,
2438
+ nn as removeVertex,
2439
+ Me as translateGeometry,
2440
+ _n as visibleFloorCount
733
2441
  };
734
2442
  //# sourceMappingURL=index.js.map