floor-editor-ts 1.3.7 → 1.3.9

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.
@@ -5963,6 +5963,98 @@ if (typeof window !== "undefined") {
5963
5963
  var _window$__svelte, _window$__svelte$v, _window, _window$__svelte2;
5964
5964
  ((_window$__svelte$v = (_window$__svelte = (_window$__svelte2 = (_window = window).__svelte) !== null && _window$__svelte2 !== void 0 ? _window$__svelte2 : _window.__svelte = {}).v) !== null && _window$__svelte$v !== void 0 ? _window$__svelte$v : _window$__svelte.v = /* @__PURE__ */ new Set()).add("5");
5965
5965
  }
5966
+ //#endregion
5967
+ //#region src/lib/utils/zoneGeometry.ts
5968
+ var ZONE_COLOR_PALETTE = [
5969
+ "#F97316",
5970
+ "#22C55E",
5971
+ "#3B82F6",
5972
+ "#EF4444",
5973
+ "#A855F7",
5974
+ "#EAB308"
5975
+ ];
5976
+ var DEFAULT_ZONE_FILL_OPACITY = .1;
5977
+ function nextZoneColor(existingCount) {
5978
+ return ZONE_COLOR_PALETTE[existingCount % ZONE_COLOR_PALETTE.length];
5979
+ }
5980
+ function rectPoints(x1, y1, x2, y2) {
5981
+ const minX = Math.min(x1, x2);
5982
+ const maxX = Math.max(x1, x2);
5983
+ const minY = Math.min(y1, y2);
5984
+ const maxY = Math.max(y1, y2);
5985
+ return [
5986
+ {
5987
+ x: minX,
5988
+ y: minY
5989
+ },
5990
+ {
5991
+ x: maxX,
5992
+ y: minY
5993
+ },
5994
+ {
5995
+ x: maxX,
5996
+ y: maxY
5997
+ },
5998
+ {
5999
+ x: minX,
6000
+ y: maxY
6001
+ }
6002
+ ];
6003
+ }
6004
+ /** Isosceles triangle pointing up, centered at `c`. */
6005
+ function trianglePoints(c, size = 200) {
6006
+ const h = size * .866;
6007
+ return [
6008
+ {
6009
+ x: c.x,
6010
+ y: c.y - h / 2
6011
+ },
6012
+ {
6013
+ x: c.x + size / 2,
6014
+ y: c.y + h / 2
6015
+ },
6016
+ {
6017
+ x: c.x - size / 2,
6018
+ y: c.y + h / 2
6019
+ }
6020
+ ];
6021
+ }
6022
+ function zoneBounds(points) {
6023
+ if (!points.length) return null;
6024
+ let minX = points[0].x, minY = points[0].y, maxX = points[0].x, maxY = points[0].y;
6025
+ for (let i = 1; i < points.length; i++) {
6026
+ const p = points[i];
6027
+ if (p.x < minX) minX = p.x;
6028
+ if (p.y < minY) minY = p.y;
6029
+ if (p.x > maxX) maxX = p.x;
6030
+ if (p.y > maxY) maxY = p.y;
6031
+ }
6032
+ return {
6033
+ minX,
6034
+ minY,
6035
+ maxX,
6036
+ maxY
6037
+ };
6038
+ }
6039
+ function translatePoints(points, dx, dy) {
6040
+ return points.map((p) => ({
6041
+ x: p.x + dx,
6042
+ y: p.y + dy
6043
+ }));
6044
+ }
6045
+ /** Axis-aligned resize: keep opposite corner fixed when dragging corner index. */
6046
+ function resizeRectCorner(points, cornerIndex, to) {
6047
+ if (points.length !== 4) {
6048
+ const next = points.map((p) => ({ ...p }));
6049
+ if (next[cornerIndex]) next[cornerIndex] = { ...to };
6050
+ return next;
6051
+ }
6052
+ const fixed = points[(cornerIndex + 2) % 4];
6053
+ return rectPoints(fixed.x, fixed.y, to.x, to.y);
6054
+ }
6055
+ function isNearPoint(a, b, threshold) {
6056
+ return Math.hypot(a.x - b.x, a.y - b.y) <= threshold;
6057
+ }
5966
6058
  /** True while host → package assignedCameras sync is mutating furniture. */
5967
6059
  var assignedCamerasSyncing = false;
5968
6060
  function setAssignedCamerasSyncing(value) {
@@ -6076,6 +6168,7 @@ function createDefaultFloor(level = 0) {
6076
6168
  measurements: [],
6077
6169
  annotations: [],
6078
6170
  textAnnotations: [],
6171
+ zones: [],
6079
6172
  groups: []
6080
6173
  };
6081
6174
  }
@@ -6097,6 +6190,8 @@ var activeFloor = derived$1(currentProject, ($p) => {
6097
6190
  return (_ref = (_$p$floors$find = $p.floors.find((f) => f.id === $p.activeFloorId)) !== null && _$p$floors$find !== void 0 ? _$p$floors$find : $p.floors[0]) !== null && _ref !== void 0 ? _ref : null;
6098
6191
  });
6099
6192
  var selectedTool = writable("select");
6193
+ /** Subtype when selectedTool === 'zone' */
6194
+ var placingZoneShape = writable("rectangle");
6100
6195
  var snapEnabled = writable(true);
6101
6196
  /** When true, left-click drag pans the canvas instead of selecting */
6102
6197
  var panMode = writable(false);
@@ -6537,6 +6632,7 @@ function removeElement(id) {
6537
6632
  if (f.stairs) f.stairs = f.stairs.filter((s) => s.id !== id);
6538
6633
  if (f.columns) f.columns = f.columns.filter((c) => c.id !== id);
6539
6634
  if (f.textAnnotations) f.textAnnotations = f.textAnnotations.filter((t) => t.id !== id);
6635
+ if (f.zones) f.zones = f.zones.filter((z) => z.id !== id);
6540
6636
  }, "Deleted element");
6541
6637
  if ((removedCamera === null || removedCamera === void 0 ? void 0 : removedCamera.serial) && !isAssignedCamerasSyncing()) {
6542
6638
  const props = cameraItemToCallbackProps(removedCamera);
@@ -6639,6 +6735,7 @@ function addFloor(name, copyCurrentLayout = false) {
6639
6735
  measurements: [],
6640
6736
  annotations: [],
6641
6737
  textAnnotations: [],
6738
+ zones: [],
6642
6739
  groups: []
6643
6740
  };
6644
6741
  if (copyCurrentLayout) {
@@ -6947,6 +7044,55 @@ function moveTextAnnotation(id, position) {
6947
7044
  p.updatedAt = /* @__PURE__ */ new Date();
6948
7045
  currentProject.set({ ...p });
6949
7046
  }
7047
+ function addZone(shape, points, name, color) {
7048
+ const id = uid$1();
7049
+ mutate((f) => {
7050
+ if (!f.zones) f.zones = [];
7051
+ const count = f.zones.length;
7052
+ f.zones.push({
7053
+ id,
7054
+ name: (name === null || name === void 0 ? void 0 : name.trim()) || `Zone ${count + 1}`,
7055
+ shape,
7056
+ points: points.map((p) => ({
7057
+ x: p.x,
7058
+ y: p.y
7059
+ })),
7060
+ color: color || nextZoneColor(count),
7061
+ fillOpacity: .1
7062
+ });
7063
+ }, "Added zone");
7064
+ return id;
7065
+ }
7066
+ function updateZone(id, updates) {
7067
+ mutate((f) => {
7068
+ if (!f.zones) return;
7069
+ const z = f.zones.find((z) => z.id === id);
7070
+ if (!z) return;
7071
+ if (updates.name != null) z.name = updates.name;
7072
+ if (updates.color != null) z.color = updates.color;
7073
+ if (updates.fillOpacity != null) z.fillOpacity = updates.fillOpacity;
7074
+ if (updates.shape != null) z.shape = updates.shape;
7075
+ if (updates.points) z.points = updates.points.map((p) => ({
7076
+ x: p.x,
7077
+ y: p.y
7078
+ }));
7079
+ }, "Updated zone");
7080
+ }
7081
+ /** Live drag without undo snapshot (commit with updateZone / endUndoGroup). */
7082
+ function moveZonePoints(id, points) {
7083
+ const p = get$1(currentProject);
7084
+ if (!p) return;
7085
+ const floor = p.floors.find((f) => f.id === p.activeFloorId);
7086
+ if (!(floor === null || floor === void 0 ? void 0 : floor.zones)) return;
7087
+ const z = floor.zones.find((z) => z.id === id);
7088
+ if (!z) return;
7089
+ z.points = points.map((pt) => ({
7090
+ x: pt.x,
7091
+ y: pt.y
7092
+ }));
7093
+ p.updatedAt = /* @__PURE__ */ new Date();
7094
+ currentProject.set({ ...p });
7095
+ }
6950
7096
  var layerVisibility = writable({
6951
7097
  walls: true,
6952
7098
  doors: true,
@@ -6956,7 +7102,8 @@ var layerVisibility = writable({
6956
7102
  columns: true,
6957
7103
  guides: true,
6958
7104
  measurements: true,
6959
- annotations: true
7105
+ annotations: true,
7106
+ zones: true
6960
7107
  });
6961
7108
  function toggleFurnitureLock(id) {
6962
7109
  mutate((f) => {
@@ -7091,6 +7238,108 @@ var localStore = {
7091
7238
  }
7092
7239
  };
7093
7240
  //#endregion
7241
+ //#region src/lib/utils/heatmapColorScale.ts
7242
+ function normalizeHeatmapColorScale(value) {
7243
+ if (!value || typeof value !== "object") return void 0;
7244
+ const raw = value;
7245
+ const mode = raw.mode === "levels" ? "levels" : raw.mode === "gradient" ? "gradient" : void 0;
7246
+ if (!mode) return void 0;
7247
+ const hideBelow = typeof raw.hideBelow === "number" && Number.isFinite(raw.hideBelow) ? raw.hideBelow : 0;
7248
+ const levelsIn = Array.isArray(raw.levels) ? raw.levels : [];
7249
+ const levels = [];
7250
+ for (const item of levelsIn) {
7251
+ if (!item || typeof item !== "object") continue;
7252
+ const row = item;
7253
+ const min = typeof row.min === "number" && Number.isFinite(row.min) ? row.min : NaN;
7254
+ const color = typeof row.color === "string" && row.color.trim() ? row.color.trim() : "";
7255
+ if (!Number.isFinite(min) || !color) continue;
7256
+ const level = {
7257
+ min,
7258
+ color
7259
+ };
7260
+ if (typeof row.max === "number" && Number.isFinite(row.max)) level.max = row.max;
7261
+ if (typeof row.label === "string" && row.label.trim()) level.label = row.label.trim();
7262
+ levels.push(level);
7263
+ }
7264
+ levels.sort((a, b) => a.min - b.min);
7265
+ if (mode === "levels" && levels.length === 0) return {
7266
+ mode: "gradient",
7267
+ hideBelow
7268
+ };
7269
+ return {
7270
+ mode,
7271
+ hideBelow,
7272
+ ...levels.length ? { levels } : {}
7273
+ };
7274
+ }
7275
+ /** Fingerprint for heatmap offscreen cache invalidation. */
7276
+ function getHeatmapColorScaleKey(scale) {
7277
+ var _scale$hideBelow, _scale$levels;
7278
+ if (!scale) return "gradient";
7279
+ const hide = (_scale$hideBelow = scale.hideBelow) !== null && _scale$hideBelow !== void 0 ? _scale$hideBelow : 0;
7280
+ if (scale.mode !== "levels" || !((_scale$levels = scale.levels) === null || _scale$levels === void 0 ? void 0 : _scale$levels.length)) return `gradient:${hide}`;
7281
+ return `levels:${hide}:${scale.levels.map((l) => {
7282
+ var _l$max, _l$label;
7283
+ return `${l.min}:${(_l$max = l.max) !== null && _l$max !== void 0 ? _l$max : ""}:${l.color}:${(_l$label = l.label) !== null && _l$label !== void 0 ? _l$label : ""}`;
7284
+ }).join("|")}`;
7285
+ }
7286
+ function colorWithAlpha(color, alpha) {
7287
+ const a = Math.max(0, Math.min(1, alpha));
7288
+ const c = color.trim();
7289
+ const rgbaMatch = c.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*[\d.]+\s*)?\)$/i);
7290
+ if (rgbaMatch) return `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, ${a})`;
7291
+ let hex = c;
7292
+ const short = hex.match(/^#([0-9a-f]{3})$/i);
7293
+ if (short) {
7294
+ const h = short[1];
7295
+ hex = `#${h[0]}${h[0]}${h[1]}${h[1]}${h[2]}${h[2]}`;
7296
+ }
7297
+ const long = hex.match(/^#([0-9a-f]{6})$/i);
7298
+ if (long) {
7299
+ const n = parseInt(long[1], 16);
7300
+ return `rgba(${n >> 16 & 255}, ${n >> 8 & 255}, ${n & 255}, ${a})`;
7301
+ }
7302
+ const longA = hex.match(/^#([0-9a-f]{8})$/i);
7303
+ if (longA) {
7304
+ const n = parseInt(longA[1], 16);
7305
+ return `rgba(${n >> 24 & 255}, ${n >> 16 & 255}, ${n >> 8 & 255}, ${a})`;
7306
+ }
7307
+ return c;
7308
+ }
7309
+ /**
7310
+ * Resolve discrete band color for a cell value.
7311
+ * @returns null → do not draw
7312
+ */
7313
+ function resolveHeatmapLevelColor(value, scale) {
7314
+ var _scale$hideBelow2, _scale$levels2;
7315
+ if (!(value > ((_scale$hideBelow2 = scale.hideBelow) !== null && _scale$hideBelow2 !== void 0 ? _scale$hideBelow2 : 0))) return null;
7316
+ const levels = (_scale$levels2 = scale.levels) !== null && _scale$levels2 !== void 0 ? _scale$levels2 : [];
7317
+ if (!levels.length) return null;
7318
+ const sorted = [...levels].sort((a, b) => a.min - b.min);
7319
+ const levelCount = sorted.length;
7320
+ if (sorted.every((l) => typeof l.max === "number" && Number.isFinite(l.max))) {
7321
+ const idx = sorted.findIndex((l) => value >= l.min && value <= l.max);
7322
+ if (idx < 0) return null;
7323
+ return {
7324
+ color: sorted[idx].color,
7325
+ levelIndex: idx,
7326
+ levelCount
7327
+ };
7328
+ }
7329
+ for (let i = 0; i < sorted.length; i++) {
7330
+ const upper = i + 1 < sorted.length ? sorted[i + 1].min : Infinity;
7331
+ if (value >= sorted[i].min && value < upper) return {
7332
+ color: sorted[i].color,
7333
+ levelIndex: i,
7334
+ levelCount
7335
+ };
7336
+ }
7337
+ return null;
7338
+ }
7339
+ function isLevelsColorScale(scale) {
7340
+ return !!scale && scale.mode === "levels" && Array.isArray(scale.levels) && scale.levels.length > 0;
7341
+ }
7342
+ //#endregion
7094
7343
  //#region src/lib/packageDefaults.ts
7095
7344
  /** Flatten host camera object into string props for furniture + UI. */
7096
7345
  function assignedCameraToProps(cam) {
@@ -7110,6 +7359,7 @@ var DEFAULT_CONFIG = {
7110
7359
  floorMaxHeight: 400,
7111
7360
  heatmapEnabled: false,
7112
7361
  heatmapMatrix: [],
7362
+ heatmapColorScale: void 0,
7113
7363
  projectName: void 0,
7114
7364
  selectedCameraSerial: null,
7115
7365
  showCameraCones: false,
@@ -7140,6 +7390,7 @@ function normalizeConfig(value) {
7140
7390
  const canvasBackground = normalizeColor$1(value.canvasBackground, DEFAULT_CONFIG.canvasBackground);
7141
7391
  const floorPlateBackground = normalizeColor$1(value.floorPlateBackground, DEFAULT_CONFIG.floorPlateBackground);
7142
7392
  const headerToolsMode = value.headerToolsMode === "compact" || value.headerToolsMode === "auto" || value.headerToolsMode === "full" ? value.headerToolsMode : DEFAULT_CONFIG.headerToolsMode;
7393
+ const heatmapColorScale = normalizeHeatmapColorScale(value.heatmapColorScale);
7143
7394
  return {
7144
7395
  ...DEFAULT_CONFIG,
7145
7396
  ...value,
@@ -7149,7 +7400,8 @@ function normalizeConfig(value) {
7149
7400
  cameraThumbnailOpacity: opacity,
7150
7401
  canvasBackground,
7151
7402
  floorPlateBackground,
7152
- headerToolsMode
7403
+ headerToolsMode,
7404
+ heatmapColorScale
7153
7405
  };
7154
7406
  }
7155
7407
  function normalizeColor$1(value, fallback) {
@@ -56271,9 +56523,9 @@ var themePreference = createThemeStore();
56271
56523
  //#endregion
56272
56524
  //#region src/lib/components/toolbar/SettingsDialog.svelte
56273
56525
  init_client();
56274
- var root_2$13 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56275
- var root_3$12 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56276
- var root_4$11 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56526
+ var root_2$12 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56527
+ var root_3$11 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56528
+ var root_4$10 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56277
56529
  var root_5$8 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
56278
56530
  var root_6$5 = /* @__PURE__ */ from_html(`<div class="space-y-4"><label class="block"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Project Name</span> <input type="text" class="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="Untitled Project"/></label> <label class="block"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Description</span> <textarea rows="3" class="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none resize-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="Add a description for this project..."></textarea></label></div>`);
56279
56531
  var root_7$6 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between mb-5"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Metrics unit</span> <div class="flex rounded-lg border border-gray-300 dark:border-gray-600 overflow-hidden"><button>m, cm</button> <button>ft, inch</button></div></div> <div class="bg-gray-50 dark:bg-gray-700/50 rounded-xl divide-y divide-gray-200 dark:divide-gray-600"><label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Dimensions</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
@@ -56282,11 +56534,11 @@ var root_7$6 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-
56282
56534
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Extension Lines</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
56283
56535
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Object Distance</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
56284
56536
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <div class="flex items-center justify-between px-4 py-3.5"><span class="text-sm text-gray-700">Line Color</span> <div class="flex items-center gap-2"><button style="background-color: #ffffff" aria-label="White line color"></button> <span class="text-gray-300">|</span> <button style="background-color: #1e293b" aria-label="Dark line color"></button></div></div></div>`, 1);
56285
- var root_9$3 = /* @__PURE__ */ from_html(`<button><span class="text-2xl"> </span> <span class="text-xs font-medium text-gray-700 dark:text-gray-300"> </span></button>`);
56286
- var root_8$3 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-3">Theme</span> <div class="flex gap-3"></div></div></div>`);
56537
+ var root_9$4 = /* @__PURE__ */ from_html(`<button><span class="text-2xl"> </span> <span class="text-xs font-medium text-gray-700 dark:text-gray-300"> </span></button>`);
56538
+ var root_8$4 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-3">Theme</span> <div class="flex gap-3"></div></div></div>`);
56287
56539
  var root_11$3 = /* @__PURE__ */ from_html(`<button class="px-4 py-2 text-sm font-medium text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">Remove</button>`);
56288
56540
  var root_12$3 = /* @__PURE__ */ from_html(`<button class="px-4 py-2 text-sm font-medium text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">Remove</button>`);
56289
- var root_10$3 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">Gemini API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Required for AI-powered photorealistic rendering. Your key is stored locally in your browser only - never sent to our servers.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="AIza..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get a Gemini key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://aistudio.google.com/apikey" target="_blank" rel="noopener" class="text-blue-500 hover:underline">Google AI Studio</a></li> <li>Click "Create API Key"</li> <li>Copy and paste it above</li></ol></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">OpenAI API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Optional — enables OpenAI image generation as an alternative to Gemini. Stored locally only.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="sk-..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div> <div class="mt-3"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get an OpenAI key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener" class="text-blue-500 hover:underline">OpenAI Platform</a></li> <li>Click "Create new secret key"</li> <li>Copy and paste it above</li></ol></div></div></div>`);
56541
+ var root_10$4 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">Gemini API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Required for AI-powered photorealistic rendering. Your key is stored locally in your browser only - never sent to our servers.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="AIza..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get a Gemini key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://aistudio.google.com/apikey" target="_blank" rel="noopener" class="text-blue-500 hover:underline">Google AI Studio</a></li> <li>Click "Create API Key"</li> <li>Copy and paste it above</li></ol></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">OpenAI API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Optional — enables OpenAI image generation as an alternative to Gemini. Stored locally only.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="sk-..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div> <div class="mt-3"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get an OpenAI key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener" class="text-blue-500 hover:underline">OpenAI Platform</a></li> <li>Click "Create new secret key"</li> <li>Copy and paste it above</li></ol></div></div></div>`);
56290
56542
  var root_1$13 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center" role="dialog" tabindex="-1" aria-label="Settings"><div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-[420px] max-h-[80vh] flex flex-col" role="document"><div class="flex items-center justify-between px-5 pt-4 pb-2"><h2 class="text-lg font-bold text-gray-800 dark:text-gray-100">Settings</h2> <button class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-xl leading-none" aria-label="Close settings">✕</button></div> <div class="flex border-b border-gray-200 dark:border-gray-700 px-5"><button>Project <!></button> <button>Dimensions <!></button> <button>Appearance <!></button> <button>AI <!></button></div> <div class="p-5 overflow-y-auto"><!></div></div></div>`);
56291
56543
  function SettingsDialog($$anchor, $$props) {
56292
56544
  push($$props, true);
@@ -56399,7 +56651,7 @@ function SettingsDialog($$anchor, $$props) {
56399
56651
  var button_1 = child(div_3);
56400
56652
  var node_1 = sibling(child(button_1));
56401
56653
  var consequent = ($$anchor) => {
56402
- append($$anchor, root_2$13());
56654
+ append($$anchor, root_2$12());
56403
56655
  };
56404
56656
  if_block(node_1, ($$render) => {
56405
56657
  if (get(activeTab) === "project") $$render(consequent);
@@ -56408,7 +56660,7 @@ function SettingsDialog($$anchor, $$props) {
56408
56660
  var button_2 = sibling(button_1, 2);
56409
56661
  var node_2 = sibling(child(button_2));
56410
56662
  var consequent_1 = ($$anchor) => {
56411
- append($$anchor, root_3$12());
56663
+ append($$anchor, root_3$11());
56412
56664
  };
56413
56665
  if_block(node_2, ($$render) => {
56414
56666
  if (get(activeTab) === "dimensions") $$render(consequent_1);
@@ -56417,7 +56669,7 @@ function SettingsDialog($$anchor, $$props) {
56417
56669
  var button_3 = sibling(button_2, 2);
56418
56670
  var node_3 = sibling(child(button_3));
56419
56671
  var consequent_2 = ($$anchor) => {
56420
- append($$anchor, root_4$11());
56672
+ append($$anchor, root_4$10());
56421
56673
  };
56422
56674
  if_block(node_3, ($$render) => {
56423
56675
  if (get(activeTab) === "appearance") $$render(consequent_2);
@@ -56513,7 +56765,7 @@ function SettingsDialog($$anchor, $$props) {
56513
56765
  append($$anchor, fragment_1);
56514
56766
  };
56515
56767
  var consequent_6 = ($$anchor) => {
56516
- var div_15 = root_8$3();
56768
+ var div_15 = root_8$4();
56517
56769
  var div_16 = child(div_15);
56518
56770
  var div_17 = sibling(child(div_16), 2);
56519
56771
  each(div_17, 20, () => [
@@ -56537,7 +56789,7 @@ function SettingsDialog($$anchor, $$props) {
56537
56789
  let value = () => get($$array)[0];
56538
56790
  let icon = () => get($$array)[1];
56539
56791
  let label = () => get($$array)[2];
56540
- var button_9 = root_9$3();
56792
+ var button_9 = root_9$4();
56541
56793
  var span = child(button_9);
56542
56794
  var text = child(span, true);
56543
56795
  reset(span);
@@ -56559,7 +56811,7 @@ function SettingsDialog($$anchor, $$props) {
56559
56811
  append($$anchor, div_15);
56560
56812
  };
56561
56813
  var consequent_9 = ($$anchor) => {
56562
- var div_18 = root_10$3();
56814
+ var div_18 = root_10$4();
56563
56815
  var div_19 = child(div_18);
56564
56816
  var div_20 = sibling(child(div_19), 4);
56565
56817
  var div_21 = child(div_20);
@@ -56679,10 +56931,10 @@ delegate([
56679
56931
  //#endregion
56680
56932
  //#region src/lib/components/sidebar/AreaSummaryPanel.svelte
56681
56933
  init_client();
56682
- var root_2$12 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between text-xs bg-gray-50 rounded px-2 py-1.5"><span class="text-gray-700"> <span class="text-gray-400"> </span></span> <span class="font-medium text-gray-800"> </span></div>`);
56934
+ var root_2$11 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between text-xs bg-gray-50 rounded px-2 py-1.5"><span class="text-gray-700"> <span class="text-gray-400"> </span></span> <span class="font-medium text-gray-800"> </span></div>`);
56683
56935
  var root_1$12 = /* @__PURE__ */ from_html(`<div><h4 class="text-xs font-semibold text-gray-500 uppercase mb-1.5">By Category</h4> <div class="space-y-1"></div></div>`);
56684
- var root_4$10 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1.5 text-xs px-1 py-1"><div class="flex-1 min-w-0"><div class="flex items-center justify-between"><span class="text-gray-700 truncate"> </span> <span class="text-gray-500 ml-1 shrink-0"> </span></div> <div class="w-full bg-gray-200 rounded-full h-1 mt-0.5"><div class="bg-blue-400 h-1 rounded-full"></div></div></div> <span class="text-[10px] text-gray-400 w-8 text-right shrink-0"> </span></div>`);
56685
- var root_3$11 = /* @__PURE__ */ from_html(`<div><h4 class="text-xs font-semibold text-gray-500 uppercase mb-1.5">Room Breakdown</h4> <div class="space-y-0.5"></div></div>`);
56936
+ var root_4$9 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1.5 text-xs px-1 py-1"><div class="flex-1 min-w-0"><div class="flex items-center justify-between"><span class="text-gray-700 truncate"> </span> <span class="text-gray-500 ml-1 shrink-0"> </span></div> <div class="w-full bg-gray-200 rounded-full h-1 mt-0.5"><div class="bg-blue-400 h-1 rounded-full"></div></div></div> <span class="text-[10px] text-gray-400 w-8 text-right shrink-0"> </span></div>`);
56937
+ var root_3$10 = /* @__PURE__ */ from_html(`<div><h4 class="text-xs font-semibold text-gray-500 uppercase mb-1.5">Room Breakdown</h4> <div class="space-y-0.5"></div></div>`);
56686
56938
  var root_5$7 = /* @__PURE__ */ from_html(`<p class="text-xs text-gray-400 text-center py-4">No rooms detected yet.<br/>Draw walls to create rooms.</p>`);
56687
56939
  var root$6 = /* @__PURE__ */ from_html(`<div class="space-y-3"><div class="grid grid-cols-2 gap-2"><div class="bg-blue-50 rounded-lg p-2 text-center"><div class="text-lg font-bold text-blue-700"> </div> <div class="text-[10px] text-blue-500">Rooms</div></div> <div class="bg-green-50 rounded-lg p-2 text-center"><div class="text-lg font-bold text-green-700"> </div> <div class="text-[10px] text-green-500">Total Area</div></div> <div class="bg-amber-50 rounded-lg p-2 text-center"><div class="text-sm font-bold text-amber-700"> </div> <div class="text-[10px] text-amber-500">Doors / Windows</div></div> <div class="bg-purple-50 rounded-lg p-2 text-center"><div class="text-sm font-bold text-purple-700"> </div> <div class="text-[10px] text-purple-500">Wall Length</div></div></div> <!> <!></div>`);
56688
56940
  function AreaSummaryPanel($$anchor, $$props) {
@@ -56800,7 +57052,7 @@ function AreaSummaryPanel($$anchor, $$props) {
56800
57052
  var div_10 = root_1$12();
56801
57053
  var div_11 = sibling(child(div_10), 2);
56802
57054
  each(div_11, 21, () => get(categoryTotals), index$1, ($$anchor, cat) => {
56803
- var div_12 = root_2$12();
57055
+ var div_12 = root_2$11();
56804
57056
  var span = child(div_12);
56805
57057
  var text_4 = child(span);
56806
57058
  var span_1 = sibling(text_4);
@@ -56828,11 +57080,11 @@ function AreaSummaryPanel($$anchor, $$props) {
56828
57080
  });
56829
57081
  var node_1 = sibling(node, 2);
56830
57082
  var consequent_1 = ($$anchor) => {
56831
- var div_13 = root_3$11();
57083
+ var div_13 = root_3$10();
56832
57084
  var div_14 = sibling(child(div_13), 2);
56833
57085
  each(div_14, 21, () => get(allRooms), index$1, ($$anchor, room) => {
56834
57086
  const pct = /* @__PURE__ */ user_derived(() => get(totalArea) > 0 ? get(room).area / get(totalArea) * 100 : 0);
56835
- var div_15 = root_4$10();
57087
+ var div_15 = root_4$9();
56836
57088
  var div_16 = child(div_15);
56837
57089
  var div_17 = child(div_16);
56838
57090
  var span_3 = child(div_17);
@@ -57028,9 +57280,9 @@ async function autoSave(onDispatch) {
57028
57280
  //#endregion
57029
57281
  //#region src/lib/components/toolbar/VersionHistoryPanel.svelte
57030
57282
  init_client();
57031
- var root_2$11 = /* @__PURE__ */ from_html(`<p class="text-sm text-gray-400 text-center py-8">No snapshots yet.<br/>Versions are saved automatically every 5 minutes.</p>`);
57032
- var root_4$9 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between py-2 px-2 rounded-lg hover:bg-gray-50 group transition-colors"><div class="flex-1 min-w-0"><div class="text-sm font-medium text-gray-700 truncate"> </div> <div class="text-xs text-gray-400"> </div></div> <button class="text-xs px-2.5 py-1 bg-blue-50 text-blue-600 rounded-md hover:bg-blue-100 transition-colors opacity-0 group-hover:opacity-100 font-medium shrink-0 ml-2">Restore</button></div>`);
57033
- var root_3$10 = /* @__PURE__ */ from_html(`<div class="space-y-1"></div>`);
57283
+ var root_2$10 = /* @__PURE__ */ from_html(`<p class="text-sm text-gray-400 text-center py-8">No snapshots yet.<br/>Versions are saved automatically every 5 minutes.</p>`);
57284
+ var root_4$8 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between py-2 px-2 rounded-lg hover:bg-gray-50 group transition-colors"><div class="flex-1 min-w-0"><div class="text-sm font-medium text-gray-700 truncate"> </div> <div class="text-xs text-gray-400"> </div></div> <button class="text-xs px-2.5 py-1 bg-blue-50 text-blue-600 rounded-md hover:bg-blue-100 transition-colors opacity-0 group-hover:opacity-100 font-medium shrink-0 ml-2">Restore</button></div>`);
57285
+ var root_3$9 = /* @__PURE__ */ from_html(`<div class="space-y-1"></div>`);
57034
57286
  var root_5$6 = /* @__PURE__ */ from_html(`<div class="px-4 py-2 border-t border-gray-100"><button class="text-xs text-red-400 hover:text-red-600 transition-colors">Clear all versions</button></div>`);
57035
57287
  var root_1$11 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/40 z-50 flex items-center justify-center"><div class="bg-white rounded-xl shadow-2xl w-96 max-h-[70vh] flex flex-col"><div class="flex items-center justify-between px-4 py-3 border-b border-gray-100"><h2 class="text-sm font-semibold text-gray-800 flex items-center gap-2"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg> Version History</h2> <button class="text-gray-400 hover:text-gray-600 transition-colors" aria-label="Close"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button></div> <div class="flex-1 overflow-y-auto px-4 py-2"><!></div> <!></div></div>`);
57036
57288
  function VersionHistoryPanel($$anchor, $$props) {
@@ -57078,13 +57330,13 @@ function VersionHistoryPanel($$anchor, $$props) {
57078
57330
  var div_3 = sibling(div_2, 2);
57079
57331
  var node_1 = child(div_3);
57080
57332
  var consequent = ($$anchor) => {
57081
- append($$anchor, root_2$11());
57333
+ append($$anchor, root_2$10());
57082
57334
  };
57083
57335
  var alternate = ($$anchor) => {
57084
- var div_4 = root_3$10();
57336
+ var div_4 = root_3$9();
57085
57337
  each(div_4, 21, () => [...get(snapshots)].reverse(), index$1, ($$anchor, snap, i) => {
57086
57338
  const realIndex = /* @__PURE__ */ user_derived(() => get(snapshots).length - 1 - i);
57087
- var div_5 = root_4$9();
57339
+ var div_5 = root_4$8();
57088
57340
  var div_6 = child(div_5);
57089
57341
  var div_7 = child(div_6);
57090
57342
  var text = child(div_7, true);
@@ -57144,21 +57396,21 @@ delegate(["click", "keydown"]);
57144
57396
  init_client();
57145
57397
  init_index_client();
57146
57398
  init_onboarding_svelte();
57147
- var root_2$10 = /* @__PURE__ */ from_html(`<input type="text" class="bg-white/20 text-white font-semibold px-2 py-0.5 rounded border border-white/30 outline-none text-sm w-40"/>`);
57148
- var root_3$9 = /* @__PURE__ */ from_html(`<button class="font-semibold text-white text-sm hover:bg-white/10 px-2 py-0.5 rounded transition-colors" title="Click to rename"> </button>`);
57149
- var root_4$8 = /* @__PURE__ */ from_html(`<button> </button>`);
57399
+ var root_2$9 = /* @__PURE__ */ from_html(`<input type="text" class="bg-white/20 text-white font-semibold px-2 py-0.5 rounded border border-white/30 outline-none text-sm w-40"/>`);
57400
+ var root_3$8 = /* @__PURE__ */ from_html(`<button class="font-semibold text-white text-sm hover:bg-white/10 px-2 py-0.5 rounded transition-colors" title="Click to rename"> </button>`);
57401
+ var root_4$7 = /* @__PURE__ */ from_html(`<button> </button>`);
57150
57402
  var root_5$5 = /* @__PURE__ */ from_html(`<button aria-label="Snap to Grid"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg></button>`);
57151
57403
  var root_6$4 = /* @__PURE__ */ from_html(`<div class="flex bg-white/15 rounded-full p-0.5 shrink-0"><button title="Select mode (V)" aria-label="Select mode"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></button> <button title="Pan mode (H)" aria-label="Pan mode"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 11V6a2 2 0 0 0-4 0v1"></path><path d="M14 10V4a2 2 0 0 0-4 0v2"></path><path d="M10 10.5V6a2 2 0 0 0-4 0v8"></path><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"></path></svg></button></div>`);
57152
57404
  var root_7$5 = /* @__PURE__ */ from_html(`<button aria-label="Toggle Furniture"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="12" width="20" height="8" rx="1"></rect><path d="M4 12V7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5"></path><line x1="12" y1="12" x2="12" y2="20"></line></svg></button>`);
57153
- var root_8$2 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1 bg-white/15 rounded-full p-0.5 shrink-0"><button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom Out (−)" aria-label="Zoom Out">−</button> <button class="px-2 py-1 text-xs font-medium text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors min-w-[3rem] text-center" title="Reset Zoom (100%)"> </button> <button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom In (+)" aria-label="Zoom In">+</button></div>`);
57154
- var root_10$2 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-56 z-50" role="menu"><button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Snap to grid</span> <span> </span></button> <button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Show furniture</span> <span> </span></button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Version history</button> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Area summary</button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Settings…</button></div>`);
57155
- var root_9$2 = /* @__PURE__ */ from_html(`<div class="relative shrink-0"><button title="Settings &amp; tools" aria-label="Settings &amp; tools"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button> <!></div>`);
57405
+ var root_8$3 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1 bg-white/15 rounded-full p-0.5 shrink-0"><button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom Out (−)" aria-label="Zoom Out">−</button> <button class="px-2 py-1 text-xs font-medium text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors min-w-[3rem] text-center" title="Reset Zoom (100%)"> </button> <button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom In (+)" aria-label="Zoom In">+</button></div>`);
57406
+ var root_10$3 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-56 z-50" role="menu"><button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Snap to grid</span> <span> </span></button> <button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Show furniture</span> <span> </span></button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Version history</button> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Area summary</button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Settings…</button></div>`);
57407
+ var root_9$3 = /* @__PURE__ */ from_html(`<div class="relative shrink-0"><button title="Settings &amp; tools" aria-label="Settings &amp; tools"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button> <!></div>`);
57156
57408
  var root_11$2 = /* @__PURE__ */ from_html(`<button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Version History" aria-label="Version History"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg></button> <button class="px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Area Summary" aria-label="Area Summary"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><path d="M3 9h18"></path><path d="M9 3v18"></path></svg></button> <button class="px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Settings" aria-label="Settings"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button>`, 1);
57157
57409
  var root_13$2 = /* @__PURE__ */ from_html(`<button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> Import JSON</button>`);
57158
57410
  var root_12$2 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-48 z-50"><button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg> Print Layout</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><path d="M21 15l-5-5L5 21"></path></svg> Export 2D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg> Export 3D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg> Export as SVG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M8 16h2"></path><path d="M14 16h2"></path></svg> Export as DXF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M9 16h6"></path></svg> Export as DWG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M16 11v6"></path><path d="M8 11v6"></path><path d="M12 11v6"></path></svg> Export as PDF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path></svg> Download JSON</button> <div class="h-px bg-gray-100 my-1"></div> <!> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg> New Project</button></div>`);
57159
57411
  var root_1$10 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center px-4 gap-3 shrink-0 shadow-sm overflow-hidden"><button type="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2.5"></rect><path d="M9 3v18"></path></svg></button> <!> <div class="h-5 w-px bg-white/20"></div> <div class="flex items-center gap-1"><!> <button class="text-white/80 hover:text-white text-xs hover:bg-white/10 px-1.5 py-0.5 rounded transition-colors" title="Add Floor" aria-label="Add Floor">+</button> <span class="text-white/40 text-[10px] ml-1"> </span></div> <div class="flex-1"></div> <button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Undo (Ctrl+Z)" aria-label="Undo"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg></button> <button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Redo (Ctrl+Y)" aria-label="Redo"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.13-9.36L23 10"></path></svg></button> <div class="h-5 w-px bg-white/20"></div> <!> <!> <!> <div class="h-5 w-px bg-white/20"></div> <!> <!> <div class="h-5 w-px bg-white/20 shrink-0"></div> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Export</button> <!></div> <span><!></span> <button class="px-3 py-1.5 text-sm bg-white text-slate-800 font-semibold rounded-lg hover:bg-blue-50 transition-colors shadow-sm">Save</button></div>`);
57160
57412
  var root_18$3 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-48 z-50"><button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg> Print Layout</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><path d="M21 15l-5-5L5 21"></path></svg> Export 2D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg> Export 3D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg> Export as SVG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M8 16h2"></path><path d="M14 16h2"></path></svg> Export as DXF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M9 16h6"></path></svg> Export as DWG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M16 11v6"></path><path d="M8 11v6"></path><path d="M12 11v6"></path></svg> Export as PDF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path></svg> Download JSON</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> Import JSON</button></div>`);
57161
- var root_17$3 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center justify-between px-4 gap-3 shrink-0 shadow-sm"><span class="font-semibold text-white text-sm px-2 py-0.5 rounded transition-colors"> </span> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Import</button> <!></div></div>`);
57413
+ var root_17$2 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center justify-between px-4 gap-3 shrink-0 shadow-sm"><span class="font-semibold text-white text-sm px-2 py-0.5 rounded transition-colors"> </span> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Import</button> <!></div></div>`);
57162
57414
  var root_19$3 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/40"><div class="bg-white rounded-xl shadow-2xl w-[420px] max-h-[80vh] overflow-hidden"><div class="flex items-center justify-between px-5 py-3 border-b border-gray-200"><h2 class="text-base font-semibold text-gray-800">📐 Area Summary</h2> <button class="text-gray-400 hover:text-gray-600 text-xl leading-none">&times;</button></div> <div class="overflow-y-auto max-h-[calc(80vh-52px)] p-1"><!></div></div></div>`);
57163
57415
  var root$5 = /* @__PURE__ */ from_html(`<!> <!> <!> <!>`, 1);
57164
57416
  function TopBar($$anchor, $$props) {
@@ -57213,6 +57465,7 @@ function TopBar($$anchor, $$props) {
57213
57465
  }
57214
57466
  async function save() {
57215
57467
  const p = get$1(currentProject);
57468
+ console.log("🚀 ~ save ~ p:", p);
57216
57469
  if (!p) return;
57217
57470
  const thumbnail = captureThumbnail(p.id);
57218
57471
  $$props.onDispatch("floor:callbackEvent", {
@@ -57395,7 +57648,7 @@ function TopBar($$anchor, $$props) {
57395
57648
  var button = child(div);
57396
57649
  var node_1 = sibling(button, 2);
57397
57650
  var consequent = ($$anchor) => {
57398
- var input_1 = root_2$10();
57651
+ var input_1 = root_2$9();
57399
57652
  remove_input_defaults(input_1);
57400
57653
  event("blur", input_1, onNameBlur);
57401
57654
  delegated("keydown", input_1, onNameKeydown);
@@ -57403,7 +57656,7 @@ function TopBar($$anchor, $$props) {
57403
57656
  append($$anchor, input_1);
57404
57657
  };
57405
57658
  var alternate = ($$anchor) => {
57406
- var button_1 = root_3$9();
57659
+ var button_1 = root_3$8();
57407
57660
  var text_1 = child(button_1, true);
57408
57661
  reset(button_1);
57409
57662
  template_effect(() => set_text(text_1, get(projectName)));
@@ -57417,7 +57670,7 @@ function TopBar($$anchor, $$props) {
57417
57670
  var div_1 = sibling(node_1, 4);
57418
57671
  var node_2 = child(div_1);
57419
57672
  each(node_2, 17, () => get(floors), index$1, ($$anchor, fl) => {
57420
- var button_2 = root_4$8();
57673
+ var button_2 = root_4$7();
57421
57674
  var text_2 = child(button_2, true);
57422
57675
  reset(button_2);
57423
57676
  template_effect(() => {
@@ -57481,7 +57734,7 @@ function TopBar($$anchor, $$props) {
57481
57734
  });
57482
57735
  var node_6 = sibling(node_5, 4);
57483
57736
  var consequent_4 = ($$anchor) => {
57484
- var div_3 = root_8$2();
57737
+ var div_3 = root_8$3();
57485
57738
  var button_10 = child(div_3);
57486
57739
  var button_11 = sibling(button_10, 2);
57487
57740
  var text_4 = child(button_11);
@@ -57499,11 +57752,11 @@ function TopBar($$anchor, $$props) {
57499
57752
  });
57500
57753
  var node_7 = sibling(node_6, 2);
57501
57754
  var consequent_6 = ($$anchor) => {
57502
- var div_4 = root_9$2();
57755
+ var div_4 = root_9$3();
57503
57756
  var button_13 = child(div_4);
57504
57757
  var node_8 = sibling(button_13, 2);
57505
57758
  var consequent_5 = ($$anchor) => {
57506
- var div_5 = root_10$2();
57759
+ var div_5 = root_10$3();
57507
57760
  var button_14 = child(div_5);
57508
57761
  var span_1 = sibling(child(button_14), 2);
57509
57762
  var text_5 = child(span_1, true);
@@ -57660,7 +57913,7 @@ function TopBar($$anchor, $$props) {
57660
57913
  append($$anchor, div);
57661
57914
  };
57662
57915
  var alternate_3 = ($$anchor) => {
57663
- var div_8 = root_17$3();
57916
+ var div_8 = root_17$2();
57664
57917
  var span_4 = child(div_8);
57665
57918
  var text_10 = child(span_4, true);
57666
57919
  reset(span_4);
@@ -58294,9 +58547,9 @@ function placeRoomTemplate(preset, origin, template, w = 400, h = 300) {
58294
58547
  //#endregion
58295
58548
  //#region src/lib/components/editor/UndoHistoryPanel.svelte
58296
58549
  init_client();
58297
- var root_2$9 = /* @__PURE__ */ from_html(`<div class="px-3 py-6 text-center text-xs text-gray-400">No history yet</div>`);
58298
- var root_4$7 = /* @__PURE__ */ from_html(`<button><span class="w-5 text-[10px] text-gray-400 text-right shrink-0"></span> <span class="truncate flex-1"> </span> <span class="text-[10px] text-gray-300 shrink-0"> </span></button>`);
58299
- var root_3$8 = /* @__PURE__ */ from_html(`<div class="py-1"><!> <div><span class="w-5 text-[10px] text-gray-400 text-right shrink-0">●</span> <span class="truncate flex-1 font-medium">Current state</span></div></div>`);
58550
+ var root_2$8 = /* @__PURE__ */ from_html(`<div class="px-3 py-6 text-center text-xs text-gray-400">No history yet</div>`);
58551
+ var root_4$6 = /* @__PURE__ */ from_html(`<button><span class="w-5 text-[10px] text-gray-400 text-right shrink-0"></span> <span class="truncate flex-1"> </span> <span class="text-[10px] text-gray-300 shrink-0"> </span></button>`);
58552
+ var root_3$7 = /* @__PURE__ */ from_html(`<div class="py-1"><!> <div><span class="w-5 text-[10px] text-gray-400 text-right shrink-0">●</span> <span class="truncate flex-1 font-medium">Current state</span></div></div>`);
58300
58553
  var root_1$9 = /* @__PURE__ */ from_html(`<div class="fixed bottom-12 left-4 w-64 max-h-80 bg-white rounded-xl shadow-2xl border border-gray-200 z-50 flex flex-col overflow-hidden"><div class="flex items-center justify-between px-3 py-2 border-b border-gray-100 bg-gray-50"><div class="flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-slate-500"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg> <span class="text-xs font-semibold text-slate-700">Undo History</span></div> <div class="flex items-center gap-2"><span class="text-[10px] text-slate-400"> </span> <button class="text-gray-400 hover:text-gray-600 text-sm leading-none" aria-label="Close history">✕</button></div></div> <div class="flex-1 overflow-y-auto"><!></div></div>`);
58301
58554
  function UndoHistoryPanel($$anchor, $$props) {
58302
58555
  push($$props, true);
@@ -58333,13 +58586,13 @@ function UndoHistoryPanel($$anchor, $$props) {
58333
58586
  var div_3 = sibling(div_1, 2);
58334
58587
  var node_1 = child(div_3);
58335
58588
  var consequent = ($$anchor) => {
58336
- append($$anchor, root_2$9());
58589
+ append($$anchor, root_2$8());
58337
58590
  };
58338
58591
  var alternate = ($$anchor) => {
58339
- var div_5 = root_3$8();
58592
+ var div_5 = root_3$7();
58340
58593
  var node_2 = child(div_5);
58341
58594
  each(node_2, 17, () => get(history).entries, index$1, ($$anchor, entry, i) => {
58342
- var button_1 = root_4$7();
58595
+ var button_1 = root_4$6();
58343
58596
  let classes;
58344
58597
  var span_1 = child(button_1);
58345
58598
  span_1.textContent = i + 1;
@@ -58397,24 +58650,24 @@ delegate(["click"]);
58397
58650
  //#region src/lib/components/sidebar/BuildPanel.svelte
58398
58651
  init_client();
58399
58652
  init_index_client();
58400
- var root_3$7 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-amber-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#92400e" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path></path></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
58401
- var root_4$6 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-cyan-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#0e7490" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="1"></rect><line x1="12" y1="4" x2="12" y2="20"></line><line x1="3" y1="12" x2="21" y2="12"></line></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
58402
- var root_2$8 = /* @__PURE__ */ from_html(`<div class="grid grid-cols-2 gap-2 mb-3"></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Windows</h3> <div class="grid grid-cols-2 gap-2"></div>`, 1);
58403
- var root_1$8 = /* @__PURE__ */ from_html(`<div class="space-y-1"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Tools</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></div> <div class="text-left"><div class="font-medium">Select <span class="text-gray-400 text-xs ml-1">V</span></div> <div class="text-xs text-gray-400">Click to select elements</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="8" rx="1"></rect><line x1="7" y1="8" x2="7" y2="16"></line><line x1="12" y1="8" x2="12" y2="16"></line><line x1="17" y1="8" x2="17" y2="16"></line></svg></div> <div class="text-left"><div class="font-medium">Draw Wall <span class="text-gray-400 text-xs ml-1">W</span></div> <div class="text-xs text-gray-400">Click to draw, dbl-click to finish</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Structure</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 5h-5V2h-3v6h-4V5H7v6H2v3h5v3h3v-3h4v3h3v-6h5z"></path></svg></div> <div class="text-left"><div class="font-medium">Add Stairs</div> <div class="text-xs text-gray-400">Click to place stairs</div></div></button> <div class="flex gap-2"><button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="6"></circle><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Round Column</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="6" y="6" width="12" height="12"></rect><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Square Column</div></div></button></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Annotate</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h16v3"></path><line x1="12" y1="4" x2="12" y2="20"></line><line x1="8" y1="20" x2="16" y2="20"></line></svg></div> <div class="text-left"><div class="font-medium">Text Label</div> <div class="text-xs text-gray-400">Add text annotations (T)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><line x1="16" y1="5" x2="22" y2="5"></line><line x1="19" y1="2" x2="19" y2="8"></line><line x1="3" y1="12" x2="12" y2="12"></line></svg></div> <div class="text-left"><div class="font-medium">Dimension</div> <div class="text-xs text-gray-400">Add dimension annotations (N)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12h5l2-7 4 14 2-7h7"></path></svg></div> <div class="text-left"><div class="font-medium">Measure</div> <div class="text-xs text-gray-400">Measure distances (M)</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Import</h3> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="9" cy="9" r="2"></circle><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path></svg></div> <div class="text-left"><div class="font-medium">Import Image</div> <div class="text-xs text-gray-400">Floor plan background</div></div></button> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg></div> <div class="text-left"><div class="font-medium">Import RoomPlan</div> <div class="text-xs text-gray-400">iOS LiDAR scan (.json/.zip)</div></div></button> <button class="w-full flex items-center justify-between px-1 py-2 mt-3"><h3 class="text-xs font-semibold text-gray-400 uppercase">Doors</h3> <span class="text-gray-400 text-xs"> </span></button> <!></div>`);
58404
- var root_6$3 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-blue-300 hover:bg-blue-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-gray-50 flex items-center justify-center text-2xl font-mono"> </div> <span class="text-xs font-medium text-gray-600"> </span></button>`);
58405
- var root_7$4 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-green-300 hover:bg-green-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-green-50 flex items-center justify-center text-lg"><!></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
58406
- var root_5$4 = /* @__PURE__ */ from_html(`<div class="space-y-2"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Room Presets</h3> <p class="text-xs text-gray-400 mb-3">Click to add a room shape to the canvas</p> <div class="grid grid-cols-2 gap-2"></div> <hr class="my-3 border-gray-200"/> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Room Templates</h3> <p class="text-xs text-gray-400 mb-3">Pre-furnished rooms — walls + furniture in one click</p> <div class="grid grid-cols-2 gap-2"></div></div>`);
58407
- var root_16$1 = /* @__PURE__ */ from_html(`<button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 w-5 h-5 flex items-center justify-center rounded-full hover:bg-gray-100" title="Clear search"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button>`);
58408
- var root_17$2 = /* @__PURE__ */ from_html(`<div class="text-[10px] text-gray-400 px-1"> </div>`);
58409
- var root_18$2 = /* @__PURE__ */ from_html(`<button> </button>`);
58410
- var root_20$2 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-8 h-8 rounded-lg flex items-center justify-center"><div class="w-4 h-4 rounded-sm"></div></div> <span class="text-[10px] font-medium text-gray-600 leading-tight text-center"> </span></button>`);
58411
- var root_19$2 = /* @__PURE__ */ from_html(`<div class="mt-1"><h4 class="text-[10px] font-semibold text-gray-400 uppercase mb-1.5">Recent</h4> <div class="grid grid-cols-2 gap-2"></div></div> <hr class="border-gray-100"/>`, 1);
58412
- var root_22$2 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> <mark class="bg-yellow-200 text-gray-800 rounded-sm px-0.5"> </mark> </span>`);
58413
- var root_23$2 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> </span>`);
58414
- var root_21$1 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-10 h-10 rounded-lg flex items-center justify-center"><div class="w-5 h-5 rounded-sm"></div></div> <!> <span class="text-[10px] text-gray-400"> </span></button>`);
58415
- var root_15$2 = /* @__PURE__ */ from_html(`<div class="space-y-2"><div class="relative"><input type="text" placeholder="Search furniture..." class="w-full px-3 py-2 pr-8 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-200 focus:border-blue-400 outline-none"/> <!></div> <!> <div class="flex flex-wrap gap-1 max-h-24 overflow-y-auto"><button>All</button> <button> </button> <!></div> <!> <div class="grid grid-cols-2 gap-2 mt-2"></div></div>`);
58416
- var root_24$2 = /* @__PURE__ */ from_html(`<div class="fixed z-50 pointer-events-none"><div class="bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden" style="width: 220px;"><div class="w-full h-[120px] bg-gray-50 flex items-center justify-center p-3"><div class="w-16 h-16 rounded-xl flex items-center justify-center"><div class="w-10 h-10 rounded-md"></div></div></div> <div class="p-3 space-y-1.5"><div class="flex items-center gap-2"><span class="text-sm font-semibold text-gray-800"> </span> <span class="px-1.5 py-0.5 rounded-full text-[9px] font-semibold text-white"> </span></div> <div class="text-xs text-gray-500"> </div></div></div></div>`);
58417
- var root_25$1 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center"><div class="bg-white rounded-xl shadow-2xl w-80 p-5"><h3 class="text-sm font-bold text-gray-800 mb-1">Import RoomPlan</h3> <p class="text-xs text-gray-400 mb-4"> </p> <div class="space-y-3"><label class="flex items-start gap-2.5 cursor-pointer"><input type="checkbox" class="accent-blue-500 mt-0.5"/> <div><div class="text-sm font-medium text-gray-700">Straighten walls</div> <div class="text-xs text-gray-400">Snap near-horizontal/vertical walls to axis</div></div></label> <label class="flex items-start gap-2.5 cursor-pointer"><input type="checkbox" class="accent-blue-500 mt-0.5"/> <div><div class="text-sm font-medium text-gray-700">Enforce orthogonal <span class="text-xs text-blue-400 font-mono"> </span></div> <div class="text-xs text-gray-400">Force all walls to 90°/180° angles</div></div></label> <label class="block"><div class="text-xs text-gray-500 mb-1">Corner merge distance (cm)</div> <input type="number" min="0" max="50" step="5" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div> <div class="flex gap-2 mt-5"><button class="flex-1 px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition-colors">Cancel</button> <button class="flex-1 px-3 py-2 bg-blue-500 text-white rounded-lg text-sm font-medium hover:bg-blue-600 transition-colors">Import</button></div></div></div>`);
58653
+ var root_6$3 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-amber-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#92400e" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path></path></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
58654
+ var root_7$4 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-cyan-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#0e7490" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="1"></rect><line x1="12" y1="4" x2="12" y2="20"></line><line x1="3" y1="12" x2="21" y2="12"></line></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
58655
+ var root_5$4 = /* @__PURE__ */ from_html(`<div class="grid grid-cols-2 gap-2 mb-3"></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Windows</h3> <div class="grid grid-cols-2 gap-2"></div>`, 1);
58656
+ var root_1$8 = /* @__PURE__ */ from_html(`<div class="space-y-1"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Tools</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></div> <div class="text-left"><div class="font-medium">Select <span class="text-gray-400 text-xs ml-1">V</span></div> <div class="text-xs text-gray-400">Click to select elements</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="8" rx="1"></rect><line x1="7" y1="8" x2="7" y2="16"></line><line x1="12" y1="8" x2="12" y2="16"></line><line x1="17" y1="8" x2="17" y2="16"></line></svg></div> <div class="text-left"><div class="font-medium">Draw Wall <span class="text-gray-400 text-xs ml-1">W</span></div> <div class="text-xs text-gray-400">Click to draw, dbl-click to finish</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Structure</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 5h-5V2h-3v6h-4V5H7v6H2v3h5v3h3v-3h4v3h3v-6h5z"></path></svg></div> <div class="text-left"><div class="font-medium">Add Stairs</div> <div class="text-xs text-gray-400">Click to place stairs</div></div></button> <div class="flex gap-2"><button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="6"></circle><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Round Column</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="6" y="6" width="12" height="12"></rect><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Square Column</div></div></button></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Zones</h3> <div class="grid grid-cols-3 gap-1.5 mb-1"><button type="button" title="Drag to create rectangle zone"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><rect x="4" y="6" width="16" height="12" rx="1"></rect></svg> Rect</button> <button type="button" title="Click to place triangle zone"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M12 4 L20 19 L4 19 Z"></path></svg> Triangle</button> <button type="button" title="Click points; click first point or Enter to close"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M7 4 L17 6 L20 14 L12 20 L4 12 Z"></path></svg> Polygon</button></div> <p class="text-[10px] text-gray-400 mb-2 px-0.5"><!></p> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Annotate</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h16v3"></path><line x1="12" y1="4" x2="12" y2="20"></line><line x1="8" y1="20" x2="16" y2="20"></line></svg></div> <div class="text-left"><div class="font-medium">Text Label</div> <div class="text-xs text-gray-400">Add text annotations (T)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><line x1="16" y1="5" x2="22" y2="5"></line><line x1="19" y1="2" x2="19" y2="8"></line><line x1="3" y1="12" x2="12" y2="12"></line></svg></div> <div class="text-left"><div class="font-medium">Dimension</div> <div class="text-xs text-gray-400">Add dimension annotations (N)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12h5l2-7 4 14 2-7h7"></path></svg></div> <div class="text-left"><div class="font-medium">Measure</div> <div class="text-xs text-gray-400">Measure distances (M)</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Import</h3> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="9" cy="9" r="2"></circle><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path></svg></div> <div class="text-left"><div class="font-medium">Import Image</div> <div class="text-xs text-gray-400">Floor plan background</div></div></button> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg></div> <div class="text-left"><div class="font-medium">Import RoomPlan</div> <div class="text-xs text-gray-400">iOS LiDAR scan (.json/.zip)</div></div></button> <button class="w-full flex items-center justify-between px-1 py-2 mt-3"><h3 class="text-xs font-semibold text-gray-400 uppercase">Doors</h3> <span class="text-gray-400 text-xs"> </span></button> <!></div>`);
58657
+ var root_9$2 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-blue-300 hover:bg-blue-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-gray-50 flex items-center justify-center text-2xl font-mono"> </div> <span class="text-xs font-medium text-gray-600"> </span></button>`);
58658
+ var root_10$2 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-green-300 hover:bg-green-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-green-50 flex items-center justify-center text-lg"><!></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
58659
+ var root_8$2 = /* @__PURE__ */ from_html(`<div class="space-y-2"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Room Presets</h3> <p class="text-xs text-gray-400 mb-3">Click to add a room shape to the canvas</p> <div class="grid grid-cols-2 gap-2"></div> <hr class="my-3 border-gray-200"/> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Room Templates</h3> <p class="text-xs text-gray-400 mb-3">Pre-furnished rooms — walls + furniture in one click</p> <div class="grid grid-cols-2 gap-2"></div></div>`);
58660
+ var root_19$2 = /* @__PURE__ */ from_html(`<button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 w-5 h-5 flex items-center justify-center rounded-full hover:bg-gray-100" title="Clear search"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button>`);
58661
+ var root_20$2 = /* @__PURE__ */ from_html(`<div class="text-[10px] text-gray-400 px-1"> </div>`);
58662
+ var root_21$1 = /* @__PURE__ */ from_html(`<button> </button>`);
58663
+ var root_23$2 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-8 h-8 rounded-lg flex items-center justify-center"><div class="w-4 h-4 rounded-sm"></div></div> <span class="text-[10px] font-medium text-gray-600 leading-tight text-center"> </span></button>`);
58664
+ var root_22$2 = /* @__PURE__ */ from_html(`<div class="mt-1"><h4 class="text-[10px] font-semibold text-gray-400 uppercase mb-1.5">Recent</h4> <div class="grid grid-cols-2 gap-2"></div></div> <hr class="border-gray-100"/>`, 1);
58665
+ var root_25$1 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> <mark class="bg-yellow-200 text-gray-800 rounded-sm px-0.5"> </mark> </span>`);
58666
+ var root_26$1 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> </span>`);
58667
+ var root_24$1 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-10 h-10 rounded-lg flex items-center justify-center"><div class="w-5 h-5 rounded-sm"></div></div> <!> <span class="text-[10px] text-gray-400"> </span></button>`);
58668
+ var root_18$2 = /* @__PURE__ */ from_html(`<div class="space-y-2"><div class="relative"><input type="text" placeholder="Search furniture..." class="w-full px-3 py-2 pr-8 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-200 focus:border-blue-400 outline-none"/> <!></div> <!> <div class="flex flex-wrap gap-1 max-h-24 overflow-y-auto"><button>All</button> <button> </button> <!></div> <!> <div class="grid grid-cols-2 gap-2 mt-2"></div></div>`);
58669
+ var root_27$1 = /* @__PURE__ */ from_html(`<div class="fixed z-50 pointer-events-none"><div class="bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden" style="width: 220px;"><div class="w-full h-[120px] bg-gray-50 flex items-center justify-center p-3"><div class="w-16 h-16 rounded-xl flex items-center justify-center"><div class="w-10 h-10 rounded-md"></div></div></div> <div class="p-3 space-y-1.5"><div class="flex items-center gap-2"><span class="text-sm font-semibold text-gray-800"> </span> <span class="px-1.5 py-0.5 rounded-full text-[9px] font-semibold text-white"> </span></div> <div class="text-xs text-gray-500"> </div></div></div></div>`);
58670
+ var root_28$1 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center"><div class="bg-white rounded-xl shadow-2xl w-80 p-5"><h3 class="text-sm font-bold text-gray-800 mb-1">Import RoomPlan</h3> <p class="text-xs text-gray-400 mb-4"> </p> <div class="space-y-3"><label class="flex items-start gap-2.5 cursor-pointer"><input type="checkbox" class="accent-blue-500 mt-0.5"/> <div><div class="text-sm font-medium text-gray-700">Straighten walls</div> <div class="text-xs text-gray-400">Snap near-horizontal/vertical walls to axis</div></div></label> <label class="flex items-start gap-2.5 cursor-pointer"><input type="checkbox" class="accent-blue-500 mt-0.5"/> <div><div class="text-sm font-medium text-gray-700">Enforce orthogonal <span class="text-xs text-blue-400 font-mono"> </span></div> <div class="text-xs text-gray-400">Force all walls to 90°/180° angles</div></div></label> <label class="block"><div class="text-xs text-gray-500 mb-1">Corner merge distance (cm)</div> <input type="number" min="0" max="50" step="5" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div> <div class="flex gap-2 mt-5"><button class="flex-1 px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition-colors">Cancel</button> <button class="flex-1 px-3 py-2 bg-blue-500 text-white rounded-lg text-sm font-medium hover:bg-blue-600 transition-colors">Import</button></div></div></div>`);
58418
58671
  var root$4 = /* @__PURE__ */ from_html(`<div class="relative w-64 bg-white border-r border-gray-200 flex flex-col h-full overflow-hidden"><div class="flex border-b border-gray-200"><button>Build</button> <button>Rooms</button> <button>Objects</button></div> <div class="flex-1 overflow-y-auto p-3"><!></div> <button title="Layers Panel (L)" aria-label="Toggle Layers Panel">🗂</button> <button title="Undo History" aria-label="Toggle Undo History">⟲</button> <button class="absolute bottom-4 left-4 w-8 h-8 rounded-full bg-slate-700 text-white text-sm font-bold shadow-lg hover:bg-slate-600 transition-colors z-50" title="Keyboard Shortcuts (?)" aria-label="Keyboard Shortcuts">?</button></div> <!> <!>`, 1);
58419
58672
  function BuildPanel($$anchor, $$props) {
58420
58673
  push($$props, true);
@@ -58433,10 +58686,21 @@ function BuildPanel($$anchor, $$props) {
58433
58686
  selectedTool.set(tool);
58434
58687
  placingFurnitureId.set(null);
58435
58688
  }
58689
+ function setZoneTool(shape) {
58690
+ placingZoneShape.set(shape);
58691
+ placingFurnitureId.set(null);
58692
+ placingStair.set(false);
58693
+ placingColumn.set(false);
58694
+ selectedTool.set("zone");
58695
+ }
58436
58696
  let currentTool = /* @__PURE__ */ state("select");
58437
58697
  selectedTool.subscribe((t) => {
58438
58698
  set(currentTool, t, true);
58439
58699
  });
58700
+ let currentZoneShape = /* @__PURE__ */ state("rectangle");
58701
+ placingZoneShape.subscribe((s) => {
58702
+ set(currentZoneShape, s, true);
58703
+ });
58440
58704
  let currentPlacing = /* @__PURE__ */ state(null);
58441
58705
  placingFurnitureId.subscribe((id) => {
58442
58706
  set(currentPlacing, id, true);
@@ -58734,7 +58998,7 @@ function BuildPanel($$anchor, $$props) {
58734
58998
  reset(div_1);
58735
58999
  var div_2 = sibling(div_1, 2);
58736
59000
  var node = child(div_2);
58737
- var consequent_1 = ($$anchor) => {
59001
+ var consequent_4 = ($$anchor) => {
58738
59002
  var div_3 = root_1$8();
58739
59003
  var button_3 = sibling(child(div_3), 2);
58740
59004
  var div_4 = child(button_3);
@@ -58758,86 +59022,108 @@ function BuildPanel($$anchor, $$props) {
58758
59022
  next(2);
58759
59023
  reset(button_7);
58760
59024
  reset(div_7);
58761
- var button_8 = sibling(div_7, 4);
58762
- var div_10 = child(button_8);
58763
- next(2);
58764
- reset(button_8);
59025
+ var div_10 = sibling(div_7, 4);
59026
+ var button_8 = child(div_10);
58765
59027
  var button_9 = sibling(button_8, 2);
58766
- var div_11 = child(button_9);
58767
- next(2);
58768
- reset(button_9);
58769
59028
  var button_10 = sibling(button_9, 2);
58770
- var div_12 = child(button_10);
59029
+ reset(div_10);
59030
+ var p_1 = sibling(div_10, 2);
59031
+ var node_1 = child(p_1);
59032
+ var consequent = ($$anchor) => {
59033
+ append($$anchor, text$1("Drag on canvas to draw a rectangle"));
59034
+ };
59035
+ var consequent_1 = ($$anchor) => {
59036
+ append($$anchor, text$1("Click to place a triangle, then drag vertices"));
59037
+ };
59038
+ var consequent_2 = ($$anchor) => {
59039
+ append($$anchor, text$1("Click vertices · Enter / click first point to close"));
59040
+ };
59041
+ if_block(node_1, ($$render) => {
59042
+ if (get(currentTool) === "zone" && get(currentZoneShape) === "rectangle") $$render(consequent);
59043
+ else if (get(currentTool) === "zone" && get(currentZoneShape) === "triangle") $$render(consequent_1, 1);
59044
+ else if (get(currentTool) === "zone" && get(currentZoneShape) === "polygon") $$render(consequent_2, 2);
59045
+ });
59046
+ reset(p_1);
59047
+ var button_11 = sibling(p_1, 4);
59048
+ var div_11 = child(button_11);
58771
59049
  next(2);
58772
- reset(button_10);
58773
- var button_11 = sibling(button_10, 4);
59050
+ reset(button_11);
58774
59051
  var button_12 = sibling(button_11, 2);
59052
+ var div_12 = child(button_12);
59053
+ next(2);
59054
+ reset(button_12);
58775
59055
  var button_13 = sibling(button_12, 2);
58776
- var span = sibling(child(button_13), 2);
58777
- var text_1 = child(span, true);
58778
- reset(span);
59056
+ var div_13 = child(button_13);
59057
+ next(2);
58779
59058
  reset(button_13);
58780
- var node_1 = sibling(button_13, 2);
58781
- var consequent = ($$anchor) => {
58782
- var fragment_1 = root_2$8();
58783
- var div_13 = first_child(fragment_1);
58784
- each(div_13, 21, () => doorCatalog, index$1, ($$anchor, dc) => {
58785
- var button_14 = root_3$7();
58786
- var div_14 = child(button_14);
58787
- var svg = child(div_14);
59059
+ var button_14 = sibling(button_13, 4);
59060
+ var button_15 = sibling(button_14, 2);
59061
+ var button_16 = sibling(button_15, 2);
59062
+ var span = sibling(child(button_16), 2);
59063
+ var text_4 = child(span, true);
59064
+ reset(span);
59065
+ reset(button_16);
59066
+ var node_2 = sibling(button_16, 2);
59067
+ var consequent_3 = ($$anchor) => {
59068
+ var fragment_1 = root_5$4();
59069
+ var div_14 = first_child(fragment_1);
59070
+ each(div_14, 21, () => doorCatalog, index$1, ($$anchor, dc) => {
59071
+ var button_17 = root_6$3();
59072
+ var div_15 = child(button_17);
59073
+ var svg = child(div_15);
58788
59074
  var path = child(svg);
58789
59075
  reset(svg);
58790
- reset(div_14);
58791
- var span_1 = sibling(div_14, 2);
58792
- var text_2 = child(span_1, true);
59076
+ reset(div_15);
59077
+ var span_1 = sibling(div_15, 2);
59078
+ var text_5 = child(span_1, true);
58793
59079
  reset(span_1);
58794
59080
  var span_2 = sibling(span_1, 2);
58795
- var text_3 = child(span_2, true);
59081
+ var text_6 = child(span_2, true);
58796
59082
  reset(span_2);
58797
- reset(button_14);
59083
+ reset(button_17);
58798
59084
  template_effect(() => {
58799
- set_class(button_14, 1, `flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentTool) === "door" && get(selectedDoorType) === get(dc).type ? "border-blue-400 bg-blue-50" : "border-gray-100 hover:border-gray-200"}`);
59085
+ set_class(button_17, 1, `flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentTool) === "door" && get(selectedDoorType) === get(dc).type ? "border-blue-400 bg-blue-50" : "border-gray-100 hover:border-gray-200"}`);
58800
59086
  set_attribute(path, "d", get(dc).icon);
58801
- set_text(text_2, get(dc).name);
58802
- set_text(text_3, get(dc).desc);
59087
+ set_text(text_5, get(dc).name);
59088
+ set_text(text_6, get(dc).desc);
58803
59089
  });
58804
- delegated("click", button_14, () => setDoorType(get(dc).type));
58805
- event("dragstart", button_14, (e) => {
59090
+ delegated("click", button_17, () => setDoorType(get(dc).type));
59091
+ event("dragstart", button_17, (e) => {
58806
59092
  var _e$dataTransfer, _e$dataTransfer2;
58807
59093
  (_e$dataTransfer = e.dataTransfer) === null || _e$dataTransfer === void 0 || _e$dataTransfer.setData("application/o3d-type", "door");
58808
59094
  (_e$dataTransfer2 = e.dataTransfer) === null || _e$dataTransfer2 === void 0 || _e$dataTransfer2.setData("application/o3d-id", get(dc).type);
58809
59095
  });
58810
- append($$anchor, button_14);
59096
+ append($$anchor, button_17);
58811
59097
  });
58812
- reset(div_13);
58813
- var div_15 = sibling(div_13, 4);
58814
- each(div_15, 21, () => windowCatalog, index$1, ($$anchor, wc) => {
58815
- var button_15 = root_4$6();
58816
- var span_3 = sibling(child(button_15), 2);
58817
- var text_4 = child(span_3, true);
59098
+ reset(div_14);
59099
+ var div_16 = sibling(div_14, 4);
59100
+ each(div_16, 21, () => windowCatalog, index$1, ($$anchor, wc) => {
59101
+ var button_18 = root_7$4();
59102
+ var span_3 = sibling(child(button_18), 2);
59103
+ var text_7 = child(span_3, true);
58818
59104
  reset(span_3);
58819
59105
  var span_4 = sibling(span_3, 2);
58820
- var text_5 = child(span_4, true);
59106
+ var text_8 = child(span_4, true);
58821
59107
  reset(span_4);
58822
- reset(button_15);
59108
+ reset(button_18);
58823
59109
  template_effect(() => {
58824
- set_class(button_15, 1, `flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentTool) === "window" && get(selectedWindowType) === get(wc).type ? "border-blue-400 bg-blue-50" : "border-gray-100 hover:border-gray-200"}`);
58825
- set_text(text_4, get(wc).name);
58826
- set_text(text_5, get(wc).desc);
59110
+ set_class(button_18, 1, `flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentTool) === "window" && get(selectedWindowType) === get(wc).type ? "border-blue-400 bg-blue-50" : "border-gray-100 hover:border-gray-200"}`);
59111
+ set_text(text_7, get(wc).name);
59112
+ set_text(text_8, get(wc).desc);
58827
59113
  });
58828
- delegated("click", button_15, () => setWindowType(get(wc).type));
58829
- event("dragstart", button_15, (e) => {
59114
+ delegated("click", button_18, () => setWindowType(get(wc).type));
59115
+ event("dragstart", button_18, (e) => {
58830
59116
  var _e$dataTransfer3, _e$dataTransfer4;
58831
59117
  (_e$dataTransfer3 = e.dataTransfer) === null || _e$dataTransfer3 === void 0 || _e$dataTransfer3.setData("application/o3d-type", "window");
58832
59118
  (_e$dataTransfer4 = e.dataTransfer) === null || _e$dataTransfer4 === void 0 || _e$dataTransfer4.setData("application/o3d-id", get(wc).type);
58833
59119
  });
58834
- append($$anchor, button_15);
59120
+ append($$anchor, button_18);
58835
59121
  });
58836
- reset(div_15);
59122
+ reset(div_16);
58837
59123
  append($$anchor, fragment_1);
58838
59124
  };
58839
- if_block(node_1, ($$render) => {
58840
- if (get(constructionOpen)) $$render(consequent);
59125
+ if_block(node_2, ($$render) => {
59126
+ if (get(constructionOpen)) $$render(consequent_3);
58841
59127
  });
58842
59128
  reset(div_3);
58843
59129
  template_effect(() => {
@@ -58851,200 +59137,206 @@ function BuildPanel($$anchor, $$props) {
58851
59137
  set_class(div_8, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(isPlacingColumn) ? "bg-blue-100" : ""}`);
58852
59138
  set_class(button_7, 1, `flex-1 flex items-center gap-2 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(isPlacingColumn) ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
58853
59139
  set_class(div_9, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(isPlacingColumn) ? "bg-blue-100" : ""}`);
58854
- set_class(button_8, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "text" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
58855
- set_class(div_10, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "text" ? "bg-blue-100" : ""}`);
58856
- set_class(button_9, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "annotate" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
58857
- set_class(div_11, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "annotate" ? "bg-blue-100" : ""}`);
58858
- set_class(button_10, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "measure" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
58859
- set_class(div_12, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "measure" ? "bg-blue-100" : ""}`);
58860
- set_text(text_1, get(constructionOpen) ? "▼" : "▶");
59140
+ set_class(button_8, 1, `flex flex-col items-center gap-1 p-2 rounded-lg border-2 text-xs transition-colors ${get(currentTool) === "zone" && get(currentZoneShape) === "rectangle" ? "border-orange-400 bg-orange-50" : "border-gray-100 hover:border-gray-200"}`);
59141
+ set_class(button_9, 1, `flex flex-col items-center gap-1 p-2 rounded-lg border-2 text-xs transition-colors ${get(currentTool) === "zone" && get(currentZoneShape) === "triangle" ? "border-orange-400 bg-orange-50" : "border-gray-100 hover:border-gray-200"}`);
59142
+ set_class(button_10, 1, `flex flex-col items-center gap-1 p-2 rounded-lg border-2 text-xs transition-colors ${get(currentTool) === "zone" && get(currentZoneShape) === "polygon" ? "border-orange-400 bg-orange-50" : "border-gray-100 hover:border-gray-200"}`);
59143
+ set_class(button_11, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "text" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
59144
+ set_class(div_11, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "text" ? "bg-blue-100" : ""}`);
59145
+ set_class(button_12, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "annotate" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
59146
+ set_class(div_12, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "annotate" ? "bg-blue-100" : ""}`);
59147
+ set_class(button_13, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "measure" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
59148
+ set_class(div_13, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "measure" ? "bg-blue-100" : ""}`);
59149
+ set_text(text_4, get(constructionOpen) ? "▼" : "▶");
58861
59150
  });
58862
59151
  delegated("click", button_3, () => setTool("select"));
58863
59152
  delegated("click", button_4, () => setTool("wall"));
58864
59153
  delegated("click", button_5, onPlaceStair);
58865
59154
  delegated("click", button_6, () => onPlaceColumn("round"));
58866
59155
  delegated("click", button_7, () => onPlaceColumn("square"));
58867
- delegated("click", button_8, () => setTool("text"));
58868
- delegated("click", button_9, () => setTool("annotate"));
58869
- delegated("click", button_10, () => setTool("measure"));
58870
- delegated("click", button_11, onImportImage);
58871
- delegated("click", button_12, onImportRoomPlan);
58872
- delegated("click", button_13, () => set(constructionOpen, !get(constructionOpen)));
59156
+ delegated("click", button_8, () => setZoneTool("rectangle"));
59157
+ delegated("click", button_9, () => setZoneTool("triangle"));
59158
+ delegated("click", button_10, () => setZoneTool("polygon"));
59159
+ delegated("click", button_11, () => setTool("text"));
59160
+ delegated("click", button_12, () => setTool("annotate"));
59161
+ delegated("click", button_13, () => setTool("measure"));
59162
+ delegated("click", button_14, onImportImage);
59163
+ delegated("click", button_15, onImportRoomPlan);
59164
+ delegated("click", button_16, () => set(constructionOpen, !get(constructionOpen)));
58873
59165
  append($$anchor, div_3);
58874
59166
  };
58875
- var consequent_8 = ($$anchor) => {
58876
- var div_16 = root_5$4();
58877
- var div_17 = sibling(child(div_16), 4);
58878
- each(div_17, 21, () => roomPresets, index$1, ($$anchor, preset) => {
58879
- var button_16 = root_6$3();
58880
- var div_18 = child(button_16);
58881
- var text_6 = child(div_18, true);
58882
- reset(div_18);
58883
- var span_5 = sibling(div_18, 2);
58884
- var text_7 = child(span_5, true);
59167
+ var consequent_11 = ($$anchor) => {
59168
+ var div_17 = root_8$2();
59169
+ var div_18 = sibling(child(div_17), 4);
59170
+ each(div_18, 21, () => roomPresets, index$1, ($$anchor, preset) => {
59171
+ var button_19 = root_9$2();
59172
+ var div_19 = child(button_19);
59173
+ var text_9 = child(div_19, true);
59174
+ reset(div_19);
59175
+ var span_5 = sibling(div_19, 2);
59176
+ var text_10 = child(span_5, true);
58885
59177
  reset(span_5);
58886
- reset(button_16);
59178
+ reset(button_19);
58887
59179
  template_effect(() => {
58888
- set_text(text_6, get(preset).icon);
58889
- set_text(text_7, get(preset).name);
59180
+ set_text(text_9, get(preset).icon);
59181
+ set_text(text_10, get(preset).name);
58890
59182
  });
58891
- delegated("click", button_16, () => onPresetClick(get(preset).id));
58892
- event("dragstart", button_16, (e) => {
59183
+ delegated("click", button_19, () => onPresetClick(get(preset).id));
59184
+ event("dragstart", button_19, (e) => {
58893
59185
  var _e$dataTransfer5, _e$dataTransfer6;
58894
59186
  (_e$dataTransfer5 = e.dataTransfer) === null || _e$dataTransfer5 === void 0 || _e$dataTransfer5.setData("application/o3d-type", "room");
58895
59187
  (_e$dataTransfer6 = e.dataTransfer) === null || _e$dataTransfer6 === void 0 || _e$dataTransfer6.setData("application/o3d-id", get(preset).id);
58896
59188
  });
58897
- append($$anchor, button_16);
59189
+ append($$anchor, button_19);
58898
59190
  });
58899
- reset(div_17);
58900
- var div_19 = sibling(div_17, 8);
58901
- each(div_19, 21, () => roomTemplates, index$1, ($$anchor, tmpl) => {
58902
- var button_17 = root_7$4();
58903
- var div_20 = child(button_17);
58904
- var node_2 = child(div_20);
58905
- var consequent_2 = ($$anchor) => {
59191
+ reset(div_18);
59192
+ var div_20 = sibling(div_18, 8);
59193
+ each(div_20, 21, () => roomTemplates, index$1, ($$anchor, tmpl) => {
59194
+ var button_20 = root_10$2();
59195
+ var div_21 = child(button_20);
59196
+ var node_3 = child(div_21);
59197
+ var consequent_5 = ($$anchor) => {
58906
59198
  append($$anchor, text$1("🛋️"));
58907
59199
  };
58908
- var consequent_3 = ($$anchor) => {
59200
+ var consequent_6 = ($$anchor) => {
58909
59201
  append($$anchor, text$1("🛏️"));
58910
59202
  };
58911
- var consequent_4 = ($$anchor) => {
59203
+ var consequent_7 = ($$anchor) => {
58912
59204
  append($$anchor, text$1("🍳"));
58913
59205
  };
58914
- var consequent_5 = ($$anchor) => {
59206
+ var consequent_8 = ($$anchor) => {
58915
59207
  append($$anchor, text$1("🛁"));
58916
59208
  };
58917
- var consequent_6 = ($$anchor) => {
59209
+ var consequent_9 = ($$anchor) => {
58918
59210
  append($$anchor, text$1("🖥️"));
58919
59211
  };
58920
- var consequent_7 = ($$anchor) => {
59212
+ var consequent_10 = ($$anchor) => {
58921
59213
  append($$anchor, text$1("🍽️"));
58922
59214
  };
58923
59215
  var alternate = ($$anchor) => {
58924
59216
  append($$anchor, text$1("🏠"));
58925
59217
  };
58926
- if_block(node_2, ($$render) => {
58927
- if (get(tmpl).name === "Living Room") $$render(consequent_2);
58928
- else if (get(tmpl).name === "Bedroom") $$render(consequent_3, 1);
58929
- else if (get(tmpl).name === "Kitchen") $$render(consequent_4, 2);
58930
- else if (get(tmpl).name === "Bathroom") $$render(consequent_5, 3);
58931
- else if (get(tmpl).name === "Office") $$render(consequent_6, 4);
58932
- else if (get(tmpl).name === "Dining Room") $$render(consequent_7, 5);
59218
+ if_block(node_3, ($$render) => {
59219
+ if (get(tmpl).name === "Living Room") $$render(consequent_5);
59220
+ else if (get(tmpl).name === "Bedroom") $$render(consequent_6, 1);
59221
+ else if (get(tmpl).name === "Kitchen") $$render(consequent_7, 2);
59222
+ else if (get(tmpl).name === "Bathroom") $$render(consequent_8, 3);
59223
+ else if (get(tmpl).name === "Office") $$render(consequent_9, 4);
59224
+ else if (get(tmpl).name === "Dining Room") $$render(consequent_10, 5);
58933
59225
  else $$render(alternate, -1);
58934
59226
  });
58935
- reset(div_20);
58936
- var span_6 = sibling(div_20, 2);
58937
- var text_15 = child(span_6, true);
59227
+ reset(div_21);
59228
+ var span_6 = sibling(div_21, 2);
59229
+ var text_18 = child(span_6, true);
58938
59230
  reset(span_6);
58939
59231
  var span_7 = sibling(span_6, 2);
58940
- var text_16 = child(span_7);
59232
+ var text_19 = child(span_7);
58941
59233
  reset(span_7);
58942
- reset(button_17);
59234
+ reset(button_20);
58943
59235
  template_effect(() => {
58944
59236
  var _$$get$furniture$leng;
58945
- set_text(text_15, get(tmpl).name);
58946
- set_text(text_16, `${(_$$get$furniture$leng = get(tmpl).furniture.length) !== null && _$$get$furniture$leng !== void 0 ? _$$get$furniture$leng : ""} items`);
59237
+ set_text(text_18, get(tmpl).name);
59238
+ set_text(text_19, `${(_$$get$furniture$leng = get(tmpl).furniture.length) !== null && _$$get$furniture$leng !== void 0 ? _$$get$furniture$leng : ""} items`);
58947
59239
  });
58948
- delegated("click", button_17, () => onPresetClick(get(tmpl).presetId, get(tmpl).name));
58949
- event("dragstart", button_17, (e) => {
59240
+ delegated("click", button_20, () => onPresetClick(get(tmpl).presetId, get(tmpl).name));
59241
+ event("dragstart", button_20, (e) => {
58950
59242
  var _e$dataTransfer7, _e$dataTransfer8;
58951
59243
  (_e$dataTransfer7 = e.dataTransfer) === null || _e$dataTransfer7 === void 0 || _e$dataTransfer7.setData("application/o3d-type", "room-template");
58952
59244
  (_e$dataTransfer8 = e.dataTransfer) === null || _e$dataTransfer8 === void 0 || _e$dataTransfer8.setData("application/o3d-id", get(tmpl).name);
58953
59245
  });
58954
- append($$anchor, button_17);
59246
+ append($$anchor, button_20);
58955
59247
  });
58956
- reset(div_19);
58957
- reset(div_16);
58958
- append($$anchor, div_16);
59248
+ reset(div_20);
59249
+ reset(div_17);
59250
+ append($$anchor, div_17);
58959
59251
  };
58960
- var consequent_13 = ($$anchor) => {
58961
- var div_21 = root_15$2();
58962
- var div_22 = child(div_21);
58963
- var input_1 = child(div_22);
59252
+ var consequent_16 = ($$anchor) => {
59253
+ var div_22 = root_18$2();
59254
+ var div_23 = child(div_22);
59255
+ var input_1 = child(div_23);
58964
59256
  remove_input_defaults(input_1);
58965
- var node_3 = sibling(input_1, 2);
58966
- var consequent_9 = ($$anchor) => {
58967
- var button_18 = root_16$1();
58968
- delegated("click", button_18, () => set(search, ""));
58969
- append($$anchor, button_18);
59257
+ var node_4 = sibling(input_1, 2);
59258
+ var consequent_12 = ($$anchor) => {
59259
+ var button_21 = root_19$2();
59260
+ delegated("click", button_21, () => set(search, ""));
59261
+ append($$anchor, button_21);
58970
59262
  };
58971
- if_block(node_3, ($$render) => {
58972
- if (get(search)) $$render(consequent_9);
59263
+ if_block(node_4, ($$render) => {
59264
+ if (get(search)) $$render(consequent_12);
58973
59265
  });
58974
- reset(div_22);
58975
- var node_4 = sibling(div_22, 2);
58976
- var consequent_10 = ($$anchor) => {
58977
- var div_23 = root_17$2();
58978
- var text_17 = child(div_23);
58979
- reset(div_23);
59266
+ reset(div_23);
59267
+ var node_5 = sibling(div_23, 2);
59268
+ var consequent_13 = ($$anchor) => {
59269
+ var div_24 = root_20$2();
59270
+ var text_20 = child(div_24);
59271
+ reset(div_24);
58980
59272
  template_effect(() => {
58981
59273
  var _$$get$length, _$$get;
58982
- return set_text(text_17, `${(_$$get$length = get(filtered).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} result${get(filtered).length !== 1 ? "s" : ""} for "${(_$$get = get(search)) !== null && _$$get !== void 0 ? _$$get : ""}"`);
59274
+ return set_text(text_20, `${(_$$get$length = get(filtered).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} result${get(filtered).length !== 1 ? "s" : ""} for "${(_$$get = get(search)) !== null && _$$get !== void 0 ? _$$get : ""}"`);
58983
59275
  });
58984
- append($$anchor, div_23);
59276
+ append($$anchor, div_24);
58985
59277
  };
58986
- if_block(node_4, ($$render) => {
58987
- if (get(search)) $$render(consequent_10);
59278
+ if_block(node_5, ($$render) => {
59279
+ if (get(search)) $$render(consequent_13);
58988
59280
  });
58989
- var div_24 = sibling(node_4, 2);
58990
- var button_19 = child(div_24);
58991
- var button_20 = sibling(button_19, 2);
58992
- var text_18 = child(button_20);
58993
- reset(button_20);
58994
- each(sibling(button_20, 2), 17, () => furnitureCategories, index$1, ($$anchor, cat) => {
58995
- var button_21 = root_18$2();
58996
- var text_19 = child(button_21, true);
58997
- reset(button_21);
59281
+ var div_25 = sibling(node_5, 2);
59282
+ var button_22 = child(div_25);
59283
+ var button_23 = sibling(button_22, 2);
59284
+ var text_21 = child(button_23);
59285
+ reset(button_23);
59286
+ each(sibling(button_23, 2), 17, () => furnitureCategories, index$1, ($$anchor, cat) => {
59287
+ var button_24 = root_21$1();
59288
+ var text_22 = child(button_24, true);
59289
+ reset(button_24);
58998
59290
  template_effect(() => {
58999
59291
  var _categoryColors$$$get;
59000
- set_class(button_21, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === get(cat) ? "text-white" : "text-gray-600 hover:bg-gray-200"}`);
59001
- set_style(button_21, get(selectedCategory) === get(cat) ? `background-color: ${(_categoryColors$$$get = categoryColors[get(cat)]) !== null && _categoryColors$$$get !== void 0 ? _categoryColors$$$get : "#6b7280"}` : "background-color: #f3f4f6");
59002
- set_text(text_19, get(cat));
59292
+ set_class(button_24, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === get(cat) ? "text-white" : "text-gray-600 hover:bg-gray-200"}`);
59293
+ set_style(button_24, get(selectedCategory) === get(cat) ? `background-color: ${(_categoryColors$$$get = categoryColors[get(cat)]) !== null && _categoryColors$$$get !== void 0 ? _categoryColors$$$get : "#6b7280"}` : "background-color: #f3f4f6");
59294
+ set_text(text_22, get(cat));
59003
59295
  });
59004
- delegated("click", button_21, () => set(selectedCategory, get(cat), true));
59005
- append($$anchor, button_21);
59296
+ delegated("click", button_24, () => set(selectedCategory, get(cat), true));
59297
+ append($$anchor, button_24);
59006
59298
  });
59007
- reset(div_24);
59008
- var node_6 = sibling(div_24, 2);
59009
- var consequent_11 = ($$anchor) => {
59010
- var fragment_2 = root_19$2();
59011
- var div_25 = first_child(fragment_2);
59012
- var div_26 = sibling(child(div_25), 2);
59013
- each(div_26, 21, () => get(recentItems), index$1, ($$anchor, item) => {
59014
- var button_22 = root_20$2();
59015
- var span_8 = child(button_22);
59016
- var text_20 = child(span_8, true);
59299
+ reset(div_25);
59300
+ var node_7 = sibling(div_25, 2);
59301
+ var consequent_14 = ($$anchor) => {
59302
+ var fragment_2 = root_22$2();
59303
+ var div_26 = first_child(fragment_2);
59304
+ var div_27 = sibling(child(div_26), 2);
59305
+ each(div_27, 21, () => get(recentItems), index$1, ($$anchor, item) => {
59306
+ var button_25 = root_23$2();
59307
+ var span_8 = child(button_25);
59308
+ var text_23 = child(span_8, true);
59017
59309
  reset(span_8);
59018
- var div_27 = sibling(span_8, 2);
59019
- var div_28 = child(div_27);
59020
- reset(div_27);
59021
- var span_9 = sibling(div_27, 2);
59022
- var text_21 = child(span_9, true);
59310
+ var div_28 = sibling(span_8, 2);
59311
+ var div_29 = child(div_28);
59312
+ reset(div_28);
59313
+ var span_9 = sibling(div_28, 2);
59314
+ var text_24 = child(span_9, true);
59023
59315
  reset(span_9);
59024
- reset(button_22);
59316
+ reset(button_25);
59025
59317
  template_effect(($0, $1, $2) => {
59026
59318
  var _$$get$color, _$$get$color2;
59027
- set_class(button_22, 1, `relative flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentPlacing) === get(item).id ? "border-blue-400 bg-blue-50 ring-1 ring-blue-300" : "border-gray-100 hover:border-blue-300 hover:bg-blue-50"}`);
59319
+ set_class(button_25, 1, `relative flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentPlacing) === get(item).id ? "border-blue-400 bg-blue-50 ring-1 ring-blue-300" : "border-gray-100 hover:border-blue-300 hover:bg-blue-50"}`);
59028
59320
  set_class(span_8, 1, `absolute top-1 right-1 text-[12px] leading-none cursor-pointer ${$0 !== null && $0 !== void 0 ? $0 : ""}`);
59029
59321
  set_attribute(span_8, "title", $1);
59030
- set_text(text_20, $2);
59031
- set_style(div_27, `background-color: ${(_$$get$color = get(item).color) !== null && _$$get$color !== void 0 ? _$$get$color : ""}20`);
59032
- set_style(div_28, `background-color: ${(_$$get$color2 = get(item).color) !== null && _$$get$color2 !== void 0 ? _$$get$color2 : ""}; opacity: 0.7`);
59033
- set_text(text_21, get(item).name);
59322
+ set_text(text_23, $2);
59323
+ set_style(div_28, `background-color: ${(_$$get$color = get(item).color) !== null && _$$get$color !== void 0 ? _$$get$color : ""}20`);
59324
+ set_style(div_29, `background-color: ${(_$$get$color2 = get(item).color) !== null && _$$get$color2 !== void 0 ? _$$get$color2 : ""}; opacity: 0.7`);
59325
+ set_text(text_24, get(item).name);
59034
59326
  }, [
59035
59327
  () => get(favoriteIds).includes(get(item).id) ? "text-pink-500" : "text-gray-300 hover:text-pink-400",
59036
59328
  () => get(favoriteIds).includes(get(item).id) ? "Remove from favorites" : "Add to favorites",
59037
59329
  () => get(favoriteIds).includes(get(item).id) ? "♥" : "♡"
59038
59330
  ]);
59039
- delegated("click", button_22, () => onFurnitureClick(get(item)));
59040
- event("dragstart", button_22, (e) => {
59331
+ delegated("click", button_25, () => onFurnitureClick(get(item)));
59332
+ event("dragstart", button_25, (e) => {
59041
59333
  var _e$dataTransfer9, _e$dataTransfer10;
59042
59334
  (_e$dataTransfer9 = e.dataTransfer) === null || _e$dataTransfer9 === void 0 || _e$dataTransfer9.setData("application/o3d-type", "furniture");
59043
59335
  (_e$dataTransfer10 = e.dataTransfer) === null || _e$dataTransfer10 === void 0 || _e$dataTransfer10.setData("application/o3d-id", get(item).id);
59044
59336
  });
59045
- event("mouseenter", button_22, (e) => onItemMouseEnter(e, get(item)));
59046
- delegated("mousemove", button_22, onItemMouseMove);
59047
- event("mouseleave", button_22, onItemMouseLeave);
59337
+ event("mouseenter", button_25, (e) => onItemMouseEnter(e, get(item)));
59338
+ delegated("mousemove", button_25, onItemMouseMove);
59339
+ event("mouseleave", button_25, onItemMouseLeave);
59048
59340
  delegated("click", span_8, (e) => {
59049
59341
  e.stopPropagation();
59050
59342
  e.preventDefault();
@@ -59056,40 +59348,40 @@ function BuildPanel($$anchor, $$props) {
59056
59348
  toggleFavorite(get(item).id);
59057
59349
  }
59058
59350
  });
59059
- append($$anchor, button_22);
59351
+ append($$anchor, button_25);
59060
59352
  });
59353
+ reset(div_27);
59061
59354
  reset(div_26);
59062
- reset(div_25);
59063
59355
  next(2);
59064
59356
  append($$anchor, fragment_2);
59065
59357
  };
59066
- if_block(node_6, ($$render) => {
59067
- if (!get(search) && get(selectedCategory) === "All" && get(recentItems).length > 0) $$render(consequent_11);
59358
+ if_block(node_7, ($$render) => {
59359
+ if (!get(search) && get(selectedCategory) === "All" && get(recentItems).length > 0) $$render(consequent_14);
59068
59360
  });
59069
- var div_29 = sibling(node_6, 2);
59070
- each(div_29, 21, () => get(filtered), index$1, ($$anchor, item) => {
59361
+ var div_30 = sibling(node_7, 2);
59362
+ each(div_30, 21, () => get(filtered), index$1, ($$anchor, item) => {
59071
59363
  const s = /* @__PURE__ */ user_derived(() => get(search).toLowerCase());
59072
- var button_23 = root_21$1();
59073
- var span_10 = child(button_23);
59074
- var text_22 = child(span_10, true);
59364
+ var button_26 = root_24$1();
59365
+ var span_10 = child(button_26);
59366
+ var text_25 = child(span_10, true);
59075
59367
  reset(span_10);
59076
- var div_30 = sibling(span_10, 2);
59077
- var div_31 = child(div_30);
59078
- reset(div_30);
59079
- var node_7 = sibling(div_30, 2);
59080
- var consequent_12 = ($$anchor) => {
59368
+ var div_31 = sibling(span_10, 2);
59369
+ var div_32 = child(div_31);
59370
+ reset(div_31);
59371
+ var node_8 = sibling(div_31, 2);
59372
+ var consequent_15 = ($$anchor) => {
59081
59373
  const idx = /* @__PURE__ */ user_derived(() => get(item).name.toLowerCase().indexOf(get(s)));
59082
- var span_11 = root_22$2();
59083
- var text_23 = child(span_11, true);
59084
- var mark = sibling(text_23);
59085
- var text_24 = child(mark, true);
59374
+ var span_11 = root_25$1();
59375
+ var text_26 = child(span_11, true);
59376
+ var mark = sibling(text_26);
59377
+ var text_27 = child(mark, true);
59086
59378
  reset(mark);
59087
- var text_25 = sibling(mark, 1, true);
59379
+ var text_28 = sibling(mark, 1, true);
59088
59380
  reset(span_11);
59089
59381
  template_effect(($0, $1, $2) => {
59090
- set_text(text_23, $0);
59091
- set_text(text_24, $1);
59092
- set_text(text_25, $2);
59382
+ set_text(text_26, $0);
59383
+ set_text(text_27, $1);
59384
+ set_text(text_28, $2);
59093
59385
  }, [
59094
59386
  () => get(item).name.slice(0, get(idx)),
59095
59387
  () => get(item).name.slice(get(idx), get(idx) + get(s).length),
@@ -59099,43 +59391,43 @@ function BuildPanel($$anchor, $$props) {
59099
59391
  };
59100
59392
  var d = /* @__PURE__ */ user_derived(() => get(s) && get(item).name.toLowerCase().includes(get(s)));
59101
59393
  var alternate_1 = ($$anchor) => {
59102
- var span_12 = root_23$2();
59103
- var text_26 = child(span_12, true);
59394
+ var span_12 = root_26$1();
59395
+ var text_29 = child(span_12, true);
59104
59396
  reset(span_12);
59105
- template_effect(() => set_text(text_26, get(item).name));
59397
+ template_effect(() => set_text(text_29, get(item).name));
59106
59398
  append($$anchor, span_12);
59107
59399
  };
59108
- if_block(node_7, ($$render) => {
59109
- if (get(d)) $$render(consequent_12);
59400
+ if_block(node_8, ($$render) => {
59401
+ if (get(d)) $$render(consequent_15);
59110
59402
  else $$render(alternate_1, -1);
59111
59403
  });
59112
- var span_13 = sibling(node_7, 2);
59113
- var text_27 = child(span_13);
59404
+ var span_13 = sibling(node_8, 2);
59405
+ var text_30 = child(span_13);
59114
59406
  reset(span_13);
59115
- reset(button_23);
59407
+ reset(button_26);
59116
59408
  template_effect(($0, $1, $2) => {
59117
59409
  var _$$get$color3, _$$get$color4, _$$get$width, _$$get$depth;
59118
- set_class(button_23, 1, `relative flex flex-col items-center gap-1 p-3 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentPlacing) === get(item).id ? "border-blue-400 bg-blue-50 ring-1 ring-blue-300" : "border-gray-100 hover:border-blue-300 hover:bg-blue-50"}`);
59410
+ set_class(button_26, 1, `relative flex flex-col items-center gap-1 p-3 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentPlacing) === get(item).id ? "border-blue-400 bg-blue-50 ring-1 ring-blue-300" : "border-gray-100 hover:border-blue-300 hover:bg-blue-50"}`);
59119
59411
  set_class(span_10, 1, `absolute top-1 right-1 text-[12px] leading-none cursor-pointer ${$0 !== null && $0 !== void 0 ? $0 : ""}`);
59120
59412
  set_attribute(span_10, "title", $1);
59121
- set_text(text_22, $2);
59122
- set_style(div_30, `background-color: ${(_$$get$color3 = get(item).color) !== null && _$$get$color3 !== void 0 ? _$$get$color3 : ""}20`);
59123
- set_style(div_31, `background-color: ${(_$$get$color4 = get(item).color) !== null && _$$get$color4 !== void 0 ? _$$get$color4 : ""}; opacity: 0.7`);
59124
- set_text(text_27, `${(_$$get$width = get(item).width) !== null && _$$get$width !== void 0 ? _$$get$width : ""}×${(_$$get$depth = get(item).depth) !== null && _$$get$depth !== void 0 ? _$$get$depth : ""}cm`);
59413
+ set_text(text_25, $2);
59414
+ set_style(div_31, `background-color: ${(_$$get$color3 = get(item).color) !== null && _$$get$color3 !== void 0 ? _$$get$color3 : ""}20`);
59415
+ set_style(div_32, `background-color: ${(_$$get$color4 = get(item).color) !== null && _$$get$color4 !== void 0 ? _$$get$color4 : ""}; opacity: 0.7`);
59416
+ set_text(text_30, `${(_$$get$width = get(item).width) !== null && _$$get$width !== void 0 ? _$$get$width : ""}×${(_$$get$depth = get(item).depth) !== null && _$$get$depth !== void 0 ? _$$get$depth : ""}cm`);
59125
59417
  }, [
59126
59418
  () => get(favoriteIds).includes(get(item).id) ? "text-pink-500" : "text-gray-300 hover:text-pink-400",
59127
59419
  () => get(favoriteIds).includes(get(item).id) ? "Remove from favorites" : "Add to favorites",
59128
59420
  () => get(favoriteIds).includes(get(item).id) ? "♥" : "♡"
59129
59421
  ]);
59130
- delegated("click", button_23, () => onFurnitureClick(get(item)));
59131
- event("dragstart", button_23, (e) => {
59422
+ delegated("click", button_26, () => onFurnitureClick(get(item)));
59423
+ event("dragstart", button_26, (e) => {
59132
59424
  var _e$dataTransfer11, _e$dataTransfer12;
59133
59425
  (_e$dataTransfer11 = e.dataTransfer) === null || _e$dataTransfer11 === void 0 || _e$dataTransfer11.setData("application/o3d-type", "furniture");
59134
59426
  (_e$dataTransfer12 = e.dataTransfer) === null || _e$dataTransfer12 === void 0 || _e$dataTransfer12.setData("application/o3d-id", get(item).id);
59135
59427
  });
59136
- event("mouseenter", button_23, (e) => onItemMouseEnter(e, get(item)));
59137
- delegated("mousemove", button_23, onItemMouseMove);
59138
- event("mouseleave", button_23, onItemMouseLeave);
59428
+ event("mouseenter", button_26, (e) => onItemMouseEnter(e, get(item)));
59429
+ delegated("mousemove", button_26, onItemMouseMove);
59430
+ event("mouseleave", button_26, onItemMouseLeave);
59139
59431
  delegated("click", span_10, (e) => {
59140
59432
  e.stopPropagation();
59141
59433
  e.preventDefault();
@@ -59147,81 +59439,81 @@ function BuildPanel($$anchor, $$props) {
59147
59439
  toggleFavorite(get(item).id);
59148
59440
  }
59149
59441
  });
59150
- append($$anchor, button_23);
59442
+ append($$anchor, button_26);
59151
59443
  });
59152
- reset(div_29);
59153
- reset(div_21);
59444
+ reset(div_30);
59445
+ reset(div_22);
59154
59446
  template_effect(() => {
59155
- set_class(button_19, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === "All" ? "bg-blue-600 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`);
59156
- set_class(button_20, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === "Favorites" ? "bg-pink-500 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`);
59157
- set_text(text_18, `♥ Favorites${get(favoriteIds).length ? ` (${get(favoriteIds).length})` : ""}`);
59447
+ set_class(button_22, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === "All" ? "bg-blue-600 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`);
59448
+ set_class(button_23, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === "Favorites" ? "bg-pink-500 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`);
59449
+ set_text(text_21, `♥ Favorites${get(favoriteIds).length ? ` (${get(favoriteIds).length})` : ""}`);
59158
59450
  });
59159
59451
  bind_value(input_1, () => get(search), ($$value) => set(search, $$value));
59160
- delegated("click", button_19, () => set(selectedCategory, "All"));
59161
- delegated("click", button_20, () => set(selectedCategory, "Favorites"));
59162
- append($$anchor, div_21);
59452
+ delegated("click", button_22, () => set(selectedCategory, "All"));
59453
+ delegated("click", button_23, () => set(selectedCategory, "Favorites"));
59454
+ append($$anchor, div_22);
59163
59455
  };
59164
59456
  if_block(node, ($$render) => {
59165
- if (get(activeTab) === "draw") $$render(consequent_1);
59166
- else if (get(activeTab) === "rooms") $$render(consequent_8, 1);
59167
- else if (get(activeTab) === "objects") $$render(consequent_13, 2);
59457
+ if (get(activeTab) === "draw") $$render(consequent_4);
59458
+ else if (get(activeTab) === "rooms") $$render(consequent_11, 1);
59459
+ else if (get(activeTab) === "objects") $$render(consequent_16, 2);
59168
59460
  });
59169
59461
  reset(div_2);
59170
- var button_24 = sibling(div_2, 2);
59462
+ var button_27 = sibling(div_2, 2);
59171
59463
  let classes;
59172
- var button_25 = sibling(button_24, 2);
59464
+ var button_28 = sibling(button_27, 2);
59173
59465
  let classes_1;
59174
- var button_26 = sibling(button_25, 2);
59466
+ var button_29 = sibling(button_28, 2);
59175
59467
  reset(div);
59176
- var node_8 = sibling(div, 2);
59177
- var consequent_14 = ($$anchor) => {
59468
+ var node_9 = sibling(div, 2);
59469
+ var consequent_17 = ($$anchor) => {
59178
59470
  const item = /* @__PURE__ */ user_derived(() => get(hoveredItem));
59179
- var div_32 = root_24$2();
59180
- var div_33 = child(div_32);
59471
+ var div_33 = root_27$1();
59181
59472
  var div_34 = child(div_33);
59182
59473
  var div_35 = child(div_34);
59183
59474
  var div_36 = child(div_35);
59475
+ var div_37 = child(div_36);
59476
+ reset(div_36);
59184
59477
  reset(div_35);
59185
- reset(div_34);
59186
- var div_37 = sibling(div_34, 2);
59187
- var div_38 = child(div_37);
59188
- var span_14 = child(div_38);
59189
- var text_28 = child(span_14, true);
59478
+ var div_38 = sibling(div_35, 2);
59479
+ var div_39 = child(div_38);
59480
+ var span_14 = child(div_39);
59481
+ var text_31 = child(span_14, true);
59190
59482
  reset(span_14);
59191
59483
  var span_15 = sibling(span_14, 2);
59192
- var text_29 = child(span_15, true);
59484
+ var text_32 = child(span_15, true);
59193
59485
  reset(span_15);
59194
- reset(div_38);
59195
- var div_39 = sibling(div_38, 2);
59196
- var text_30 = child(div_39);
59197
59486
  reset(div_39);
59198
- reset(div_37);
59487
+ var div_40 = sibling(div_39, 2);
59488
+ var text_33 = child(div_40);
59489
+ reset(div_40);
59490
+ reset(div_38);
59491
+ reset(div_34);
59199
59492
  reset(div_33);
59200
- reset(div_32);
59201
59493
  template_effect(() => {
59202
59494
  var _$$get$x, _$$get$y, _$$get$color5, _$$get$color6, _ref, _categoryColors$$$get2, _$$get$width2, _$$get$depth2, _$$get$height;
59203
- set_style(div_32, `left: ${(_$$get$x = get(hoverPos).x) !== null && _$$get$x !== void 0 ? _$$get$x : ""}px; top: ${(_$$get$y = get(hoverPos).y) !== null && _$$get$y !== void 0 ? _$$get$y : ""}px;`);
59204
- set_style(div_35, `background-color: ${(_$$get$color5 = get(item).color) !== null && _$$get$color5 !== void 0 ? _$$get$color5 : ""}20`);
59205
- set_style(div_36, `background-color: ${(_$$get$color6 = get(item).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : ""}; opacity: 0.7`);
59206
- set_text(text_28, get(item).name);
59495
+ set_style(div_33, `left: ${(_$$get$x = get(hoverPos).x) !== null && _$$get$x !== void 0 ? _$$get$x : ""}px; top: ${(_$$get$y = get(hoverPos).y) !== null && _$$get$y !== void 0 ? _$$get$y : ""}px;`);
59496
+ set_style(div_36, `background-color: ${(_$$get$color5 = get(item).color) !== null && _$$get$color5 !== void 0 ? _$$get$color5 : ""}20`);
59497
+ set_style(div_37, `background-color: ${(_$$get$color6 = get(item).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : ""}; opacity: 0.7`);
59498
+ set_text(text_31, get(item).name);
59207
59499
  set_style(span_15, `background-color: ${(_ref = (_categoryColors$$$get2 = categoryColors[get(item).category]) !== null && _categoryColors$$$get2 !== void 0 ? _categoryColors$$$get2 : "#6b7280") !== null && _ref !== void 0 ? _ref : ""}`);
59208
- set_text(text_29, get(item).category);
59209
- set_text(text_30, `${(_$$get$width2 = get(item).width) !== null && _$$get$width2 !== void 0 ? _$$get$width2 : ""} × ${(_$$get$depth2 = get(item).depth) !== null && _$$get$depth2 !== void 0 ? _$$get$depth2 : ""} × ${(_$$get$height = get(item).height) !== null && _$$get$height !== void 0 ? _$$get$height : ""} cm`);
59500
+ set_text(text_32, get(item).category);
59501
+ set_text(text_33, `${(_$$get$width2 = get(item).width) !== null && _$$get$width2 !== void 0 ? _$$get$width2 : ""} × ${(_$$get$depth2 = get(item).depth) !== null && _$$get$depth2 !== void 0 ? _$$get$depth2 : ""} × ${(_$$get$height = get(item).height) !== null && _$$get$height !== void 0 ? _$$get$height : ""} cm`);
59210
59502
  });
59211
- append($$anchor, div_32);
59503
+ append($$anchor, div_33);
59212
59504
  };
59213
- if_block(node_8, ($$render) => {
59214
- if (get(showPreview) && get(hoveredItem)) $$render(consequent_14);
59505
+ if_block(node_9, ($$render) => {
59506
+ if (get(showPreview) && get(hoveredItem)) $$render(consequent_17);
59215
59507
  });
59216
- var node_9 = sibling(node_8, 2);
59217
- var consequent_15 = ($$anchor) => {
59218
- var div_40 = root_25$1();
59219
- var div_41 = child(div_40);
59220
- var p_1 = sibling(child(div_41), 2);
59221
- var text_31 = child(p_1, true);
59222
- reset(p_1);
59223
- var div_42 = sibling(p_1, 2);
59224
- var label = child(div_42);
59508
+ var node_10 = sibling(node_9, 2);
59509
+ var consequent_18 = ($$anchor) => {
59510
+ var div_41 = root_28$1();
59511
+ var div_42 = child(div_41);
59512
+ var p_2 = sibling(child(div_42), 2);
59513
+ var text_34 = child(p_2, true);
59514
+ reset(p_2);
59515
+ var div_43 = sibling(p_2, 2);
59516
+ var label = child(div_43);
59225
59517
  var input_2 = child(label);
59226
59518
  remove_input_defaults(input_2);
59227
59519
  next(2);
@@ -59229,53 +59521,53 @@ function BuildPanel($$anchor, $$props) {
59229
59521
  var label_1 = sibling(label, 2);
59230
59522
  var input_3 = child(label_1);
59231
59523
  remove_input_defaults(input_3);
59232
- var div_43 = sibling(input_3, 2);
59233
- var div_44 = child(div_43);
59234
- var span_16 = sibling(child(div_44));
59235
- var text_32 = child(span_16, true);
59524
+ var div_44 = sibling(input_3, 2);
59525
+ var div_45 = child(div_44);
59526
+ var span_16 = sibling(child(div_45));
59527
+ var text_35 = child(span_16, true);
59236
59528
  reset(span_16);
59237
- reset(div_44);
59529
+ reset(div_45);
59238
59530
  next(2);
59239
- reset(div_43);
59531
+ reset(div_44);
59240
59532
  reset(label_1);
59241
59533
  var label_2 = sibling(label_1, 2);
59242
59534
  var input_4 = sibling(child(label_2), 2);
59243
59535
  remove_input_defaults(input_4);
59244
59536
  reset(label_2);
59537
+ reset(div_43);
59538
+ var div_46 = sibling(div_43, 2);
59539
+ var button_30 = child(div_46);
59540
+ var button_31 = sibling(button_30, 2);
59541
+ reset(div_46);
59245
59542
  reset(div_42);
59246
- var div_45 = sibling(div_42, 2);
59247
- var button_27 = child(div_45);
59248
- var button_28 = sibling(button_27, 2);
59249
- reset(div_45);
59250
59543
  reset(div_41);
59251
- reset(div_40);
59252
59544
  template_effect(() => {
59253
- set_text(text_31, get(importFileName));
59254
- set_text(text_32, "v5");
59545
+ set_text(text_34, get(importFileName));
59546
+ set_text(text_35, "v5");
59255
59547
  });
59256
- delegated("click", div_40, cancelImport);
59257
- delegated("click", div_41, (e) => e.stopPropagation());
59548
+ delegated("click", div_41, cancelImport);
59549
+ delegated("click", div_42, (e) => e.stopPropagation());
59258
59550
  bind_checked(input_2, () => get(optStraighten), ($$value) => set(optStraighten, $$value));
59259
59551
  bind_checked(input_3, () => get(optOrthogonal), ($$value) => set(optOrthogonal, $$value));
59260
59552
  bind_value(input_4, () => get(optMergeDistance), ($$value) => set(optMergeDistance, $$value));
59261
- delegated("click", button_27, cancelImport);
59262
- delegated("click", button_28, confirmImport);
59263
- append($$anchor, div_40);
59553
+ delegated("click", button_30, cancelImport);
59554
+ delegated("click", button_31, confirmImport);
59555
+ append($$anchor, div_41);
59264
59556
  };
59265
- if_block(node_9, ($$render) => {
59266
- if (get(showImportDialog)) $$render(consequent_15);
59557
+ if_block(node_10, ($$render) => {
59558
+ if (get(showImportDialog)) $$render(consequent_18);
59267
59559
  });
59268
59560
  template_effect(() => {
59269
59561
  set_class(button, 1, `flex-1 py-2.5 text-xs font-semibold uppercase tracking-wide ${get(activeTab) === "draw" ? "text-slate-800 border-b-2 border-blue-500 bg-blue-50" : "text-gray-500 hover:text-gray-700"}`);
59270
59562
  set_class(button_1, 1, `flex-1 py-2.5 text-xs font-semibold uppercase tracking-wide ${get(activeTab) === "rooms" ? "text-slate-800 border-b-2 border-blue-500 bg-blue-50" : "text-gray-500 hover:text-gray-700"}`);
59271
59563
  set_class(button_2, 1, `flex-1 py-2.5 text-xs font-semibold uppercase tracking-wide ${get(activeTab) === "objects" ? "text-slate-800 border-b-2 border-blue-500 bg-blue-50" : "text-gray-500 hover:text-gray-700"}`);
59272
- classes = set_class(button_24, 1, "absolute bottom-4 left-14 w-8 h-8 rounded-full shadow-lg hover:bg-slate-600 transition-colors z-50 text-sm", null, classes, {
59564
+ classes = set_class(button_27, 1, "absolute bottom-4 left-14 w-8 h-8 rounded-full shadow-lg hover:bg-slate-600 transition-colors z-50 text-sm", null, classes, {
59273
59565
  "bg-blue-600": showLayers(),
59274
59566
  "text-white": showLayers(),
59275
59567
  "bg-slate-700": !showLayers(),
59276
59568
  "text-gray-300": !showLayers()
59277
59569
  });
59278
- classes_1 = set_class(button_25, 1, "absolute bottom-4 left-24 w-8 h-8 rounded-full shadow-lg hover:bg-slate-600 transition-colors z-50 text-sm", null, classes_1, {
59570
+ classes_1 = set_class(button_28, 1, "absolute bottom-4 left-24 w-8 h-8 rounded-full shadow-lg hover:bg-slate-600 transition-colors z-50 text-sm", null, classes_1, {
59279
59571
  "bg-blue-600": showUndoHistory(),
59280
59572
  "text-white": showUndoHistory(),
59281
59573
  "bg-slate-700": !showUndoHistory(),
@@ -59285,9 +59577,9 @@ function BuildPanel($$anchor, $$props) {
59285
59577
  delegated("click", button, () => set(activeTab, "draw"));
59286
59578
  delegated("click", button_1, () => set(activeTab, "rooms"));
59287
59579
  delegated("click", button_2, () => set(activeTab, "objects"));
59288
- delegated("click", button_24, () => showLayers(!showLayers()));
59289
- delegated("click", button_25, () => showUndoHistory(!showUndoHistory()));
59290
- delegated("click", button_26, () => showHelp(!showHelp()));
59580
+ delegated("click", button_27, () => showLayers(!showLayers()));
59581
+ delegated("click", button_28, () => showUndoHistory(!showUndoHistory()));
59582
+ delegated("click", button_29, () => showHelp(!showHelp()));
59291
59583
  append($$anchor, fragment);
59292
59584
  pop();
59293
59585
  }
@@ -59660,20 +59952,22 @@ var root_13$1 = /* @__PURE__ */ from_html(`<option> </option>`);
59660
59952
  var root_12$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Camera</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm bg-white"><option>Select camera...</option><!></select></label>`);
59661
59953
  var root_14$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500"> </span> <input type="text"/></label>`);
59662
59954
  var root_11$1 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
59663
- var root_15$1 = /* @__PURE__ */ from_html(`<button></button>`);
59955
+ var root_15 = /* @__PURE__ */ from_html(`<button></button>`);
59664
59956
  var root_10$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-purple-100 rounded flex items-center justify-center text-xs"> </span> <button> </button></h3> <div class="space-y-3"><!> <div><div class="flex items-center gap-1 mb-2"><span class="text-xs text-gray-500">Color</span> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-gray-400"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="9" cy="9" r="2"></circle><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path></svg></div> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="1" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="1" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="1" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Material</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Wood</option><option>Metal</option><option>Fabric</option><option>Leather</option><option>Glass</option><option>Plastic</option><option>Stone</option><option>Ceramic</option></select></label> <label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="flex gap-1"><button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Rotate 90° left">↺ 90°</button> <button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Rotate 90° right">↻ 90°</button></div> <div class="flex gap-1"><button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Flip horizontally">↔ Flip H</button> <button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Flip vertically">↕ Flip V</button></div> <button class="w-full px-2 py-1.5 border border-gray-300 rounded text-sm text-gray-600 hover:bg-gray-50 transition-colors">Reset to defaults</button></div>`, 1);
59665
59957
  var root_17$1 = /* @__PURE__ */ from_html(`<label class="block pb-3 border-b border-gray-200"><span class="text-xs text-gray-500"> </span> <input type="range" min="0.05" max="1" step="0.05" class="w-full"/></label>`);
59666
59958
  var root_18$1 = /* @__PURE__ */ from_html(`<option> </option>`);
59667
59959
  var root_19$1 = /* @__PURE__ */ from_html(`<button></button>`);
59668
59960
  var root_22$1 = /* @__PURE__ */ from_html(`<button><div class="w-full h-12 rounded-md mb-1 overflow-hidden"></div> <div class="text-center leading-3 text-[10px] text-gray-600 truncate"> </div></button>`);
59669
59961
  var root_20$1 = /* @__PURE__ */ from_html(`<div><span class="text-xs font-medium text-gray-600 mb-1.5 block"> </span> <div class="grid grid-cols-3 gap-1.5"></div></div>`);
59670
- var root_16 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-green-100 rounded flex items-center justify-center text-xs">⬜</span> Room Properties</h3> <div class="space-y-3"><!> <label class="block"><span class="text-xs text-gray-500">Room Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"></select></label> <label class="block"><span class="text-xs text-gray-500">Room Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Category</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>🏠 Indoor</option><option>🌳 Outdoor</option><option>🚗 Garage</option><option>🔧 Utility</option></select></label> <div><span class="text-xs text-gray-500">Area</span> <p class="text-sm text-gray-700"> </p></div> <div><span class="text-xs text-gray-500 mb-1.5 block">Room Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <div><div class="flex items-center gap-1 mb-2"><span class="text-xs text-gray-500">Floor Material</span> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-gray-400"><path d="M3 3h18v18H3z"></path><path d="M8 8h8v8H8z"></path></svg></div> <div class="space-y-3"></div></div></div>`, 1);
59962
+ var root_16$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-green-100 rounded flex items-center justify-center text-xs">⬜</span> Room Properties</h3> <div class="space-y-3"><!> <label class="block"><span class="text-xs text-gray-500">Room Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"></select></label> <label class="block"><span class="text-xs text-gray-500">Room Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Category</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>🏠 Indoor</option><option>🌳 Outdoor</option><option>🚗 Garage</option><option>🔧 Utility</option></select></label> <div><span class="text-xs text-gray-500">Area</span> <p class="text-sm text-gray-700"> </p></div> <div><span class="text-xs text-gray-500 mb-1.5 block">Room Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <div><div class="flex items-center gap-1 mb-2"><span class="text-xs text-gray-500">Floor Material</span> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-gray-400"><path d="M3 3h18v18H3z"></path><path d="M8 8h8v8H8z"></path></svg></div> <div class="space-y-3"></div></div></div>`, 1);
59671
59963
  var root_23$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🪜</span> Stair Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Straight</option><option>L-Shaped</option><option>U-Shaped</option><option>Spiral</option></select></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Risers</span> <input type="number" min="3" max="30" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Direction</span> <div class="flex gap-2"><button>Up ↑</button> <button>Down ↓</button></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`, 1);
59672
59964
  var root_25 = /* @__PURE__ */ from_html(`<button></button>`);
59673
59965
  var root_26 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label>`);
59674
- var root_24$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🏛️</span> Column Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Shape</span> <div class="flex gap-2"><button>⭕ Round</button> <button>⬜ Square</button></div></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="10" max="200" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="50" max="1000" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div><span class="text-xs text-gray-500 mb-1.5 block">Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <!></div>`, 1);
59675
- var root_27 = /* @__PURE__ */ from_html(`<div class="space-y-3"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-emerald-100 rounded flex items-center justify-center text-xs">🏷️</span> Text Annotation</h3> <label class="block"><span class="text-xs text-gray-500">Text</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Font Size</span> <input type="number" min="8" max="72" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex items-center gap-2"><input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/> <span class="text-xs text-gray-400"> </span></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (°)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">X</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Y</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`);
59676
- var root_28 = /* @__PURE__ */ from_html(`<div class="mt-4 pt-3 border-t border-gray-200"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-blue-100 rounded flex items-center justify-center text-xs">🖼️</span> Background Image</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Opacity</span> <input type="range" min="0.05" max="1" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Scale</span> <input type="range" min="0.1" max="5" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Rotation</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="flex gap-2"><button> </button> <button class="flex-1 px-2 py-1.5 border rounded text-sm border-gray-200 hover:bg-gray-50">📏 Set Scale</button></div> <button class="w-full px-2 py-1.5 border border-red-300 rounded text-sm text-red-600 hover:bg-red-50">Remove Image</button></div></div>`);
59966
+ var root_24 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🏛️</span> Column Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Shape</span> <div class="flex gap-2"><button>⭕ Round</button> <button>⬜ Square</button></div></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="10" max="200" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="50" max="1000" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div><span class="text-xs text-gray-500 mb-1.5 block">Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <!></div>`, 1);
59967
+ var root_28 = /* @__PURE__ */ from_html(`<button type="button"></button>`);
59968
+ var root_27 = /* @__PURE__ */ from_html(`<div class="space-y-3"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 rounded flex items-center justify-center text-xs">⬡</span> Zone</h3> <label class="block"><span class="text-xs text-gray-500">Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="text-xs text-gray-500">Shape: <span class="text-gray-700 capitalize"> </span></div> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex flex-wrap gap-1.5 mt-1"><!> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></label> <label class="block"><span class="text-xs text-gray-500">Fill opacity</span> <input type="range" min="0" max="0.4" step="0.02" class="w-full"/></label></div>`);
59969
+ var root_29 = /* @__PURE__ */ from_html(`<div class="space-y-3"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-emerald-100 rounded flex items-center justify-center text-xs">🏷️</span> Text Annotation</h3> <label class="block"><span class="text-xs text-gray-500">Text</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Font Size</span> <input type="number" min="8" max="72" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex items-center gap-2"><input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/> <span class="text-xs text-gray-400"> </span></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (°)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">X</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Y</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`);
59970
+ var root_30 = /* @__PURE__ */ from_html(`<div class="mt-4 pt-3 border-t border-gray-200"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-blue-100 rounded flex items-center justify-center text-xs">🖼️</span> Background Image</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Opacity</span> <input type="range" min="0.05" max="1" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Scale</span> <input type="range" min="0.1" max="5" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Rotation</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="flex gap-2"><button> </button> <button class="flex-1 px-2 py-1.5 border rounded text-sm border-gray-200 hover:bg-gray-50">📏 Set Scale</button></div> <button class="w-full px-2 py-1.5 border border-red-300 rounded text-sm text-red-600 hover:bg-red-50">Remove Image</button></div></div>`);
59677
59971
  var root$3 = /* @__PURE__ */ from_html(`<div data-properties-panel="" style="top: 0; bottom: 0;"><!> <!></div>`);
59678
59972
  function PropertiesPanel($$anchor, $$props) {
59679
59973
  push($$props, true);
@@ -59741,29 +60035,33 @@ function PropertiesPanel($$anchor, $$props) {
59741
60035
  var _$$get$textAnnotation, _$$get7;
59742
60036
  return (_$$get$textAnnotation = (_$$get7 = get(floor)) === null || _$$get7 === void 0 || (_$$get7 = _$$get7.textAnnotations) === null || _$$get7 === void 0 ? void 0 : _$$get7.find((t) => t.id === get(selId))) !== null && _$$get$textAnnotation !== void 0 ? _$$get$textAnnotation : null;
59743
60037
  });
60038
+ let selectedZone = /* @__PURE__ */ user_derived(() => {
60039
+ var _$$get$zones$find, _$$get8;
60040
+ return (_$$get$zones$find = (_$$get8 = get(floor)) === null || _$$get8 === void 0 || (_$$get8 = _$$get8.zones) === null || _$$get8 === void 0 ? void 0 : _$$get8.find((z) => z.id === get(selId))) !== null && _$$get$zones$find !== void 0 ? _$$get$zones$find : null;
60041
+ });
59744
60042
  let hasBgImage = /* @__PURE__ */ user_derived(() => {
59745
- var _$$get8;
59746
- return !!((_$$get8 = get(floor)) === null || _$$get8 === void 0 ? void 0 : _$$get8.backgroundImage);
60043
+ var _$$get9;
60044
+ return !!((_$$get9 = get(floor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.backgroundImage);
59747
60045
  });
59748
60046
  let hasCameraThumbnailOverlay = /* @__PURE__ */ user_derived(() => {
59749
- var _cameraThumbnail, _$$get9;
59750
- return !!((_cameraThumbnail = cameraThumbnail()) === null || _cameraThumbnail === void 0 ? void 0 : _cameraThumbnail.trim()) && !((_$$get9 = get(floor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.backgroundImage);
60047
+ var _cameraThumbnail, _$$get10;
60048
+ return !!((_cameraThumbnail = cameraThumbnail()) === null || _cameraThumbnail === void 0 ? void 0 : _cameraThumbnail.trim()) && !((_$$get10 = get(floor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.backgroundImage);
59751
60049
  });
59752
60050
  let thumbOpacity = /* @__PURE__ */ state(.65);
59753
60051
  cameraThumbnailOpacity.subscribe((v) => {
59754
60052
  set(thumbOpacity, v, true);
59755
60053
  });
59756
60054
  let selectedRoom = /* @__PURE__ */ user_derived(() => {
59757
- var _ref, _$$get$rooms$find, _$$get10;
59758
- return (_ref = (_$$get$rooms$find = (_$$get10 = get(floor)) === null || _$$get10 === void 0 || (_$$get10 = _$$get10.rooms) === null || _$$get10 === void 0 ? void 0 : _$$get10.find((r) => r.id === get(selRoomId))) !== null && _$$get$rooms$find !== void 0 ? _$$get$rooms$find : get(detectedRooms).find((r) => r.id === get(selRoomId))) !== null && _ref !== void 0 ? _ref : null;
60055
+ var _ref, _$$get$rooms$find, _$$get11;
60056
+ return (_ref = (_$$get$rooms$find = (_$$get11 = get(floor)) === null || _$$get11 === void 0 || (_$$get11 = _$$get11.rooms) === null || _$$get11 === void 0 ? void 0 : _$$get11.find((r) => r.id === get(selRoomId))) !== null && _$$get$rooms$find !== void 0 ? _$$get$rooms$find : get(detectedRooms).find((r) => r.id === get(selRoomId))) !== null && _ref !== void 0 ? _ref : null;
59759
60057
  });
59760
60058
  let selectedDoorWall = /* @__PURE__ */ user_derived(() => {
59761
- var _ref2, _$$get11;
59762
- return (_ref2 = get(selectedDoor) && ((_$$get11 = get(floor)) === null || _$$get11 === void 0 || (_$$get11 = _$$get11.walls) === null || _$$get11 === void 0 ? void 0 : _$$get11.find((w) => w.id === get(selectedDoor).wallId))) !== null && _ref2 !== void 0 ? _ref2 : null;
60059
+ var _ref2, _$$get12;
60060
+ return (_ref2 = get(selectedDoor) && ((_$$get12 = get(floor)) === null || _$$get12 === void 0 || (_$$get12 = _$$get12.walls) === null || _$$get12 === void 0 ? void 0 : _$$get12.find((w) => w.id === get(selectedDoor).wallId))) !== null && _ref2 !== void 0 ? _ref2 : null;
59763
60061
  });
59764
60062
  let selectedWindowWall = /* @__PURE__ */ user_derived(() => {
59765
- var _ref3, _$$get12;
59766
- return (_ref3 = get(selectedWindow) && ((_$$get12 = get(floor)) === null || _$$get12 === void 0 || (_$$get12 = _$$get12.walls) === null || _$$get12 === void 0 ? void 0 : _$$get12.find((w) => w.id === get(selectedWindow).wallId))) !== null && _ref3 !== void 0 ? _ref3 : null;
60063
+ var _ref3, _$$get13;
60064
+ return (_ref3 = get(selectedWindow) && ((_$$get13 = get(floor)) === null || _$$get13 === void 0 || (_$$get13 = _$$get13.walls) === null || _$$get13 === void 0 ? void 0 : _$$get13.find((w) => w.id === get(selectedWindow).wallId))) !== null && _ref3 !== void 0 ? _ref3 : null;
59767
60065
  });
59768
60066
  function calcWallLength(wall) {
59769
60067
  if (wall.curvePoint) {
@@ -59881,14 +60179,14 @@ function PropertiesPanel($$anchor, $$props) {
59881
60179
  });
59882
60180
  /** Host-assigned camera fields are read-only; package fields (color/size/…) stay editable. */
59883
60181
  const cameraPropsLocked = /* @__PURE__ */ user_derived(() => {
59884
- var _$$get13;
59885
- return !!(((_$$get13 = get(selectedFurniture)) === null || _$$get13 === void 0 ? void 0 : _$$get13.catalogId) === "camera" && get(selectedFurniture).props && Object.keys(get(selectedFurniture).props).length > 0);
60182
+ var _$$get14;
60183
+ return !!(((_$$get14 = get(selectedFurniture)) === null || _$$get14 === void 0 ? void 0 : _$$get14.catalogId) === "camera" && get(selectedFurniture).props && Object.keys(get(selectedFurniture).props).length > 0);
59886
60184
  });
59887
60185
  const useSiteCameraSelect = /* @__PURE__ */ user_derived(() => siteCameras().length > 0);
59888
60186
  const usedCameraSerials = /* @__PURE__ */ user_derived(() => {
59889
- var _$$get14;
60187
+ var _$$get15;
59890
60188
  const used = /* @__PURE__ */ new Set();
59891
- if (!((_$$get14 = get(floor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.furniture) || !get(selectedFurniture)) return used;
60189
+ if (!((_$$get15 = get(floor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.furniture) || !get(selectedFurniture)) return used;
59892
60190
  for (const item of get(floor).furniture) {
59893
60191
  if (item.catalogId !== "camera" || item.id === get(selectedFurniture).id) continue;
59894
60192
  if (item.serial) used.add(item.serial);
@@ -60481,7 +60779,7 @@ function PropertiesPanel($$anchor, $$props) {
60481
60779
  reset(label_11);
60482
60780
  reset(div_11);
60483
60781
  template_effect(($0, $1, $2, $3, $4, $5, $6, $7) => {
60484
- var _$$get15, _$$get16, _$$get17, _$$get18;
60782
+ var _$$get16, _$$get17, _$$get18, _$$get19;
60485
60783
  set_text(text_6, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60486
60784
  set_value(input_5, $1);
60487
60785
  set_text(text_7, `Distance from A (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
@@ -60494,10 +60792,10 @@ function PropertiesPanel($$anchor, $$props) {
60494
60792
  var _select$__value;
60495
60793
  select.value = (_select$__value = select.__value = get(selectedDoor).type) !== null && _select$__value !== void 0 ? _select$__value : "", select_option(select, get(selectedDoor).type);
60496
60794
  }
60497
- set_class(button_9, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get15 = get(selectedDoor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.swingDirection) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60498
- set_class(button_10, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.swingDirection) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60499
- set_class(button_11, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${!((_$$get17 = get(selectedDoor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60500
- set_class(button_12, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get18 = get(selectedDoor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60795
+ set_class(button_9, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.swingDirection) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60796
+ set_class(button_10, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get17 = get(selectedDoor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.swingDirection) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60797
+ set_class(button_11, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${!((_$$get18 = get(selectedDoor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60798
+ set_class(button_12, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get19 = get(selectedDoor)) === null || _$$get19 === void 0 ? void 0 : _$$get19.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60501
60799
  }, [
60502
60800
  () => unitLabel(),
60503
60801
  () => displayValue(get(selectedDoor).width),
@@ -60702,7 +61000,7 @@ function PropertiesPanel($$anchor, $$props) {
60702
61000
  "#dc143c",
60703
61001
  "#228b22"
60704
61002
  ], index$1, ($$anchor, color) => {
60705
- var button_14 = root_15$1();
61003
+ var button_14 = root_15();
60706
61004
  template_effect(($0) => {
60707
61005
  set_class(button_14, 1, `w-6 h-6 rounded border-2 hover:border-gray-300 transition-colors ${$0 !== null && $0 !== void 0 ? $0 : ""}`);
60708
61006
  set_style(button_14, `background-color: ${color !== null && color !== void 0 ? color : ""}`);
@@ -60865,7 +61163,7 @@ function PropertiesPanel($$anchor, $$props) {
60865
61163
  append($$anchor, fragment_3);
60866
61164
  };
60867
61165
  var consequent_9 = ($$anchor) => {
60868
- var fragment_5 = root_16();
61166
+ var fragment_5 = root_16$1();
60869
61167
  var div_21 = sibling(first_child(fragment_5), 2);
60870
61168
  var node_8 = child(div_21);
60871
61169
  var consequent_7 = ($$anchor) => {
@@ -61095,7 +61393,7 @@ function PropertiesPanel($$anchor, $$props) {
61095
61393
  append($$anchor, fragment_7);
61096
61394
  };
61097
61395
  var consequent_12 = ($$anchor) => {
61098
- var fragment_8 = root_24$1();
61396
+ var fragment_8 = root_24();
61099
61397
  var div_34 = sibling(first_child(fragment_8), 2);
61100
61398
  var label_35 = child(div_34);
61101
61399
  var div_35 = sibling(child(label_35), 2);
@@ -61173,24 +61471,57 @@ function PropertiesPanel($$anchor, $$props) {
61173
61471
  };
61174
61472
  var consequent_13 = ($$anchor) => {
61175
61473
  var div_39 = root_27();
61176
- var label_39 = sibling(child(div_39), 2);
61474
+ var h3_1 = child(div_39);
61475
+ var span_25 = child(h3_1);
61476
+ next();
61477
+ reset(h3_1);
61478
+ var label_39 = sibling(h3_1, 2);
61177
61479
  var input_31 = sibling(child(label_39), 2);
61178
61480
  remove_input_defaults(input_31);
61179
61481
  reset(label_39);
61180
- var label_40 = sibling(label_39, 2);
61181
- var input_32 = sibling(child(label_40), 2);
61482
+ var div_40 = sibling(label_39, 2);
61483
+ var span_26 = sibling(child(div_40));
61484
+ var text_32 = child(span_26, true);
61485
+ reset(span_26);
61486
+ reset(div_40);
61487
+ var label_40 = sibling(div_40, 2);
61488
+ var div_41 = sibling(child(label_40), 2);
61489
+ var node_11 = child(div_41);
61490
+ each(node_11, 17, () => ZONE_COLOR_PALETTE, index$1, ($$anchor, c) => {
61491
+ var button_27 = root_28();
61492
+ template_effect(() => {
61493
+ var _$$get20;
61494
+ set_class(button_27, 1, `w-6 h-6 rounded border-2 ${get(selectedZone).color === get(c) ? "border-slate-800" : "border-transparent"}`);
61495
+ set_style(button_27, `background:${(_$$get20 = get(c)) !== null && _$$get20 !== void 0 ? _$$get20 : ""}`);
61496
+ });
61497
+ delegated("click", button_27, () => updateZone(get(selectedZone).id, { color: get(c) }));
61498
+ append($$anchor, button_27);
61499
+ });
61500
+ var input_32 = sibling(node_11, 2);
61182
61501
  remove_input_defaults(input_32);
61502
+ reset(div_41);
61183
61503
  reset(label_40);
61184
61504
  var label_41 = sibling(label_40, 2);
61185
- var div_40 = sibling(child(label_41), 2);
61186
- var input_33 = child(div_40);
61505
+ var input_33 = sibling(child(label_41), 2);
61187
61506
  remove_input_defaults(input_33);
61188
- var span_25 = sibling(input_33, 2);
61189
- var text_32 = child(span_25, true);
61190
- reset(span_25);
61191
- reset(div_40);
61192
61507
  reset(label_41);
61193
- var label_42 = sibling(label_41, 2);
61508
+ reset(div_39);
61509
+ template_effect(() => {
61510
+ var _$$get$color8, _$$get$color9, _$$get$fillOpacity;
61511
+ set_style(span_25, `background:${(_$$get$color8 = get(selectedZone).color) !== null && _$$get$color8 !== void 0 ? _$$get$color8 : ""}22;color:${(_$$get$color9 = get(selectedZone).color) !== null && _$$get$color9 !== void 0 ? _$$get$color9 : ""}`);
61512
+ set_value(input_31, get(selectedZone).name);
61513
+ set_text(text_32, get(selectedZone).shape);
61514
+ set_value(input_32, get(selectedZone).color);
61515
+ set_value(input_33, (_$$get$fillOpacity = get(selectedZone).fillOpacity) !== null && _$$get$fillOpacity !== void 0 ? _$$get$fillOpacity : .1);
61516
+ });
61517
+ delegated("input", input_31, (e) => updateZone(get(selectedZone).id, { name: e.target.value }));
61518
+ delegated("input", input_32, (e) => updateZone(get(selectedZone).id, { color: e.target.value }));
61519
+ delegated("input", input_33, (e) => updateZone(get(selectedZone).id, { fillOpacity: Number(e.target.value) }));
61520
+ append($$anchor, div_39);
61521
+ };
61522
+ var consequent_14 = ($$anchor) => {
61523
+ var div_42 = root_29();
61524
+ var label_42 = sibling(child(div_42), 2);
61194
61525
  var input_34 = sibling(child(label_42), 2);
61195
61526
  remove_input_defaults(input_34);
61196
61527
  reset(label_42);
@@ -61199,42 +61530,15 @@ function PropertiesPanel($$anchor, $$props) {
61199
61530
  remove_input_defaults(input_35);
61200
61531
  reset(label_43);
61201
61532
  var label_44 = sibling(label_43, 2);
61202
- var input_36 = sibling(child(label_44), 2);
61533
+ var div_43 = sibling(child(label_44), 2);
61534
+ var input_36 = child(div_43);
61203
61535
  remove_input_defaults(input_36);
61536
+ var span_27 = sibling(input_36, 2);
61537
+ var text_33 = child(span_27, true);
61538
+ reset(span_27);
61539
+ reset(div_43);
61204
61540
  reset(label_44);
61205
- reset(div_39);
61206
- template_effect(($0, $1) => {
61207
- set_value(input_31, get(selectedTextAnnotation).text);
61208
- set_value(input_32, get(selectedTextAnnotation).fontSize);
61209
- set_value(input_33, get(selectedTextAnnotation).color);
61210
- set_text(text_32, get(selectedTextAnnotation).color);
61211
- set_value(input_34, get(selectedTextAnnotation).rotation);
61212
- set_value(input_35, $0);
61213
- set_value(input_36, $1);
61214
- }, [() => Math.round(get(selectedTextAnnotation).x), () => Math.round(get(selectedTextAnnotation).y)]);
61215
- delegated("input", input_31, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { text: e.target.value }));
61216
- delegated("input", input_32, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { fontSize: Number(e.target.value) }));
61217
- delegated("input", input_33, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { color: e.target.value }));
61218
- delegated("input", input_34, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
61219
- delegated("input", input_35, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
61220
- delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
61221
- append($$anchor, div_39);
61222
- };
61223
- if_block(node, ($$render) => {
61224
- if (get(selectedWall)) $$render(consequent_1);
61225
- else if (get(selectedDoor)) $$render(consequent_2, 1);
61226
- else if (get(selectedWindow)) $$render(consequent_3, 2);
61227
- else if (get(selectedFurniture)) $$render(consequent_6, 3);
61228
- else if (get(selectedRoom)) $$render(consequent_9, 4);
61229
- else if (get(selectedStair)) $$render(consequent_10, 5);
61230
- else if (get(selectedColumn)) $$render(consequent_12, 6);
61231
- else if (get(selectedTextAnnotation)) $$render(consequent_13, 7);
61232
- });
61233
- var node_11 = sibling(node, 2);
61234
- var consequent_14 = ($$anchor) => {
61235
- var div_41 = root_28();
61236
- var div_42 = sibling(child(div_41), 2);
61237
- var label_45 = child(div_42);
61541
+ var label_45 = sibling(label_44, 2);
61238
61542
  var input_37 = sibling(child(label_45), 2);
61239
61543
  remove_input_defaults(input_37);
61240
61544
  reset(label_45);
@@ -61246,36 +61550,81 @@ function PropertiesPanel($$anchor, $$props) {
61246
61550
  var input_39 = sibling(child(label_47), 2);
61247
61551
  remove_input_defaults(input_39);
61248
61552
  reset(label_47);
61249
- var div_43 = sibling(label_47, 2);
61250
- var button_27 = child(div_43);
61251
- var text_33 = child(button_27, true);
61252
- reset(button_27);
61253
- var button_28 = sibling(button_27, 2);
61254
- reset(div_43);
61255
- var button_29 = sibling(div_43, 2);
61256
61553
  reset(div_42);
61257
- reset(div_41);
61554
+ template_effect(($0, $1) => {
61555
+ set_value(input_34, get(selectedTextAnnotation).text);
61556
+ set_value(input_35, get(selectedTextAnnotation).fontSize);
61557
+ set_value(input_36, get(selectedTextAnnotation).color);
61558
+ set_text(text_33, get(selectedTextAnnotation).color);
61559
+ set_value(input_37, get(selectedTextAnnotation).rotation);
61560
+ set_value(input_38, $0);
61561
+ set_value(input_39, $1);
61562
+ }, [() => Math.round(get(selectedTextAnnotation).x), () => Math.round(get(selectedTextAnnotation).y)]);
61563
+ delegated("input", input_34, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { text: e.target.value }));
61564
+ delegated("input", input_35, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { fontSize: Number(e.target.value) }));
61565
+ delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { color: e.target.value }));
61566
+ delegated("input", input_37, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
61567
+ delegated("input", input_38, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
61568
+ delegated("input", input_39, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
61569
+ append($$anchor, div_42);
61570
+ };
61571
+ if_block(node, ($$render) => {
61572
+ if (get(selectedWall)) $$render(consequent_1);
61573
+ else if (get(selectedDoor)) $$render(consequent_2, 1);
61574
+ else if (get(selectedWindow)) $$render(consequent_3, 2);
61575
+ else if (get(selectedFurniture)) $$render(consequent_6, 3);
61576
+ else if (get(selectedRoom)) $$render(consequent_9, 4);
61577
+ else if (get(selectedStair)) $$render(consequent_10, 5);
61578
+ else if (get(selectedColumn)) $$render(consequent_12, 6);
61579
+ else if (get(selectedZone)) $$render(consequent_13, 7);
61580
+ else if (get(selectedTextAnnotation)) $$render(consequent_14, 8);
61581
+ });
61582
+ var node_12 = sibling(node, 2);
61583
+ var consequent_15 = ($$anchor) => {
61584
+ var div_44 = root_30();
61585
+ var div_45 = sibling(child(div_44), 2);
61586
+ var label_48 = child(div_45);
61587
+ var input_40 = sibling(child(label_48), 2);
61588
+ remove_input_defaults(input_40);
61589
+ reset(label_48);
61590
+ var label_49 = sibling(label_48, 2);
61591
+ var input_41 = sibling(child(label_49), 2);
61592
+ remove_input_defaults(input_41);
61593
+ reset(label_49);
61594
+ var label_50 = sibling(label_49, 2);
61595
+ var input_42 = sibling(child(label_50), 2);
61596
+ remove_input_defaults(input_42);
61597
+ reset(label_50);
61598
+ var div_46 = sibling(label_50, 2);
61599
+ var button_28 = child(div_46);
61600
+ var text_34 = child(button_28, true);
61601
+ reset(button_28);
61602
+ var button_29 = sibling(button_28, 2);
61603
+ reset(div_46);
61604
+ var button_30 = sibling(div_46, 2);
61605
+ reset(div_45);
61606
+ reset(div_44);
61258
61607
  template_effect(() => {
61259
- set_value(input_37, get(floor).backgroundImage.opacity);
61260
- set_value(input_38, get(floor).backgroundImage.scale);
61261
- set_value(input_39, get(floor).backgroundImage.rotation);
61262
- set_class(button_27, 1, `flex-1 px-2 py-1.5 border rounded text-sm ${get(floor).backgroundImage.locked ? "bg-amber-100 border-amber-400 text-amber-700" : "border-gray-200 hover:bg-gray-50"}`);
61263
- set_text(text_33, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
61608
+ set_value(input_40, get(floor).backgroundImage.opacity);
61609
+ set_value(input_41, get(floor).backgroundImage.scale);
61610
+ set_value(input_42, get(floor).backgroundImage.rotation);
61611
+ set_class(button_28, 1, `flex-1 px-2 py-1.5 border rounded text-sm ${get(floor).backgroundImage.locked ? "bg-amber-100 border-amber-400 text-amber-700" : "border-gray-200 hover:bg-gray-50"}`);
61612
+ set_text(text_34, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
61264
61613
  });
61265
- delegated("input", input_37, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
61266
- delegated("input", input_38, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
61267
- delegated("input", input_39, (e) => updateBackgroundImage({ rotation: Number(e.target.value) }));
61268
- delegated("click", button_27, () => updateBackgroundImage({ locked: !get(floor).backgroundImage.locked }));
61269
- delegated("click", button_28, () => {
61614
+ delegated("input", input_40, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
61615
+ delegated("input", input_41, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
61616
+ delegated("input", input_42, (e) => updateBackgroundImage({ rotation: Number(e.target.value) }));
61617
+ delegated("click", button_28, () => updateBackgroundImage({ locked: !get(floor).backgroundImage.locked }));
61618
+ delegated("click", button_29, () => {
61270
61619
  calibrationPoints.set([]);
61271
61620
  calibrationMode.set(true);
61272
61621
  });
61273
- delegated("click", button_29, () => setBackgroundImage(void 0));
61274
- append($$anchor, div_41);
61622
+ delegated("click", button_30, () => setBackgroundImage(void 0));
61623
+ append($$anchor, div_44);
61275
61624
  };
61276
- if_block(node_11, ($$render) => {
61277
- var _$$get19;
61278
- if (get(hasBgImage) && ((_$$get19 = get(floor)) === null || _$$get19 === void 0 ? void 0 : _$$get19.backgroundImage)) $$render(consequent_14);
61625
+ if_block(node_12, ($$render) => {
61626
+ var _$$get21;
61627
+ if (get(hasBgImage) && ((_$$get21 = get(floor)) === null || _$$get21 === void 0 ? void 0 : _$$get21.backgroundImage)) $$render(consequent_15);
61279
61628
  });
61280
61629
  reset(div);
61281
61630
  template_effect(() => classes = set_class(div, 1, `${is3D() ? "w-80" : "w-64"} shrink-0 bg-white border-l border-gray-200 flex flex-col overflow-y-auto p-3 absolute right-0 z-40 shadow-lg`, null, classes, { hidden: !get(hasSelection) }));
@@ -61319,10 +61668,14 @@ function LayersPanel($$anchor, $$props) {
61319
61668
  columns: true,
61320
61669
  guides: true,
61321
61670
  measurements: true,
61322
- annotations: true
61671
+ annotations: true,
61672
+ zones: true
61323
61673
  }));
61324
61674
  layerVisibility.subscribe((v) => {
61325
- set(vis, v, true);
61675
+ set(vis, {
61676
+ zones: true,
61677
+ ...v
61678
+ }, true);
61326
61679
  });
61327
61680
  let collapsed = proxy({});
61328
61681
  function toggle(cat) {
@@ -61338,7 +61691,7 @@ function LayersPanel($$anchor, $$props) {
61338
61691
  selectedElementId.set(id);
61339
61692
  }
61340
61693
  let categories = /* @__PURE__ */ user_derived(() => {
61341
- var _$$get$stairs, _$$get$columns, _$$get$guides, _$$get$measurements, _$$get$annotations;
61694
+ var _$$get$stairs, _$$get$columns, _$$get$zones, _$$get$guides, _$$get$measurements, _$$get$annotations;
61342
61695
  if (!get(floor)) return [];
61343
61696
  const cats = [];
61344
61697
  cats.push({
@@ -61405,6 +61758,16 @@ function LayersPanel($$anchor, $$props) {
61405
61758
  icon: "🏛️"
61406
61759
  }))
61407
61760
  });
61761
+ if ((_$$get$zones = get(floor).zones) === null || _$$get$zones === void 0 ? void 0 : _$$get$zones.length) cats.push({
61762
+ key: "zones",
61763
+ label: "Zones",
61764
+ icon: "⬡",
61765
+ items: get(floor).zones.map((z) => ({
61766
+ id: z.id,
61767
+ label: z.name || z.shape,
61768
+ icon: "⬡"
61769
+ }))
61770
+ });
61408
61771
  if ((_$$get$guides = get(floor).guides) === null || _$$get$guides === void 0 ? void 0 : _$$get$guides.length) cats.push({
61409
61772
  key: "guides",
61410
61773
  label: "Guides",
@@ -64351,6 +64714,120 @@ function drawTextAnnotations(cs, floor, selectedTextAnnotationId, currentSelecte
64351
64714
  ctx.restore();
64352
64715
  }
64353
64716
  }
64717
+ function hexToRgba(hex, alpha) {
64718
+ const c = hex.trim();
64719
+ const short = c.match(/^#([0-9a-f]{3})$/i);
64720
+ let h = c;
64721
+ if (short) {
64722
+ const s = short[1];
64723
+ h = `#${s[0]}${s[0]}${s[1]}${s[1]}${s[2]}${s[2]}`;
64724
+ }
64725
+ const m = h.match(/^#([0-9a-f]{6})$/i);
64726
+ if (!m) return `rgba(249, 115, 22, ${alpha})`;
64727
+ const n = parseInt(m[1], 16);
64728
+ return `rgba(${n >> 16 & 255}, ${n >> 8 & 255}, ${n & 255}, ${alpha})`;
64729
+ }
64730
+ function pathZonePolygon(ctx, cs, points) {
64731
+ if (points.length < 2) return;
64732
+ const first = wts(cs, points[0].x, points[0].y);
64733
+ ctx.moveTo(first.x, first.y);
64734
+ for (let i = 1; i < points.length; i++) {
64735
+ const s = wts(cs, points[i].x, points[i].y);
64736
+ ctx.lineTo(s.x, s.y);
64737
+ }
64738
+ ctx.closePath();
64739
+ }
64740
+ function drawZoneShape(cs, zone, selected) {
64741
+ const pts = zone.points;
64742
+ if (!pts || pts.length < 2) return;
64743
+ const { ctx, zoom } = cs;
64744
+ const color = zone.color || "#F97316";
64745
+ const fillA = typeof zone.fillOpacity === "number" ? zone.fillOpacity : DEFAULT_ZONE_FILL_OPACITY;
64746
+ ctx.save();
64747
+ ctx.beginPath();
64748
+ pathZonePolygon(ctx, cs, pts);
64749
+ ctx.fillStyle = hexToRgba(color, fillA);
64750
+ ctx.fill();
64751
+ ctx.setLineDash([8 * Math.max(.6, zoom), 6 * Math.max(.6, zoom)]);
64752
+ ctx.strokeStyle = color;
64753
+ ctx.lineWidth = selected ? 2.5 : 1.75;
64754
+ ctx.lineJoin = "round";
64755
+ ctx.stroke();
64756
+ ctx.setLineDash([]);
64757
+ const b = zoneBounds(pts);
64758
+ if (b && zone.name) {
64759
+ const pad = 6;
64760
+ const labelPos = wts(cs, b.minX, b.minY);
64761
+ const fontSize = Math.max(11, 12 * Math.min(1.2, Math.max(.75, zoom)));
64762
+ ctx.font = `600 ${fontSize}px system-ui, sans-serif`;
64763
+ ctx.textAlign = "left";
64764
+ ctx.textBaseline = "top";
64765
+ const tw = ctx.measureText(zone.name).width;
64766
+ const bx = labelPos.x + pad;
64767
+ const by = labelPos.y + pad;
64768
+ const bw = tw + 12;
64769
+ const bh = fontSize + 8;
64770
+ ctx.fillStyle = hexToRgba(color, .22);
64771
+ ctx.beginPath();
64772
+ ctx.roundRect(bx, by, bw, bh, 4);
64773
+ ctx.fill();
64774
+ ctx.fillStyle = color;
64775
+ ctx.fillText(zone.name, bx + 6, by + 4);
64776
+ }
64777
+ if (selected) for (const p of pts) {
64778
+ const s = wts(cs, p.x, p.y);
64779
+ ctx.fillStyle = "#ffffff";
64780
+ ctx.strokeStyle = color;
64781
+ ctx.lineWidth = 1.5;
64782
+ ctx.beginPath();
64783
+ ctx.arc(s.x, s.y, 5, 0, Math.PI * 2);
64784
+ ctx.fill();
64785
+ ctx.stroke();
64786
+ }
64787
+ ctx.restore();
64788
+ }
64789
+ function drawZones(cs, floor, selectedZoneId) {
64790
+ var _floor$zones;
64791
+ if (!((_floor$zones = floor.zones) === null || _floor$zones === void 0 ? void 0 : _floor$zones.length)) return;
64792
+ for (const z of floor.zones) drawZoneShape(cs, z, z.id === selectedZoneId);
64793
+ }
64794
+ /** Preview while drawing polygon / dragging rect. */
64795
+ function drawZoneDraft(cs, points, color, closed, cursor) {
64796
+ if (!points.length && !cursor) return;
64797
+ const { ctx, zoom } = cs;
64798
+ const pts = [...points];
64799
+ if (cursor) pts.push(cursor);
64800
+ ctx.save();
64801
+ ctx.strokeStyle = color;
64802
+ ctx.fillStyle = hexToRgba(color, .08);
64803
+ ctx.lineWidth = 1.5;
64804
+ ctx.setLineDash([6 * Math.max(.6, zoom), 4 * Math.max(.6, zoom)]);
64805
+ if (pts.length >= 2) {
64806
+ ctx.beginPath();
64807
+ const first = wts(cs, pts[0].x, pts[0].y);
64808
+ ctx.moveTo(first.x, first.y);
64809
+ for (let i = 1; i < pts.length; i++) {
64810
+ const s = wts(cs, pts[i].x, pts[i].y);
64811
+ ctx.lineTo(s.x, s.y);
64812
+ }
64813
+ if (closed && pts.length >= 3) {
64814
+ ctx.closePath();
64815
+ ctx.fill();
64816
+ }
64817
+ ctx.stroke();
64818
+ }
64819
+ for (const p of points) {
64820
+ const s = wts(cs, p.x, p.y);
64821
+ ctx.setLineDash([]);
64822
+ ctx.fillStyle = "#fff";
64823
+ ctx.strokeStyle = color;
64824
+ ctx.beginPath();
64825
+ ctx.arc(s.x, s.y, 4, 0, Math.PI * 2);
64826
+ ctx.fill();
64827
+ ctx.stroke();
64828
+ }
64829
+ ctx.restore();
64830
+ }
64354
64831
  function drawAnnotation(cs, a, selected, dimSettings) {
64355
64832
  const { ctx, zoom } = cs;
64356
64833
  const offset = a.offset || 40;
@@ -64745,14 +65222,39 @@ function getMatrixKey(matrix) {
64745
65222
  const step = Math.max(1, Math.floor(flat.length / 20));
64746
65223
  return flat.filter((_, i) => i % step === 0).join(",");
64747
65224
  }
64748
- function drawFloorHeatmap(cs, floor, heatmapMatrix, detectedRooms) {
65225
+ function paintHeatmapBlob(blobCtx, px, py, radius, centerColor, midColor, edgeColor, fadeColor) {
65226
+ const gradient = blobCtx.createRadialGradient(px, py, 0, px, py, radius);
65227
+ gradient.addColorStop(0, centerColor);
65228
+ gradient.addColorStop(.2, midColor);
65229
+ gradient.addColorStop(.5, edgeColor);
65230
+ gradient.addColorStop(1, fadeColor);
65231
+ blobCtx.fillStyle = gradient;
65232
+ blobCtx.beginPath();
65233
+ blobCtx.arc(px, py, radius, 0, Math.PI * 2);
65234
+ blobCtx.fill();
65235
+ }
65236
+ function drawFloorHeatmap(cs, floor, heatmapMatrix, detectedRooms, colorScale) {
64749
65237
  var _heatmapMatrix$;
64750
65238
  const { ctx } = cs;
64751
65239
  const rows = heatmapMatrix.length;
64752
65240
  const cols = ((_heatmapMatrix$ = heatmapMatrix[0]) === null || _heatmapMatrix$ === void 0 ? void 0 : _heatmapMatrix$.length) || 0;
64753
65241
  if (rows === 0 || cols === 0) return;
65242
+ const useLevels = isLevelsColorScale(colorScale);
64754
65243
  const maxValue = heatmapMatrix.reduce((max, row) => row.reduce((m, v) => v > m ? v : m, max), 0);
64755
- if (maxValue <= 0) return;
65244
+ if (!useLevels && maxValue <= 0) return;
65245
+ if (useLevels) {
65246
+ var _colorScale$hideBelow;
65247
+ const hide = (_colorScale$hideBelow = colorScale.hideBelow) !== null && _colorScale$hideBelow !== void 0 ? _colorScale$hideBelow : 0;
65248
+ let anyVisible = false;
65249
+ outer: for (let y = 0; y < rows; y++) for (let x = 0; x < cols; x++) {
65250
+ const v = heatmapMatrix[y][x];
65251
+ if (v > hide && resolveHeatmapLevelColor(v, colorScale)) {
65252
+ anyVisible = true;
65253
+ break outer;
65254
+ }
65255
+ }
65256
+ if (!anyVisible) return;
65257
+ }
64756
65258
  const bounds = getFloorBounds(floor);
64757
65259
  if (!bounds) return;
64758
65260
  const { minX, minY, maxX, maxY } = bounds;
@@ -64760,8 +65262,9 @@ function drawFloorHeatmap(cs, floor, heatmapMatrix, detectedRooms) {
64760
65262
  const boxH = bounds.height;
64761
65263
  if (boxW <= 0 || boxH <= 0) return;
64762
65264
  const matrixKey = getMatrixKey(heatmapMatrix);
65265
+ const scaleKey = getHeatmapColorScaleKey(colorScale);
64763
65266
  const floorId = floor.id;
64764
- const needsRedraw = !heatmapCache || heatmapCache.matrixKey !== matrixKey || heatmapCache.floorId !== floorId;
65267
+ const needsRedraw = !heatmapCache || heatmapCache.matrixKey !== matrixKey || heatmapCache.scaleKey !== scaleKey || heatmapCache.floorId !== floorId;
64765
65268
  const OFFSCREEN_W = 512;
64766
65269
  const OFFSCREEN_H = 512;
64767
65270
  if (needsRedraw) {
@@ -64776,19 +65279,18 @@ function drawFloorHeatmap(cs, floor, heatmapMatrix, detectedRooms) {
64776
65279
  for (let y = 0; y < rows; y++) for (let x = 0; x < cols; x++) {
64777
65280
  const value = heatmapMatrix[y][x];
64778
65281
  if (!value || value <= 0) continue;
64779
- const intensity = Math.min(value / maxValue, 1);
64780
65282
  const px = (x + .5) * offCellW;
64781
65283
  const py = (y + .5) * offCellH;
64782
- const alpha = .5 + intensity * .45;
64783
- const gradient = blobCtx.createRadialGradient(px, py, 0, px, py, radius);
64784
- gradient.addColorStop(0, getHeatmapColor(intensity, alpha));
64785
- gradient.addColorStop(.2, getHeatmapColor(intensity, alpha * .75));
64786
- gradient.addColorStop(.5, getHeatmapColor(intensity, alpha * .25));
64787
- gradient.addColorStop(1, getHeatmapColor(intensity, 0));
64788
- blobCtx.fillStyle = gradient;
64789
- blobCtx.beginPath();
64790
- blobCtx.arc(px, py, radius, 0, Math.PI * 2);
64791
- blobCtx.fill();
65284
+ if (useLevels) {
65285
+ const hit = resolveHeatmapLevelColor(value, colorScale);
65286
+ if (!hit) continue;
65287
+ const alpha = .55 + (hit.levelCount <= 1 ? 1 : hit.levelIndex / (hit.levelCount - 1)) * .4;
65288
+ paintHeatmapBlob(blobCtx, px, py, radius, colorWithAlpha(hit.color, alpha), colorWithAlpha(hit.color, alpha * .75), colorWithAlpha(hit.color, alpha * .25), colorWithAlpha(hit.color, 0));
65289
+ } else {
65290
+ const intensity = Math.min(value / maxValue, 1);
65291
+ const alpha = .5 + intensity * .45;
65292
+ paintHeatmapBlob(blobCtx, px, py, radius, getHeatmapColor(intensity, alpha), getHeatmapColor(intensity, alpha * .75), getHeatmapColor(intensity, alpha * .25), getHeatmapColor(intensity, 0));
65293
+ }
64792
65294
  }
64793
65295
  const finalCanvas = document.createElement("canvas");
64794
65296
  finalCanvas.width = OFFSCREEN_W;
@@ -64813,6 +65315,7 @@ function drawFloorHeatmap(cs, floor, heatmapMatrix, detectedRooms) {
64813
65315
  heatmapCache = {
64814
65316
  canvas: finalCanvas,
64815
65317
  matrixKey,
65318
+ scaleKey,
64816
65319
  floorId
64817
65320
  };
64818
65321
  }
@@ -65084,41 +65587,65 @@ function hitTestTextAnnotation(wp, floor, ctx, zoom) {
65084
65587
  }
65085
65588
  return null;
65086
65589
  }
65590
+ /** Hit zone vertex; returns index or -1. */
65591
+ function findZoneVertexAt(wp, zone, zoom) {
65592
+ const threshold = 10 / zoom;
65593
+ for (let i = 0; i < zone.points.length; i++) {
65594
+ const p = zone.points[i];
65595
+ if (Math.hypot(wp.x - p.x, wp.y - p.y) <= threshold) return i;
65596
+ }
65597
+ return -1;
65598
+ }
65599
+ /** Top-most zone under point (fill or near edge). */
65600
+ function findZoneAt(wp, zones, zoom) {
65601
+ if (!(zones === null || zones === void 0 ? void 0 : zones.length)) return null;
65602
+ const edgeTol = 8 / zoom;
65603
+ for (let i = zones.length - 1; i >= 0; i--) {
65604
+ const z = zones[i];
65605
+ if (!z.points || z.points.length < 2) continue;
65606
+ if (pointInPolygon(wp, z.points)) return z;
65607
+ for (let j = 0; j < z.points.length; j++) {
65608
+ const a = z.points[j];
65609
+ const b = z.points[(j + 1) % z.points.length];
65610
+ if (pointToSegmentDist(wp, a, b) <= edgeTol) return z;
65611
+ }
65612
+ }
65613
+ return null;
65614
+ }
65087
65615
  //#endregion
65088
65616
  //#region src/lib/components/editor/FloorPlanCanvas.svelte
65089
65617
  init_client();
65090
65618
  init_index_client();
65091
- var root_1$4 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-2 z-10 px-2 py-1 bg-white/85 rounded text-sm font-semibold text-gray-700 shadow pointer-events-none"> </div>`);
65619
+ var root_2$4 = /* @__PURE__ */ from_html(`<input type="text" class="absolute bg-white border-2 border-blue-500 rounded px-2 py-1 text-sm text-center shadow-lg outline-none"/>`);
65092
65620
  var root_3$3 = /* @__PURE__ */ from_html(`<input type="text" class="absolute bg-white border-2 border-blue-500 rounded px-2 py-1 text-sm text-center shadow-lg outline-none"/>`);
65093
- var root_4$2 = /* @__PURE__ */ from_html(`<input type="text" class="absolute bg-white border-2 border-blue-500 rounded px-2 py-1 text-sm text-center shadow-lg outline-none"/>`);
65094
- var root_5 = /* @__PURE__ */ from_html(`<div class="absolute inset-0 flex items-center justify-center pointer-events-none"><div class="text-center opacity-60"><div class="text-5xl mb-3">🏠</div> <div class="text-sm font-medium text-gray-500">Start building your floor plan</div> <div class="text-xs text-gray-400 mt-1">Draw walls with <span class="font-mono bg-gray-100 px-1 rounded">W</span> or drag items from the sidebar</div></div></div>`);
65095
- var root_6 = /* @__PURE__ */ from_html(`<canvas width="180" height="120" class="absolute bottom-10 right-2 rounded-lg shadow-lg border border-gray-300 cursor-crosshair bg-white" style="z-index: 15;"></canvas>`);
65096
- var root_8 = /* @__PURE__ */ from_html(`<span> </span> <span> </span> <span class="text-gray-300">|</span>`, 1);
65621
+ var root_4$2 = /* @__PURE__ */ from_html(`<div class="absolute inset-0 flex items-center justify-center pointer-events-none"><div class="text-center opacity-60"><div class="text-5xl mb-3">🏠</div> <div class="text-sm font-medium text-gray-500">Start building your floor plan</div> <div class="text-xs text-gray-400 mt-1">Draw walls with <span class="font-mono bg-gray-100 px-1 rounded">W</span> or drag items from the sidebar</div></div></div>`);
65622
+ var root_5 = /* @__PURE__ */ from_html(`<canvas width="180" height="120" class="absolute bottom-10 right-2 rounded-lg shadow-lg border border-gray-300 cursor-crosshair bg-white" style="z-index: 15;"></canvas>`);
65623
+ var root_7$1 = /* @__PURE__ */ from_html(`<span> </span> <span> </span> <span class="text-gray-300">|</span>`, 1);
65624
+ var root_9 = /* @__PURE__ */ from_html(`<span> </span>`);
65097
65625
  var root_10 = /* @__PURE__ */ from_html(`<span> </span>`);
65098
65626
  var root_11 = /* @__PURE__ */ from_html(`<span> </span>`);
65099
- var root_12 = /* @__PURE__ */ from_html(`<span> </span>`);
65100
- var root_9 = /* @__PURE__ */ from_html(`<span> </span> <!> <!> <!> <span class="text-gray-300">|</span>`, 1);
65101
- var root_13 = /* @__PURE__ */ from_html(`<span class="text-blue-600 font-medium"> </span> <span class="text-gray-300">|</span>`, 1);
65102
- var root_7$1 = /* @__PURE__ */ from_html(`<div class="absolute bottom-2 right-2 bg-white/80 rounded px-2 py-1 text-xs text-gray-500 flex gap-3"><!> <!> <!> <span> </span> <button class="hover:text-gray-700" title="Zoom to Fit (F)">⊞ Fit</button> <button class="hover:text-gray-700" title="Toggle Grid (G)"> </button> <button class="hover:text-gray-700" title="Toggle Snap to Grid (S)"> </button> <button class="hover:text-gray-700" title="Toggle Furniture"> </button> <button class="hover:text-gray-700" title="Layer Visibility">🗂 Layers</button> <button class="hover:text-gray-700" title="Toggle Rulers"> </button> <button class="hover:text-gray-700" title="Toggle Mini-map"> </button></div>`);
65103
- var root_15 = /* @__PURE__ */ from_html(`<label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span> </span></label>`);
65104
- var root_14 = /* @__PURE__ */ from_html(`<div class="absolute bottom-12 right-2 z-20 bg-white rounded-lg shadow-lg border border-gray-200 p-3 text-xs min-w-[160px]"><div class="font-semibold text-gray-700 mb-2">Layers</div> <!> <hr class="my-1 border-gray-100"/> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Room Labels</span></label> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Dimensions</span></label></div>`);
65105
- var root_18 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Flip swing" aria-label="Flip swing"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 16V4m0 0L3 8m4-4l4 4M17 8v12m0 0l4-4m-4 4l-4-4"></path></svg></button>`);
65106
- var root_19 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Split wall at midpoint" aria-label="Split wall at midpoint"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M4 12h4M16 12h4"></path></svg></button>`);
65107
- var root_17 = /* @__PURE__ */ from_html(`<div class="absolute z-40 flex items-center gap-0.5 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Duplicate" aria-label="Duplicate"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg></button> <!> <!> <div class="w-px h-5 bg-gray-200 mx-0.5"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-red-50 text-gray-400 hover:text-red-600" title="Delete" aria-label="Delete"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2m3 0v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6h14"></path></svg></button></div>`);
65108
- var root_20 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-blue-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to add wall segment · Double-click to finish · C to close loop ·
65627
+ var root_8 = /* @__PURE__ */ from_html(`<span> </span> <!> <!> <!> <span class="text-gray-300">|</span>`, 1);
65628
+ var root_12 = /* @__PURE__ */ from_html(`<span class="text-blue-600 font-medium"> </span> <span class="text-gray-300">|</span>`, 1);
65629
+ var root_6 = /* @__PURE__ */ from_html(`<div class="absolute bottom-2 right-2 bg-white/80 rounded px-2 py-1 text-xs text-gray-500 flex gap-3"><!> <!> <!> <span> </span> <button class="hover:text-gray-700" title="Zoom to Fit (F)">⊞ Fit</button> <button class="hover:text-gray-700" title="Toggle Grid (G)"> </button> <button class="hover:text-gray-700" title="Toggle Snap to Grid (S)"> </button> <button class="hover:text-gray-700" title="Toggle Furniture"> </button> <button class="hover:text-gray-700" title="Layer Visibility">🗂 Layers</button> <button class="hover:text-gray-700" title="Toggle Rulers"> </button> <button class="hover:text-gray-700" title="Toggle Mini-map"> </button></div>`);
65630
+ var root_14 = /* @__PURE__ */ from_html(`<label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span> </span></label>`);
65631
+ var root_13 = /* @__PURE__ */ from_html(`<div class="absolute bottom-12 right-2 z-20 bg-white rounded-lg shadow-lg border border-gray-200 p-3 text-xs min-w-[160px]"><div class="font-semibold text-gray-700 mb-2">Layers</div> <!> <hr class="my-1 border-gray-100"/> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Room Labels</span></label> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Dimensions</span></label></div>`);
65632
+ var root_17 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Flip swing" aria-label="Flip swing"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 16V4m0 0L3 8m4-4l4 4M17 8v12m0 0l4-4m-4 4l-4-4"></path></svg></button>`);
65633
+ var root_18 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Split wall at midpoint" aria-label="Split wall at midpoint"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M4 12h4M16 12h4"></path></svg></button>`);
65634
+ var root_16 = /* @__PURE__ */ from_html(`<div class="absolute z-40 flex items-center gap-0.5 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Duplicate" aria-label="Duplicate"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg></button> <!> <!> <div class="w-px h-5 bg-gray-200 mx-0.5"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-red-50 text-gray-400 hover:text-red-600" title="Delete" aria-label="Delete"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2m3 0v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6h14"></path></svg></button></div>`);
65635
+ var root_19 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-blue-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to add wall segment · Double-click to finish · C to close loop ·
65109
65636
  Esc to cancel</div>`);
65110
- var root_21 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-purple-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
65111
- var root_22 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-red-600 text-white px-3 py-1 rounded-full text-xs shadow">Right-click two points to measure · M to exit · Esc to cancel</div>`);
65112
- var root_23 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-emerald-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to place text label · Esc to cancel</div>`);
65113
- var root_24 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-indigo-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
65114
- var root_2$4 = /* @__PURE__ */ from_html(`<!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <div class="absolute bottom-3 left-3 z-20 flex items-center gap-1 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom Out (−)" aria-label="Zoom out">−</button> <button class="min-w-[3.5rem] h-7 flex items-center justify-center rounded hover:bg-gray-100 text-xs font-medium text-gray-600 hover:text-gray-800 tabular-nums" title="Reset to 100%" aria-label="Zoom to 100%"> </button> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom In (+)" aria-label="Zoom in">+</button> <div class="w-px h-5 bg-gray-200"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700 text-sm" title="Zoom to Fit (F)" aria-label="Zoom to fit">⊞</button></div> <!>`, 1);
65115
- var root$1 = /* @__PURE__ */ from_html(`<div class="w-full h-full relative overflow-hidden" role="application"><div class="w-full h-full"><canvas aria-label="Floor plan editor canvas"></canvas></div> <!> <!></div>`);
65637
+ var root_20 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-purple-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
65638
+ var root_21 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-red-600 text-white px-3 py-1 rounded-full text-xs shadow">Right-click two points to measure · M to exit · Esc to cancel</div>`);
65639
+ var root_22 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-emerald-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to place text label · Esc to cancel</div>`);
65640
+ var root_23 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-indigo-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
65641
+ var root_1$4 = /* @__PURE__ */ from_html(`<!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <div class="absolute bottom-3 left-3 z-20 flex items-center gap-1 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom Out (−)" aria-label="Zoom out">−</button> <button class="min-w-[3.5rem] h-7 flex items-center justify-center rounded hover:bg-gray-100 text-xs font-medium text-gray-600 hover:text-gray-800 tabular-nums" title="Reset to 100%" aria-label="Zoom to 100%"> </button> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom In (+)" aria-label="Zoom in">+</button> <div class="w-px h-5 bg-gray-200"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700 text-sm" title="Zoom to Fit (F)" aria-label="Zoom to fit">⊞</button></div> <!>`, 1);
65642
+ var root$1 = /* @__PURE__ */ from_html(`<div class="w-full h-full relative overflow-hidden" role="application"><div class="w-full h-full"><canvas aria-label="Floor plan editor canvas"></canvas></div> <!></div>`);
65116
65643
  function FloorPlanCanvas($$anchor, $$props) {
65117
65644
  push($$props, true);
65118
65645
  const $panMode = () => store_get(panMode, "$panMode", $$stores);
65119
65646
  const $projectSettings = () => store_get(projectSettings, "$projectSettings", $$stores);
65120
65647
  const [$$stores, $$cleanup] = setup_stores();
65121
- let selectedCameraSerial = prop($$props, "selectedCameraSerial", 3, null), showCameraCones = prop($$props, "showCameraCones", 3, false), showCameraLabels = prop($$props, "showCameraLabels", 3, true), cameraHeatmapMatrix = prop($$props, "cameraHeatmapMatrix", 19, () => []), cameraThumbnail = prop($$props, "cameraThumbnail", 3, ""), canvasBackground = prop($$props, "canvasBackground", 3, "#2E353F"), floorPlateBackground = prop($$props, "floorPlateBackground", 3, "#ffffff");
65648
+ let heatmapColorScale = prop($$props, "heatmapColorScale", 3, void 0), selectedCameraSerial = prop($$props, "selectedCameraSerial", 3, null), showCameraCones = prop($$props, "showCameraCones", 3, false), showCameraLabels = prop($$props, "showCameraLabels", 3, true), cameraHeatmapMatrix = prop($$props, "cameraHeatmapMatrix", 19, () => []), cameraThumbnail = prop($$props, "cameraThumbnail", 3, ""), canvasBackground = prop($$props, "canvasBackground", 3, "#2E353F"), floorPlateBackground = prop($$props, "floorPlateBackground", 3, "#ffffff");
65122
65649
  let canvas;
65123
65650
  let ctx;
65124
65651
  let width = /* @__PURE__ */ state(800);
@@ -65189,6 +65716,15 @@ function FloorPlanCanvas($$anchor, $$props) {
65189
65716
  let annotationStart = /* @__PURE__ */ state(null);
65190
65717
  let selectedAnnotationId = /* @__PURE__ */ state(null);
65191
65718
  let textAnnotationMode = /* @__PURE__ */ state(false);
65719
+ let currentZoneShape = /* @__PURE__ */ state("rectangle");
65720
+ let selectedZoneId = /* @__PURE__ */ state(null);
65721
+ let zonePolyDraft = /* @__PURE__ */ state(proxy([]));
65722
+ let zoneRectDragStart = /* @__PURE__ */ state(null);
65723
+ let zoneRectDragCurrent = /* @__PURE__ */ state(null);
65724
+ let draggingZoneId = /* @__PURE__ */ state(null);
65725
+ let draggingZoneVertex = /* @__PURE__ */ state(null);
65726
+ let zoneDragLast = /* @__PURE__ */ state(null);
65727
+ let zoneCursor = /* @__PURE__ */ state(null);
65192
65728
  let editingTextAnnotationId = /* @__PURE__ */ state(null);
65193
65729
  let editingTextAnnotationPos = /* @__PURE__ */ state(proxy({
65194
65730
  x: 0,
@@ -65220,9 +65756,9 @@ function FloorPlanCanvas($$anchor, $$props) {
65220
65756
  cameraThumbnail();
65221
65757
  canvasBackground();
65222
65758
  floorPlateBackground();
65223
- $$props.projectName;
65224
65759
  $$props.heatmapEnabled;
65225
65760
  $$props.heatmapMatrix;
65761
+ heatmapColorScale();
65226
65762
  markDirty();
65227
65763
  });
65228
65764
  let layerVis = /* @__PURE__ */ state(proxy({
@@ -65234,7 +65770,8 @@ function FloorPlanCanvas($$anchor, $$props) {
65234
65770
  columns: true,
65235
65771
  guides: true,
65236
65772
  measurements: true,
65237
- annotations: true
65773
+ annotations: true,
65774
+ zones: true
65238
65775
  }));
65239
65776
  let showFurniture = /* @__PURE__ */ user_derived(() => get(layerVis).furniture);
65240
65777
  user_effect(() => {
@@ -66109,7 +66646,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66109
66646
  var _$$props$heatmapMatri, _$$props$heatmapMatri2;
66110
66647
  const floor = get(currentFloor);
66111
66648
  if (!floor || !$$props.heatmapEnabled || !((_$$props$heatmapMatri = $$props.heatmapMatrix) === null || _$$props$heatmapMatri === void 0 ? void 0 : _$$props$heatmapMatri.length)) return;
66112
- drawFloorHeatmap(getCS(), floor, (_$$props$heatmapMatri2 = $$props.heatmapMatrix) !== null && _$$props$heatmapMatri2 !== void 0 ? _$$props$heatmapMatri2 : [], get(detectedRooms));
66649
+ drawFloorHeatmap(getCS(), floor, (_$$props$heatmapMatri2 = $$props.heatmapMatrix) !== null && _$$props$heatmapMatri2 !== void 0 ? _$$props$heatmapMatri2 : [], get(detectedRooms), heatmapColorScale());
66113
66650
  }
66114
66651
  function getFloorWallBounds(floor = get(currentFloor)) {
66115
66652
  var _floor$walls;
@@ -66151,6 +66688,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66151
66688
  return "width: 100%; height: 100%";
66152
66689
  }
66153
66690
  function draw() {
66691
+ var _floor$zones;
66154
66692
  if (!ctx) return;
66155
66693
  if (!canvasDirty) {
66156
66694
  requestAnimationFrame(draw);
@@ -66173,7 +66711,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66173
66711
  else zoomToFit();
66174
66712
  needsFitToCanvas = false;
66175
66713
  }
66176
- if (get(wallStart) || get(draggingFurnitureId) || get(draggingDoorId) || get(draggingWindowId) || get(draggingStairId) || get(draggingColumnId) || get(draggingWallEndpoint) || get(draggingWallParallel) || get(draggingCurveHandle) || get(draggingHandle) || get(draggingMultiSelect) || get(draggingRoomId) || get(draggingRoomLabelId) || get(draggingTextAnnotationId) || get(draggingGuideId) || get(measuring) || get(annotating) || get(currentPlacingId) || get(isPlacingStair) || get(isPlacingColumn) || get(marqueeStart) || get(isPanning)) canvasDirty = true;
66714
+ if (get(wallStart) || get(draggingFurnitureId) || get(draggingDoorId) || get(draggingWindowId) || get(draggingStairId) || get(draggingColumnId) || get(draggingWallEndpoint) || get(draggingWallParallel) || get(draggingCurveHandle) || get(draggingHandle) || get(draggingMultiSelect) || get(draggingRoomId) || get(draggingRoomLabelId) || get(draggingTextAnnotationId) || get(draggingGuideId) || get(draggingZoneId) || get(zoneRectDragStart) || get(zonePolyDraft).length > 0 || get(measuring) || get(annotating) || get(currentPlacingId) || get(isPlacingStair) || get(isPlacingColumn) || get(marqueeStart) || get(isPanning)) canvasDirty = true;
66177
66715
  updateDetectedRooms();
66178
66716
  const selId = get(currentSelectedId);
66179
66717
  const multiIds = get(currentSelectedIds);
@@ -66806,6 +67344,17 @@ function FloorPlanCanvas($$anchor, $$props) {
66806
67344
  ctx.restore();
66807
67345
  }
66808
67346
  drawFloorHeatmapLayer();
67347
+ if (get(layerVis).zones && (floor === null || floor === void 0 || (_floor$zones = floor.zones) === null || _floor$zones === void 0 ? void 0 : _floor$zones.length)) {
67348
+ var _$$get6;
67349
+ const zoneSel = (_$$get6 = get(selectedZoneId)) !== null && _$$get6 !== void 0 ? _$$get6 : floor.zones.some((z) => z.id === get(currentSelectedId)) ? get(currentSelectedId) : null;
67350
+ drawZones(getCS(), floor, zoneSel);
67351
+ }
67352
+ if (get(currentTool) === "zone") {
67353
+ var _floor$zones$length, _floor$zones2;
67354
+ const draftColor = nextZoneColor((_floor$zones$length = floor === null || floor === void 0 || (_floor$zones2 = floor.zones) === null || _floor$zones2 === void 0 ? void 0 : _floor$zones2.length) !== null && _floor$zones$length !== void 0 ? _floor$zones$length : 0);
67355
+ if (get(zoneRectDragStart) && get(zoneRectDragCurrent)) drawZoneDraft(getCS(), rectPoints(get(zoneRectDragStart).x, get(zoneRectDragStart).y, get(zoneRectDragCurrent).x, get(zoneRectDragCurrent).y), draftColor, true);
67356
+ else if (get(zonePolyDraft).length || get(zoneCursor)) drawZoneDraft(getCS(), get(zonePolyDraft), draftColor, false, get(zoneCursor));
67357
+ }
66809
67358
  drawMinimap$1();
66810
67359
  requestAnimationFrame(draw);
66811
67360
  }
@@ -66846,6 +67395,18 @@ function FloorPlanCanvas($$anchor, $$props) {
66846
67395
  set(currentTool, t, true);
66847
67396
  set(textAnnotationMode, t === "text");
66848
67397
  if (t !== "text") set(editingTextAnnotationId, null);
67398
+ if (t !== "zone") {
67399
+ set(zonePolyDraft, [], true);
67400
+ set(zoneRectDragStart, null);
67401
+ set(zoneRectDragCurrent, null);
67402
+ }
67403
+ markDirty();
67404
+ });
67405
+ const unsubZoneShape = placingZoneShape.subscribe((s) => {
67406
+ set(currentZoneShape, s, true);
67407
+ set(zonePolyDraft, [], true);
67408
+ set(zoneRectDragStart, null);
67409
+ set(zoneRectDragCurrent, null);
66849
67410
  markDirty();
66850
67411
  });
66851
67412
  const unsub7 = detectedRoomsStore.subscribe((rooms) => {
@@ -66949,6 +67510,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66949
67510
  unsub4();
66950
67511
  unsub5();
66951
67512
  unsub6();
67513
+ unsubZoneShape();
66952
67514
  unsub7();
66953
67515
  unsub8();
66954
67516
  unsub9();
@@ -67131,7 +67693,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67131
67693
  return findRoomAt(p, get(detectedRooms), get(currentFloor).walls);
67132
67694
  }
67133
67695
  function onMouseDown(e) {
67134
- var _$$get6;
67696
+ var _$$get7, _$$get8;
67135
67697
  if ($$props.viewOnly) return;
67136
67698
  markDirty();
67137
67699
  if (e.button === 1 || e.button === 0 && (get(spaceDown) || $panMode() || e.shiftKey && get(currentTool) === "select")) {
@@ -67212,7 +67774,61 @@ function FloorPlanCanvas($$anchor, $$props) {
67212
67774
  placingStair.set(false);
67213
67775
  return;
67214
67776
  }
67215
- if (tool === "select" && ((_$$get6 = get(currentFloor)) === null || _$$get6 === void 0 ? void 0 : _$$get6.guides)) {
67777
+ if (tool === "zone") {
67778
+ const snapped = {
67779
+ x: snap(wp.x),
67780
+ y: snap(wp.y)
67781
+ };
67782
+ if (get(currentZoneShape) === "rectangle") {
67783
+ set(zoneRectDragStart, snapped, true);
67784
+ set(zoneRectDragCurrent, snapped, true);
67785
+ return;
67786
+ }
67787
+ if (get(currentZoneShape) === "triangle") {
67788
+ const id = addZone("triangle", trianglePoints(snapped));
67789
+ set(selectedZoneId, id, true);
67790
+ selectedElementId.set(id);
67791
+ selectedTool.set("select");
67792
+ return;
67793
+ }
67794
+ if (get(zonePolyDraft).length >= 3 && isNearPoint(snapped, get(zonePolyDraft)[0], 15 / get(zoom))) {
67795
+ const id = addZone("polygon", get(zonePolyDraft));
67796
+ set(zonePolyDraft, [], true);
67797
+ set(zoneCursor, null);
67798
+ set(selectedZoneId, id, true);
67799
+ selectedElementId.set(id);
67800
+ selectedTool.set("select");
67801
+ return;
67802
+ }
67803
+ set(zonePolyDraft, [...get(zonePolyDraft), snapped], true);
67804
+ return;
67805
+ }
67806
+ if (tool === "select" && ((_$$get7 = get(currentFloor)) === null || _$$get7 === void 0 || (_$$get7 = _$$get7.zones) === null || _$$get7 === void 0 ? void 0 : _$$get7.length) && get(layerVis).zones) {
67807
+ const zHit = findZoneAt(wp, get(currentFloor).zones, get(zoom));
67808
+ if (zHit) {
67809
+ set(selectedZoneId, zHit.id, true);
67810
+ selectedElementId.set(zHit.id);
67811
+ set(selectedTextAnnotationId, null);
67812
+ set(selectedAnnotationId, null);
67813
+ set(selectedMeasurementId, null);
67814
+ const vIdx = findZoneVertexAt(wp, zHit, get(zoom));
67815
+ beginUndoGroup();
67816
+ if (vIdx >= 0) {
67817
+ set(draggingZoneId, zHit.id, true);
67818
+ set(draggingZoneVertex, vIdx, true);
67819
+ } else {
67820
+ set(draggingZoneId, zHit.id, true);
67821
+ set(draggingZoneVertex, null);
67822
+ set(zoneDragLast, {
67823
+ x: wp.x,
67824
+ y: wp.y
67825
+ }, true);
67826
+ }
67827
+ return;
67828
+ }
67829
+ set(selectedZoneId, null);
67830
+ }
67831
+ if (tool === "select" && ((_$$get8 = get(currentFloor)) === null || _$$get8 === void 0 ? void 0 : _$$get8.guides)) {
67216
67832
  const GUIDE_HIT = 6 / get(zoom);
67217
67833
  for (const g of get(currentFloor).guides) {
67218
67834
  if (g.orientation === "horizontal" && Math.abs(wp.y - g.position) < GUIDE_HIT) {
@@ -67281,9 +67897,9 @@ function FloorPlanCanvas($$anchor, $$props) {
67281
67897
  const dist = Math.hypot(newPts[1].x - newPts[0].x, newPts[1].y - newPts[0].y);
67282
67898
  const realDist = prompt("Enter the real-world distance between these two points (in cm):");
67283
67899
  if (realDist && Number(realDist) > 0) {
67284
- var _$$get7;
67900
+ var _$$get9;
67285
67901
  const pixelsPerCm = dist / Number(realDist);
67286
- if ((_$$get7 = get(currentFloor)) === null || _$$get7 === void 0 ? void 0 : _$$get7.backgroundImage) updateBackgroundImage({ scale: get(currentFloor).backgroundImage.scale * (1 / pixelsPerCm) });
67902
+ if ((_$$get9 = get(currentFloor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.backgroundImage) updateBackgroundImage({ scale: get(currentFloor).backgroundImage.scale * (1 / pixelsPerCm) });
67287
67903
  }
67288
67904
  calibrationMode.set(false);
67289
67905
  return [];
@@ -67633,6 +68249,15 @@ function FloorPlanCanvas($$anchor, $$props) {
67633
68249
  return;
67634
68250
  }
67635
68251
  }
68252
+ if (get(currentTool) === "zone" && get(currentZoneShape) === "polygon" && get(zonePolyDraft).length >= 3) {
68253
+ const id = addZone("polygon", get(zonePolyDraft));
68254
+ set(zonePolyDraft, [], true);
68255
+ set(zoneCursor, null);
68256
+ set(selectedZoneId, id, true);
68257
+ selectedElementId.set(id);
68258
+ selectedTool.set("select");
68259
+ return;
68260
+ }
67636
68261
  if (get(currentTool) === "select") {
67637
68262
  const wp = screenToWorld(sx, sy);
67638
68263
  const wall = findWallAt$1(wp);
@@ -67653,11 +68278,47 @@ function FloorPlanCanvas($$anchor, $$props) {
67653
68278
  }
67654
68279
  }
67655
68280
  function onMouseMove(e) {
67656
- var _$$get8, _$$get9, _$$get10, _$$get11;
68281
+ var _$$get10, _$$get11, _$$get12, _$$get13, _$$get14;
67657
68282
  if ($$props.viewOnly) return;
67658
68283
  markDirty();
67659
68284
  const rect = canvas.getBoundingClientRect();
67660
68285
  set(mousePos, screenToWorld(e.clientX - rect.left, e.clientY - rect.top), true);
68286
+ if (get(zoneRectDragStart) && get(currentTool) === "zone") {
68287
+ set(zoneRectDragCurrent, {
68288
+ x: snap(get(mousePos).x),
68289
+ y: snap(get(mousePos).y)
68290
+ }, true);
68291
+ return;
68292
+ }
68293
+ if (get(currentTool) === "zone" && get(currentZoneShape) === "polygon") set(zoneCursor, {
68294
+ x: snap(get(mousePos).x),
68295
+ y: snap(get(mousePos).y)
68296
+ }, true);
68297
+ if (get(draggingZoneId) && ((_$$get10 = get(currentFloor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.zones)) {
68298
+ const z = get(currentFloor).zones.find((z) => z.id === get(draggingZoneId));
68299
+ if (z) {
68300
+ const snapped = {
68301
+ x: snap(get(mousePos).x),
68302
+ y: snap(get(mousePos).y)
68303
+ };
68304
+ if (get(draggingZoneVertex) != null) if (z.shape === "rectangle" && z.points.length === 4) moveZonePoints(z.id, resizeRectCorner(z.points, get(draggingZoneVertex), snapped));
68305
+ else {
68306
+ const next = z.points.map((p) => ({ ...p }));
68307
+ next[get(draggingZoneVertex)] = snapped;
68308
+ moveZonePoints(z.id, next);
68309
+ }
68310
+ else if (get(zoneDragLast)) {
68311
+ const dx = get(mousePos).x - get(zoneDragLast).x;
68312
+ const dy = get(mousePos).y - get(zoneDragLast).y;
68313
+ set(zoneDragLast, {
68314
+ x: get(mousePos).x,
68315
+ y: get(mousePos).y
68316
+ }, true);
68317
+ moveZonePoints(z.id, translatePoints(z.points, dx, dy));
68318
+ }
68319
+ }
68320
+ return;
68321
+ }
67661
68322
  if (get(draggingRoomLabelId)) {
67662
68323
  const dx = get(mousePos).x - roomLabelDragStart.x;
67663
68324
  const dy = get(mousePos).y - roomLabelDragStart.y;
@@ -67671,7 +68332,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67671
68332
  } : r));
67672
68333
  return;
67673
68334
  }
67674
- if (get(draggingGuideId) && ((_$$get8 = get(currentFloor)) === null || _$$get8 === void 0 ? void 0 : _$$get8.guides)) {
68335
+ if (get(draggingGuideId) && ((_$$get11 = get(currentFloor)) === null || _$$get11 === void 0 ? void 0 : _$$get11.guides)) {
67675
68336
  const g = get(currentFloor).guides.find((g) => g.id === get(draggingGuideId));
67676
68337
  if (g) {
67677
68338
  const newPos = g.orientation === "horizontal" ? get(mousePos).y : get(mousePos).x;
@@ -67827,7 +68488,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67827
68488
  }
67828
68489
  }
67829
68490
  }
67830
- if (get(draggingTextAnnotationId) && ((_$$get9 = get(currentFloor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.textAnnotations)) {
68491
+ if (get(draggingTextAnnotationId) && ((_$$get12 = get(currentFloor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.textAnnotations)) {
67831
68492
  const basePos = {
67832
68493
  x: get(mousePos).x - textAnnotationDragOffset.x,
67833
68494
  y: get(mousePos).y - textAnnotationDragOffset.y
@@ -67844,7 +68505,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67844
68505
  }, true);
67845
68506
  }
67846
68507
  }
67847
- if (get(draggingColumnId) && ((_$$get10 = get(currentFloor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.columns)) {
68508
+ if (get(draggingColumnId) && ((_$$get13 = get(currentFloor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.columns)) {
67848
68509
  const basePos = {
67849
68510
  x: get(mousePos).x - columnDragOffset.x,
67850
68511
  y: get(mousePos).y - columnDragOffset.y
@@ -67854,7 +68515,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67854
68515
  y: snap(basePos.y)
67855
68516
  });
67856
68517
  }
67857
- if (get(draggingStairId) && ((_$$get11 = get(currentFloor)) === null || _$$get11 === void 0 ? void 0 : _$$get11.stairs)) {
68518
+ if (get(draggingStairId) && ((_$$get14 = get(currentFloor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.stairs)) {
67858
68519
  const basePos = {
67859
68520
  x: get(mousePos).x - stairDragOffset.x,
67860
68521
  y: get(mousePos).y - stairDragOffset.y
@@ -67865,12 +68526,12 @@ function FloorPlanCanvas($$anchor, $$props) {
67865
68526
  });
67866
68527
  }
67867
68528
  if (get(draggingFurnitureId)) {
67868
- var _$$get12;
68529
+ var _$$get15;
67869
68530
  const basePos = {
67870
68531
  x: get(mousePos).x - dragOffset.x,
67871
68532
  y: get(mousePos).y - dragOffset.y
67872
68533
  };
67873
- const fi = (_$$get12 = get(currentFloor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.furniture.find((f) => f.id === get(draggingFurnitureId));
68534
+ const fi = (_$$get15 = get(currentFloor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.furniture.find((f) => f.id === get(draggingFurnitureId));
67874
68535
  if (fi) {
67875
68536
  const wallSnap = snapFurnitureToWall(basePos, fi.catalogId, fi.rotation);
67876
68537
  if (wallSnap) {
@@ -67883,13 +68544,13 @@ function FloorPlanCanvas($$anchor, $$props) {
67883
68544
  wallAngle: wallSnap.wallAngle
67884
68545
  }, true);
67885
68546
  } else {
67886
- var _$$get13;
68547
+ var _$$get16;
67887
68548
  const snapped = {
67888
68549
  x: snap(basePos.x),
67889
68550
  y: snap(basePos.y)
67890
68551
  };
67891
68552
  const GUIDE_SNAP = 10;
67892
- if ((_$$get13 = get(currentFloor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.guides) for (const g of get(currentFloor).guides) {
68553
+ if ((_$$get16 = get(currentFloor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.guides) for (const g of get(currentFloor).guides) {
67893
68554
  if (g.orientation === "horizontal" && Math.abs(snapped.y - g.position) < GUIDE_SNAP) snapped.y = g.position;
67894
68555
  if (g.orientation === "vertical" && Math.abs(snapped.x - g.position) < GUIDE_SNAP) snapped.x = g.position;
67895
68556
  }
@@ -67939,6 +68600,26 @@ function FloorPlanCanvas($$anchor, $$props) {
67939
68600
  markDirty();
67940
68601
  set(isPanning, false);
67941
68602
  set(draggingGuideId, null);
68603
+ if (get(zoneRectDragStart) && get(zoneRectDragCurrent) && get(currentTool) === "zone") {
68604
+ const pts = rectPoints(get(zoneRectDragStart).x, get(zoneRectDragStart).y, get(zoneRectDragCurrent).x, get(zoneRectDragCurrent).y);
68605
+ const w = Math.abs(get(zoneRectDragCurrent).x - get(zoneRectDragStart).x);
68606
+ const h = Math.abs(get(zoneRectDragCurrent).y - get(zoneRectDragStart).y);
68607
+ set(zoneRectDragStart, null);
68608
+ set(zoneRectDragCurrent, null);
68609
+ if (w > 5 && h > 5) {
68610
+ const id = addZone("rectangle", pts);
68611
+ set(selectedZoneId, id, true);
68612
+ selectedElementId.set(id);
68613
+ selectedTool.set("select");
68614
+ }
68615
+ return;
68616
+ }
68617
+ if (get(draggingZoneId)) {
68618
+ endUndoGroup();
68619
+ set(draggingZoneId, null);
68620
+ set(draggingZoneVertex, null);
68621
+ set(zoneDragLast, null);
68622
+ }
67942
68623
  if (get(draggingRoomLabelId)) {
67943
68624
  const dx = get(mousePos).x - roomLabelDragStart.x;
67944
68625
  const dy = get(mousePos).y - roomLabelDragStart.y;
@@ -68107,6 +68788,20 @@ function FloorPlanCanvas($$anchor, $$props) {
68107
68788
  set(annotationStart, null);
68108
68789
  set(marqueeStart, null);
68109
68790
  set(marqueeEnd, null);
68791
+ set(zonePolyDraft, [], true);
68792
+ set(zoneCursor, null);
68793
+ set(zoneRectDragStart, null);
68794
+ set(zoneRectDragCurrent, null);
68795
+ }
68796
+ if (e.key === "Enter" && get(currentTool) === "zone" && get(currentZoneShape) === "polygon" && get(zonePolyDraft).length >= 3) {
68797
+ const id = addZone("polygon", get(zonePolyDraft));
68798
+ set(zonePolyDraft, [], true);
68799
+ set(zoneCursor, null);
68800
+ set(selectedZoneId, id, true);
68801
+ selectedElementId.set(id);
68802
+ selectedTool.set("select");
68803
+ e.preventDefault();
68804
+ return;
68110
68805
  }
68111
68806
  if ((e.ctrlKey || e.metaKey) && e.key === "a" && !e.shiftKey) {
68112
68807
  e.preventDefault();
@@ -68585,8 +69280,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68585
69280
  }
68586
69281
  }
68587
69282
  let cursorStyle = /* @__PURE__ */ user_derived(() => {
68588
- var _$$get14;
68589
- return get(spaceDown) || get(isPanning) || $panMode() || get(shiftDown) && get(currentTool) === "select" ? "grab" : get(draggingFurnitureId) ? "move" : get(draggingRoomId) ? "move" : get(draggingMultiSelect) ? "move" : get(draggingDoorId) ? "move" : get(draggingWindowId) ? "move" : get(draggingStairId) ? "move" : get(draggingColumnId) ? "move" : get(draggingTextAnnotationId) ? "move" : get(draggingWallParallel) ? "move" : get(draggingCurveHandle) ? "crosshair" : get(draggingWallEndpoint) ? "crosshair" : get(draggingHandle) === "rotate" ? "grabbing" : get(draggingHandle) === "resize-t" || get(draggingHandle) === "resize-b" ? "ns-resize" : get(draggingHandle) === "resize-l" || get(draggingHandle) === "resize-r" ? "ew-resize" : ((_$$get14 = get(draggingHandle)) === null || _$$get14 === void 0 ? void 0 : _$$get14.startsWith("resize")) ? "nwse-resize" : get(currentTool) === "text" ? "text" : get(currentTool) === "select" ? "default" : get(currentTool) === "furniture" ? "copy" : get(currentTool) === "door" || get(currentTool) === "window" ? get(placementPreview) ? "crosshair" : "not-allowed" : "crosshair";
69283
+ var _$$get17;
69284
+ return get(spaceDown) || get(isPanning) || $panMode() || get(shiftDown) && get(currentTool) === "select" ? "grab" : get(draggingFurnitureId) ? "move" : get(draggingRoomId) ? "move" : get(draggingMultiSelect) ? "move" : get(draggingDoorId) ? "move" : get(draggingWindowId) ? "move" : get(draggingStairId) ? "move" : get(draggingColumnId) ? "move" : get(draggingTextAnnotationId) ? "move" : get(draggingZoneId) ? "move" : get(draggingWallParallel) ? "move" : get(draggingCurveHandle) ? "crosshair" : get(draggingWallEndpoint) ? "crosshair" : get(draggingHandle) === "rotate" ? "grabbing" : get(draggingHandle) === "resize-t" || get(draggingHandle) === "resize-b" ? "ns-resize" : get(draggingHandle) === "resize-l" || get(draggingHandle) === "resize-r" ? "ew-resize" : ((_$$get17 = get(draggingHandle)) === null || _$$get17 === void 0 ? void 0 : _$$get17.startsWith("resize")) ? "nwse-resize" : get(currentTool) === "text" ? "text" : get(currentTool) === "select" ? "default" : get(currentTool) === "furniture" ? "copy" : get(currentTool) === "door" || get(currentTool) === "window" ? get(placementPreview) ? "crosshair" : "not-allowed" : "crosshair";
68590
69285
  });
68591
69286
  var div = root$1();
68592
69287
  event("keydown", $window, onKeyDown);
@@ -68598,22 +69293,11 @@ function FloorPlanCanvas($$anchor, $$props) {
68598
69293
  reset(div_1);
68599
69294
  bind_this(div_1, ($$value) => canvasFrame = $$value, () => canvasFrame);
68600
69295
  var node = sibling(div_1, 2);
68601
- var consequent = ($$anchor) => {
68602
- var div_2 = root_1$4();
68603
- var text_1 = child(div_2, true);
68604
- reset(div_2);
68605
- template_effect(() => set_text(text_1, $$props.projectName));
68606
- append($$anchor, div_2);
68607
- };
68608
- if_block(node, ($$render) => {
68609
- if ($$props.viewOnly && $$props.projectName) $$render(consequent);
68610
- });
68611
- var node_1 = sibling(node, 2);
68612
- var consequent_22 = ($$anchor) => {
68613
- var fragment = root_2$4();
68614
- var node_2 = first_child(fragment);
68615
- var consequent_1 = ($$anchor) => {
68616
- var input = root_3$3();
69296
+ var consequent_21 = ($$anchor) => {
69297
+ var fragment = root_1$4();
69298
+ var node_1 = first_child(fragment);
69299
+ var consequent = ($$anchor) => {
69300
+ var input = root_2$4();
68617
69301
  remove_input_defaults(input);
68618
69302
  autofocus(input, true);
68619
69303
  template_effect(() => {
@@ -68646,12 +69330,12 @@ function FloorPlanCanvas($$anchor, $$props) {
68646
69330
  });
68647
69331
  append($$anchor, input);
68648
69332
  };
68649
- if_block(node_2, ($$render) => {
68650
- if (get(editingRoomId)) $$render(consequent_1);
69333
+ if_block(node_1, ($$render) => {
69334
+ if (get(editingRoomId)) $$render(consequent);
68651
69335
  });
68652
- var node_3 = sibling(node_2, 2);
68653
- var consequent_2 = ($$anchor) => {
68654
- var input_1 = root_4$2();
69336
+ var node_2 = sibling(node_1, 2);
69337
+ var consequent_1 = ($$anchor) => {
69338
+ var input_1 = root_3$3();
68655
69339
  remove_input_defaults(input_1);
68656
69340
  autofocus(input_1, true);
68657
69341
  template_effect(() => {
@@ -68673,8 +69357,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68673
69357
  }
68674
69358
  set(editingTextAnnotationId, null);
68675
69359
  } else if (e.key === "Escape") {
68676
- var _$$get15;
68677
- if ((_$$get15 = get(currentFloor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.textAnnotations) {
69360
+ var _$$get18;
69361
+ if ((_$$get18 = get(currentFloor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.textAnnotations) {
68678
69362
  const ta = get(currentFloor).textAnnotations.find((t) => t.id === get(editingTextAnnotationId));
68679
69363
  if (ta && ta.text === "Text" && !get(editingTextAnnotationValue).trim()) {
68680
69364
  removeTextAnnotation(get(editingTextAnnotationId));
@@ -68698,151 +69382,151 @@ function FloorPlanCanvas($$anchor, $$props) {
68698
69382
  });
68699
69383
  append($$anchor, input_1);
68700
69384
  };
69385
+ if_block(node_2, ($$render) => {
69386
+ if (get(editingTextAnnotationId)) $$render(consequent_1);
69387
+ });
69388
+ var node_3 = sibling(node_2, 2);
69389
+ var consequent_2 = ($$anchor) => {
69390
+ append($$anchor, root_4$2());
69391
+ };
68701
69392
  if_block(node_3, ($$render) => {
68702
- if (get(editingTextAnnotationId)) $$render(consequent_2);
69393
+ if (get(currentFloor) && get(currentFloor).walls.length === 0 && get(currentFloor).furniture.length === 0 && get(currentFloor).doors.length === 0 && !$$props.viewOnly) $$render(consequent_2);
68703
69394
  });
68704
69395
  var node_4 = sibling(node_3, 2);
68705
69396
  var consequent_3 = ($$anchor) => {
68706
- append($$anchor, root_5());
68707
- };
68708
- if_block(node_4, ($$render) => {
68709
- if (get(currentFloor) && get(currentFloor).walls.length === 0 && get(currentFloor).furniture.length === 0 && get(currentFloor).doors.length === 0 && !$$props.viewOnly) $$render(consequent_3);
68710
- });
68711
- var node_5 = sibling(node_4, 2);
68712
- var consequent_4 = ($$anchor) => {
68713
- var canvas_2 = root_6();
69397
+ var canvas_2 = root_5();
68714
69398
  bind_this(canvas_2, ($$value) => minimapCanvas = $$value, () => minimapCanvas);
68715
69399
  delegated("click", canvas_2, onMinimapClick);
68716
69400
  append($$anchor, canvas_2);
68717
69401
  };
68718
- if_block(node_5, ($$render) => {
68719
- if (!$$props.viewOnly && get(showMinimap) && get(currentFloor) && get(currentFloor).walls.length > 0) $$render(consequent_4);
69402
+ if_block(node_4, ($$render) => {
69403
+ if (!$$props.viewOnly && get(showMinimap) && get(currentFloor) && get(currentFloor).walls.length > 0) $$render(consequent_3);
68720
69404
  });
68721
- var node_6 = sibling(node_5, 2);
68722
- var consequent_11 = ($$anchor) => {
68723
- var div_4 = root_7$1();
68724
- var node_7 = child(div_4);
68725
- var consequent_5 = ($$anchor) => {
68726
- var fragment_1 = root_8();
69405
+ var node_5 = sibling(node_4, 2);
69406
+ var consequent_10 = ($$anchor) => {
69407
+ var div_3 = root_6();
69408
+ var node_6 = child(div_3);
69409
+ var consequent_4 = ($$anchor) => {
69410
+ var fragment_1 = root_7$1();
68727
69411
  var span = first_child(fragment_1);
68728
- var text_2 = child(span);
69412
+ var text_1 = child(span);
68729
69413
  reset(span);
68730
69414
  var span_1 = sibling(span, 2);
68731
- var text_3 = child(span_1, true);
69415
+ var text_2 = child(span_1, true);
68732
69416
  reset(span_1);
68733
69417
  next(2);
68734
69418
  template_effect(($0) => {
68735
69419
  var _$$get$length;
68736
- set_text(text_2, `${(_$$get$length = get(detectedRooms).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} room${get(detectedRooms).length !== 1 ? "s" : ""}`);
68737
- set_text(text_3, $0);
69420
+ set_text(text_1, `${(_$$get$length = get(detectedRooms).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} room${get(detectedRooms).length !== 1 ? "s" : ""}`);
69421
+ set_text(text_2, $0);
68738
69422
  }, [() => formatArea(get(detectedRooms).reduce((s, r) => s + r.area, 0), $projectSettings().units)]);
68739
69423
  append($$anchor, fragment_1);
68740
69424
  };
68741
- if_block(node_7, ($$render) => {
68742
- if (get(detectedRooms).length > 0) $$render(consequent_5);
69425
+ if_block(node_6, ($$render) => {
69426
+ if (get(detectedRooms).length > 0) $$render(consequent_4);
68743
69427
  });
68744
- var node_8 = sibling(node_7, 2);
68745
- var consequent_9 = ($$anchor) => {
68746
- var fragment_2 = root_9();
69428
+ var node_7 = sibling(node_6, 2);
69429
+ var consequent_8 = ($$anchor) => {
69430
+ var fragment_2 = root_8();
68747
69431
  var span_2 = first_child(fragment_2);
68748
- var text_4 = child(span_2);
69432
+ var text_3 = child(span_2);
68749
69433
  reset(span_2);
68750
- var node_9 = sibling(span_2, 2);
68751
- var consequent_6 = ($$anchor) => {
68752
- var span_3 = root_10();
68753
- var text_5 = child(span_3);
69434
+ var node_8 = sibling(span_2, 2);
69435
+ var consequent_5 = ($$anchor) => {
69436
+ var span_3 = root_9();
69437
+ var text_4 = child(span_3);
68754
69438
  reset(span_3);
68755
69439
  template_effect(() => {
68756
69440
  var _$$get$doors$length;
68757
- return set_text(text_5, `${(_$$get$doors$length = get(currentFloor).doors.length) !== null && _$$get$doors$length !== void 0 ? _$$get$doors$length : ""} door${get(currentFloor).doors.length !== 1 ? "s" : ""}`);
69441
+ return set_text(text_4, `${(_$$get$doors$length = get(currentFloor).doors.length) !== null && _$$get$doors$length !== void 0 ? _$$get$doors$length : ""} door${get(currentFloor).doors.length !== 1 ? "s" : ""}`);
68758
69442
  });
68759
69443
  append($$anchor, span_3);
68760
69444
  };
68761
- if_block(node_9, ($$render) => {
68762
- if (get(currentFloor).doors.length > 0) $$render(consequent_6);
69445
+ if_block(node_8, ($$render) => {
69446
+ if (get(currentFloor).doors.length > 0) $$render(consequent_5);
68763
69447
  });
68764
- var node_10 = sibling(node_9, 2);
68765
- var consequent_7 = ($$anchor) => {
68766
- var span_4 = root_11();
68767
- var text_6 = child(span_4);
69448
+ var node_9 = sibling(node_8, 2);
69449
+ var consequent_6 = ($$anchor) => {
69450
+ var span_4 = root_10();
69451
+ var text_5 = child(span_4);
68768
69452
  reset(span_4);
68769
69453
  template_effect(() => {
68770
69454
  var _$$get$windows$length;
68771
- return set_text(text_6, `${(_$$get$windows$length = get(currentFloor).windows.length) !== null && _$$get$windows$length !== void 0 ? _$$get$windows$length : ""} window${get(currentFloor).windows.length !== 1 ? "s" : ""}`);
69455
+ return set_text(text_5, `${(_$$get$windows$length = get(currentFloor).windows.length) !== null && _$$get$windows$length !== void 0 ? _$$get$windows$length : ""} window${get(currentFloor).windows.length !== 1 ? "s" : ""}`);
68772
69456
  });
68773
69457
  append($$anchor, span_4);
68774
69458
  };
68775
- if_block(node_10, ($$render) => {
68776
- if (get(currentFloor).windows.length > 0) $$render(consequent_7);
69459
+ if_block(node_9, ($$render) => {
69460
+ if (get(currentFloor).windows.length > 0) $$render(consequent_6);
68777
69461
  });
68778
- var node_11 = sibling(node_10, 2);
68779
- var consequent_8 = ($$anchor) => {
68780
- var span_5 = root_12();
68781
- var text_7 = child(span_5);
69462
+ var node_10 = sibling(node_9, 2);
69463
+ var consequent_7 = ($$anchor) => {
69464
+ var span_5 = root_11();
69465
+ var text_6 = child(span_5);
68782
69466
  reset(span_5);
68783
69467
  template_effect(() => {
68784
69468
  var _$$get$furniture$leng;
68785
- return set_text(text_7, `${(_$$get$furniture$leng = get(currentFloor).furniture.length) !== null && _$$get$furniture$leng !== void 0 ? _$$get$furniture$leng : ""} object${get(currentFloor).furniture.length !== 1 ? "s" : ""}`);
69469
+ return set_text(text_6, `${(_$$get$furniture$leng = get(currentFloor).furniture.length) !== null && _$$get$furniture$leng !== void 0 ? _$$get$furniture$leng : ""} object${get(currentFloor).furniture.length !== 1 ? "s" : ""}`);
68786
69470
  });
68787
69471
  append($$anchor, span_5);
68788
69472
  };
68789
- if_block(node_11, ($$render) => {
68790
- if (get(currentFloor).furniture.length > 0) $$render(consequent_8);
69473
+ if_block(node_10, ($$render) => {
69474
+ if (get(currentFloor).furniture.length > 0) $$render(consequent_7);
68791
69475
  });
68792
69476
  next(2);
68793
69477
  template_effect(() => {
68794
69478
  var _$$get$walls$length;
68795
- return set_text(text_4, `${(_$$get$walls$length = get(currentFloor).walls.length) !== null && _$$get$walls$length !== void 0 ? _$$get$walls$length : ""} wall${get(currentFloor).walls.length !== 1 ? "s" : ""}`);
69479
+ return set_text(text_3, `${(_$$get$walls$length = get(currentFloor).walls.length) !== null && _$$get$walls$length !== void 0 ? _$$get$walls$length : ""} wall${get(currentFloor).walls.length !== 1 ? "s" : ""}`);
68796
69480
  });
68797
69481
  append($$anchor, fragment_2);
68798
69482
  };
68799
- if_block(node_8, ($$render) => {
68800
- if (get(currentFloor)) $$render(consequent_9);
69483
+ if_block(node_7, ($$render) => {
69484
+ if (get(currentFloor)) $$render(consequent_8);
68801
69485
  });
68802
- var node_12 = sibling(node_8, 2);
68803
- var consequent_10 = ($$anchor) => {
68804
- var fragment_3 = root_13();
69486
+ var node_11 = sibling(node_7, 2);
69487
+ var consequent_9 = ($$anchor) => {
69488
+ var fragment_3 = root_12();
68805
69489
  var span_6 = first_child(fragment_3);
68806
- var text_8 = child(span_6);
69490
+ var text_7 = child(span_6);
68807
69491
  reset(span_6);
68808
69492
  next(2);
68809
69493
  template_effect(() => {
68810
69494
  var _$$get$size;
68811
- return set_text(text_8, `${(_$$get$size = get(currentSelectedIds).size) !== null && _$$get$size !== void 0 ? _$$get$size : ""} selected`);
69495
+ return set_text(text_7, `${(_$$get$size = get(currentSelectedIds).size) !== null && _$$get$size !== void 0 ? _$$get$size : ""} selected`);
68812
69496
  });
68813
69497
  append($$anchor, fragment_3);
68814
69498
  };
68815
- if_block(node_12, ($$render) => {
68816
- if (get(currentSelectedIds).size > 1) $$render(consequent_10);
69499
+ if_block(node_11, ($$render) => {
69500
+ if (get(currentSelectedIds).size > 1) $$render(consequent_9);
68817
69501
  });
68818
- var span_7 = sibling(node_12, 2);
68819
- var text_9 = child(span_7);
69502
+ var span_7 = sibling(node_11, 2);
69503
+ var text_8 = child(span_7);
68820
69504
  reset(span_7);
68821
69505
  var button = sibling(span_7, 2);
68822
69506
  var button_1 = sibling(button, 2);
68823
- var text_10 = child(button_1);
69507
+ var text_9 = child(button_1);
68824
69508
  reset(button_1);
68825
69509
  var button_2 = sibling(button_1, 2);
68826
- var text_11 = child(button_2);
69510
+ var text_10 = child(button_2);
68827
69511
  reset(button_2);
68828
69512
  var button_3 = sibling(button_2, 2);
68829
- var text_12 = child(button_3);
69513
+ var text_11 = child(button_3);
68830
69514
  reset(button_3);
68831
69515
  var button_4 = sibling(button_3, 2);
68832
69516
  var button_5 = sibling(button_4, 2);
68833
- var text_13 = child(button_5);
69517
+ var text_12 = child(button_5);
68834
69518
  reset(button_5);
68835
69519
  var button_6 = sibling(button_5, 2);
68836
- var text_14 = child(button_6);
68837
- text_14.nodeValue = "🗺 Map";
69520
+ var text_13 = child(button_6);
69521
+ text_13.nodeValue = "🗺 Map";
68838
69522
  reset(button_6);
68839
- reset(div_4);
69523
+ reset(div_3);
68840
69524
  template_effect(($0) => {
68841
- set_text(text_9, `Zoom: ${$0 !== null && $0 !== void 0 ? $0 : ""}%`);
68842
- set_text(text_10, `${get(showGrid) ? "▦" : "▢"} Grid`);
68843
- set_text(text_11, `${get(currentSnapToGrid) ? "🧲" : "↔"} Snap`);
68844
- set_text(text_12, `${get(showFurniture) ? "🪑" : "👻"} Furniture`);
68845
- set_text(text_13, `${get(showRulers) ? "📏" : "📐"} Rulers`);
69525
+ set_text(text_8, `Zoom: ${$0 !== null && $0 !== void 0 ? $0 : ""}%`);
69526
+ set_text(text_9, `${get(showGrid) ? "▦" : "▢"} Grid`);
69527
+ set_text(text_10, `${get(currentSnapToGrid) ? "🧲" : "↔"} Snap`);
69528
+ set_text(text_11, `${get(showFurniture) ? "🪑" : "👻"} Furniture`);
69529
+ set_text(text_12, `${get(showRulers) ? "📏" : "📐"} Rulers`);
68846
69530
  }, [() => Math.round(get(zoom) * 100)]);
68847
69531
  delegated("click", button, () => zoomToFit());
68848
69532
  delegated("click", button_1, () => set(showGrid, !get(showGrid)));
@@ -68857,38 +69541,39 @@ function FloorPlanCanvas($$anchor, $$props) {
68857
69541
  delegated("click", button_4, () => set(showLayerPanel, !get(showLayerPanel)));
68858
69542
  delegated("click", button_5, () => set(showRulers, !get(showRulers)));
68859
69543
  delegated("click", button_6, () => set(showMinimap, !get(showMinimap)));
68860
- append($$anchor, div_4);
69544
+ append($$anchor, div_3);
68861
69545
  };
68862
- if_block(node_6, ($$render) => {
68863
- if (!$$props.viewOnly) $$render(consequent_11);
69546
+ if_block(node_5, ($$render) => {
69547
+ if (!$$props.viewOnly) $$render(consequent_10);
68864
69548
  });
68865
- var node_13 = sibling(node_6, 2);
68866
- var consequent_12 = ($$anchor) => {
68867
- var div_5 = root_14();
68868
- var node_14 = sibling(child(div_5), 2);
68869
- each(node_14, 16, () => [
69549
+ var node_12 = sibling(node_5, 2);
69550
+ var consequent_11 = ($$anchor) => {
69551
+ var div_4 = root_13();
69552
+ var node_13 = sibling(child(div_4), 2);
69553
+ each(node_13, 16, () => [
68870
69554
  ["walls", "Walls"],
68871
69555
  ["doors", "Doors"],
68872
69556
  ["windows", "Windows"],
68873
69557
  ["furniture", "Furniture"],
68874
69558
  ["stairs", "Stairs"],
68875
69559
  ["columns", "Columns"],
69560
+ ["zones", "Zones"],
68876
69561
  ["guides", "Guides"],
68877
69562
  ["measurements", "Measurements"]
68878
69563
  ], index$1, ($$anchor, $$item) => {
68879
69564
  var $$array = /* @__PURE__ */ user_derived(() => to_array($$item, 2));
68880
69565
  let key = () => get($$array)[0];
68881
69566
  let label = () => get($$array)[1];
68882
- var label_1 = root_15();
69567
+ var label_1 = root_14();
68883
69568
  var input_2 = child(label_1);
68884
69569
  remove_input_defaults(input_2);
68885
69570
  var span_8 = sibling(input_2, 2);
68886
- var text_15 = child(span_8, true);
69571
+ var text_14 = child(span_8, true);
68887
69572
  reset(span_8);
68888
69573
  reset(label_1);
68889
69574
  template_effect(() => {
68890
69575
  set_checked(input_2, get(layerVis)[key()]);
68891
- set_text(text_15, label());
69576
+ set_text(text_14, label());
68892
69577
  });
68893
69578
  delegated("change", input_2, () => layerVisibility.update((v) => ({
68894
69579
  ...v,
@@ -68896,7 +69581,7 @@ function FloorPlanCanvas($$anchor, $$props) {
68896
69581
  })));
68897
69582
  append($$anchor, label_1);
68898
69583
  });
68899
- var label_2 = sibling(node_14, 4);
69584
+ var label_2 = sibling(node_13, 4);
68900
69585
  var input_3 = child(label_2);
68901
69586
  remove_input_defaults(input_3);
68902
69587
  next(2);
@@ -68906,16 +69591,16 @@ function FloorPlanCanvas($$anchor, $$props) {
68906
69591
  remove_input_defaults(input_4);
68907
69592
  next(2);
68908
69593
  reset(label_3);
68909
- reset(div_5);
69594
+ reset(div_4);
68910
69595
  bind_checked(input_3, () => get(showRoomLabels), ($$value) => set(showRoomLabels, $$value));
68911
69596
  bind_checked(input_4, () => get(showDimensions), ($$value) => set(showDimensions, $$value));
68912
- append($$anchor, div_5);
69597
+ append($$anchor, div_4);
68913
69598
  };
68914
- if_block(node_13, ($$render) => {
68915
- if (get(showLayerPanel)) $$render(consequent_12);
69599
+ if_block(node_12, ($$render) => {
69600
+ if (get(showLayerPanel)) $$render(consequent_11);
68916
69601
  });
68917
- var node_15 = sibling(node_13, 2);
68918
- var consequent_16 = ($$anchor) => {
69602
+ var node_14 = sibling(node_12, 2);
69603
+ var consequent_15 = ($$anchor) => {
68919
69604
  const el = /* @__PURE__ */ user_derived(() => (() => {
68920
69605
  const f = get(currentFloor);
68921
69606
  const wall = f.walls.find((w) => w.id === get(currentSelectedId));
@@ -68948,24 +69633,24 @@ function FloorPlanCanvas($$anchor, $$props) {
68948
69633
  return null;
68949
69634
  })());
68950
69635
  var fragment_4 = comment();
68951
- var node_16 = first_child(fragment_4);
68952
- var consequent_15 = ($$anchor) => {
68953
- var div_6 = root_17();
68954
- var button_7 = child(div_6);
68955
- var node_17 = sibling(button_7, 2);
68956
- var consequent_13 = ($$anchor) => {
68957
- var button_8 = root_18();
69636
+ var node_15 = first_child(fragment_4);
69637
+ var consequent_14 = ($$anchor) => {
69638
+ var div_5 = root_16();
69639
+ var button_7 = child(div_5);
69640
+ var node_16 = sibling(button_7, 2);
69641
+ var consequent_12 = ($$anchor) => {
69642
+ var button_8 = root_17();
68958
69643
  delegated("click", button_8, () => {
68959
69644
  if (get(el).door) updateDoor(get(el).door.id, { swingDirection: get(el).door.swingDirection === "left" ? "right" : "left" });
68960
69645
  });
68961
69646
  append($$anchor, button_8);
68962
69647
  };
68963
- if_block(node_17, ($$render) => {
68964
- if (get(el).type === "door" && get(el).door) $$render(consequent_13);
69648
+ if_block(node_16, ($$render) => {
69649
+ if (get(el).type === "door" && get(el).door) $$render(consequent_12);
68965
69650
  });
68966
- var node_18 = sibling(node_17, 2);
68967
- var consequent_14 = ($$anchor) => {
68968
- var button_9 = root_19();
69651
+ var node_17 = sibling(node_16, 2);
69652
+ var consequent_13 = ($$anchor) => {
69653
+ var button_9 = root_18();
68969
69654
  delegated("click", button_9, () => {
68970
69655
  if (get(currentSelectedId)) {
68971
69656
  if (splitWall(get(currentSelectedId), .5)) selectedElementId.set(null);
@@ -68973,14 +69658,14 @@ function FloorPlanCanvas($$anchor, $$props) {
68973
69658
  });
68974
69659
  append($$anchor, button_9);
68975
69660
  };
68976
- if_block(node_18, ($$render) => {
68977
- if (get(el).type === "wall" && get(currentSelectedId) && get(currentSelectedIds).size === 0) $$render(consequent_14);
69661
+ if_block(node_17, ($$render) => {
69662
+ if (get(el).type === "wall" && get(currentSelectedId) && get(currentSelectedIds).size === 0) $$render(consequent_13);
68978
69663
  });
68979
- var button_10 = sibling(node_18, 4);
68980
- reset(div_6);
69664
+ var button_10 = sibling(node_17, 4);
69665
+ reset(div_5);
68981
69666
  template_effect(() => {
68982
69667
  var _$$get$pos$x;
68983
- return set_style(div_6, `left: ${(_$$get$pos$x = get(el).pos.x) !== null && _$$get$pos$x !== void 0 ? _$$get$pos$x : ""}px; top: ${get(el).pos.y - 44}px; transform: translateX(-50%);`);
69668
+ return set_style(div_5, `left: ${(_$$get$pos$x = get(el).pos.x) !== null && _$$get$pos$x !== void 0 ? _$$get$pos$x : ""}px; top: ${get(el).pos.y - 44}px; transform: translateX(-50%);`);
68984
69669
  });
68985
69670
  delegated("click", button_7, () => {
68986
69671
  if (!get(currentSelectedId) || !get(currentFloor)) return;
@@ -69003,72 +69688,72 @@ function FloorPlanCanvas($$anchor, $$props) {
69003
69688
  selectedElementId.set(null);
69004
69689
  }
69005
69690
  });
69006
- append($$anchor, div_6);
69691
+ append($$anchor, div_5);
69007
69692
  };
69008
- if_block(node_16, ($$render) => {
69009
- if (get(el)) $$render(consequent_15);
69693
+ if_block(node_15, ($$render) => {
69694
+ if (get(el)) $$render(consequent_14);
69010
69695
  });
69011
69696
  append($$anchor, fragment_4);
69012
69697
  };
69013
- if_block(node_15, ($$render) => {
69014
- if ((get(currentSelectedId) || get(currentSelectedIds).size > 0) && get(currentFloor) && get(currentTool) === "select") $$render(consequent_16);
69698
+ if_block(node_14, ($$render) => {
69699
+ if ((get(currentSelectedId) || get(currentSelectedIds).size > 0) && get(currentFloor) && get(currentTool) === "select") $$render(consequent_15);
69700
+ });
69701
+ var node_18 = sibling(node_14, 2);
69702
+ var consequent_16 = ($$anchor) => {
69703
+ append($$anchor, root_19());
69704
+ };
69705
+ if_block(node_18, ($$render) => {
69706
+ if (get(currentTool) === "wall" && get(wallStart)) $$render(consequent_16);
69015
69707
  });
69016
- var node_19 = sibling(node_15, 2);
69708
+ var node_19 = sibling(node_18, 2);
69017
69709
  var consequent_17 = ($$anchor) => {
69018
- append($$anchor, root_20());
69710
+ var div_7 = root_20();
69711
+ var text_15 = child(div_7);
69712
+ reset(div_7);
69713
+ template_effect(() => {
69714
+ var _$$get19;
69715
+ return set_text(text_15, `Click to place · Scroll or R to rotate (${(_$$get19 = get(currentPlacingRotation)) !== null && _$$get19 !== void 0 ? _$$get19 : ""}°) · Esc
69716
+ to cancel`);
69717
+ });
69718
+ append($$anchor, div_7);
69019
69719
  };
69020
69720
  if_block(node_19, ($$render) => {
69021
- if (get(currentTool) === "wall" && get(wallStart)) $$render(consequent_17);
69721
+ if (get(currentPlacingId) && get(currentTool) === "furniture") $$render(consequent_17);
69022
69722
  });
69023
69723
  var node_20 = sibling(node_19, 2);
69024
69724
  var consequent_18 = ($$anchor) => {
69025
- var div_8 = root_21();
69026
- var text_16 = child(div_8);
69027
- reset(div_8);
69028
- template_effect(() => {
69029
- var _$$get16;
69030
- return set_text(text_16, `Click to place · Scroll or R to rotate (${(_$$get16 = get(currentPlacingRotation)) !== null && _$$get16 !== void 0 ? _$$get16 : ""}°) · Esc
69031
- to cancel`);
69032
- });
69033
- append($$anchor, div_8);
69725
+ append($$anchor, root_21());
69034
69726
  };
69035
69727
  if_block(node_20, ($$render) => {
69036
- if (get(currentPlacingId) && get(currentTool) === "furniture") $$render(consequent_18);
69728
+ if (get(measuring)) $$render(consequent_18);
69037
69729
  });
69038
69730
  var node_21 = sibling(node_20, 2);
69039
69731
  var consequent_19 = ($$anchor) => {
69040
69732
  append($$anchor, root_22());
69041
69733
  };
69042
69734
  if_block(node_21, ($$render) => {
69043
- if (get(measuring)) $$render(consequent_19);
69735
+ if (get(textAnnotationMode)) $$render(consequent_19);
69044
69736
  });
69045
69737
  var node_22 = sibling(node_21, 2);
69046
69738
  var consequent_20 = ($$anchor) => {
69047
- append($$anchor, root_23());
69739
+ var div_10 = root_23();
69740
+ var text_16 = child(div_10);
69741
+ reset(div_10);
69742
+ template_effect(() => set_text(text_16, `${get(annotationStart) ? "Click second point to create annotation" : "Click first point"} · N to exit · Esc to cancel`));
69743
+ append($$anchor, div_10);
69048
69744
  };
69049
69745
  if_block(node_22, ($$render) => {
69050
- if (get(textAnnotationMode)) $$render(consequent_20);
69746
+ if (get(annotating)) $$render(consequent_20);
69051
69747
  });
69052
- var node_23 = sibling(node_22, 2);
69053
- var consequent_21 = ($$anchor) => {
69054
- var div_11 = root_24();
69055
- var text_17 = child(div_11);
69056
- reset(div_11);
69057
- template_effect(() => set_text(text_17, `${get(annotationStart) ? "Click second point to create annotation" : "Click first point"} · N to exit · Esc to cancel`));
69058
- append($$anchor, div_11);
69059
- };
69060
- if_block(node_23, ($$render) => {
69061
- if (get(annotating)) $$render(consequent_21);
69062
- });
69063
- var div_12 = sibling(node_23, 2);
69064
- var button_11 = child(div_12);
69748
+ var div_11 = sibling(node_22, 2);
69749
+ var button_11 = child(div_11);
69065
69750
  var button_12 = sibling(button_11, 2);
69066
- var text_18 = child(button_12);
69751
+ var text_17 = child(button_12);
69067
69752
  reset(button_12);
69068
69753
  var button_13 = sibling(button_12, 2);
69069
69754
  var button_14 = sibling(button_13, 4);
69070
- reset(div_12);
69071
- ContextMenu(sibling(div_12, 2), {
69755
+ reset(div_11);
69756
+ ContextMenu(sibling(div_11, 2), {
69072
69757
  get x() {
69073
69758
  return get(ctxMenuX);
69074
69759
  },
@@ -69101,7 +69786,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69101
69786
  },
69102
69787
  onaction: handleContextMenuAction
69103
69788
  });
69104
- template_effect(($0) => set_text(text_18, `${$0 !== null && $0 !== void 0 ? $0 : ""}%`), [() => Math.round(get(zoom) * 100)]);
69789
+ template_effect(($0) => set_text(text_17, `${$0 !== null && $0 !== void 0 ? $0 : ""}%`), [() => Math.round(get(zoom) * 100)]);
69105
69790
  delegated("click", button_11, () => {
69106
69791
  const newZoom = Math.max(.1, get(zoom) * .8);
69107
69792
  const worldCX = (get(width) / 2 - get(width) / 2) / get(zoom) + get(camX);
@@ -69122,8 +69807,8 @@ function FloorPlanCanvas($$anchor, $$props) {
69122
69807
  delegated("click", button_14, () => zoomToFit());
69123
69808
  append($$anchor, fragment);
69124
69809
  };
69125
- if_block(node_1, ($$render) => {
69126
- if (!$$props.viewOnly) $$render(consequent_22);
69810
+ if_block(node, ($$render) => {
69811
+ if (!$$props.viewOnly) $$render(consequent_21);
69127
69812
  });
69128
69813
  reset(div);
69129
69814
  template_effect(($0) => {
@@ -70439,7 +71124,7 @@ function App($$anchor, $$props) {
70439
71124
  });
70440
71125
  let $5 = /* @__PURE__ */ user_derived(() => {
70441
71126
  var _$$get7;
70442
- return (_$$get7 = get(config)) === null || _$$get7 === void 0 ? void 0 : _$$get7.projectName;
71127
+ return (_$$get7 = get(config)) === null || _$$get7 === void 0 ? void 0 : _$$get7.heatmapColorScale;
70443
71128
  });
70444
71129
  let $6 = /* @__PURE__ */ user_derived(() => {
70445
71130
  var _$$get8;
@@ -70485,7 +71170,7 @@ function App($$anchor, $$props) {
70485
71170
  get heatmapEnabled() {
70486
71171
  return get($4);
70487
71172
  },
70488
- get projectName() {
71173
+ get heatmapColorScale() {
70489
71174
  return get($5);
70490
71175
  },
70491
71176
  get selectedCameraSerial() {