floor-editor-ts 1.3.4 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5982,6 +5982,19 @@ function emitFloorCallback(type, data) {
5982
5982
  data
5983
5983
  });
5984
5984
  }
5985
+ function emitCamerasChanged(data) {
5986
+ if (data.added.length === 0 && data.removed.length === 0) return;
5987
+ emitFloorCallback("camerasChanged", data);
5988
+ }
5989
+ function cameraItemToCallbackProps(item) {
5990
+ var _item$props, _ref, _item$name, _item$props2;
5991
+ if (!item.serial) return null;
5992
+ return {
5993
+ ...(_item$props = item.props) !== null && _item$props !== void 0 ? _item$props : {},
5994
+ serial: item.serial,
5995
+ name: (_ref = (_item$name = item.name) !== null && _item$name !== void 0 ? _item$name : (_item$props2 = item.props) === null || _item$props2 === void 0 ? void 0 : _item$props2.name) !== null && _ref !== void 0 ? _ref : ""
5996
+ };
5997
+ }
5985
5998
  //#endregion
5986
5999
  //#region src/lib/stores/onboarding.svelte.ts
5987
6000
  var onboarding_svelte_exports = /* @__PURE__ */ __exportAll({
@@ -6156,6 +6169,33 @@ function reviveDates(p) {
6156
6169
  if (p.updatedAt && !(p.updatedAt instanceof Date)) p.updatedAt = new Date(p.updatedAt);
6157
6170
  return p;
6158
6171
  }
6172
+ function collectCamerasBySerial(project) {
6173
+ const map = /* @__PURE__ */ new Map();
6174
+ if (!(project === null || project === void 0 ? void 0 : project.floors)) return map;
6175
+ for (const floor of project.floors) {
6176
+ var _floor$furniture;
6177
+ for (const item of (_floor$furniture = floor.furniture) !== null && _floor$furniture !== void 0 ? _floor$furniture : []) {
6178
+ if (item.catalogId !== "camera" || !item.serial) continue;
6179
+ const props = cameraItemToCallbackProps(item);
6180
+ if (props) map.set(props.serial, props);
6181
+ }
6182
+ }
6183
+ return map;
6184
+ }
6185
+ /** Diff assigned cameras between two project snapshots and notify host. */
6186
+ function emitCameraDiff(before, after) {
6187
+ if (isAssignedCamerasSyncing()) return;
6188
+ const beforeMap = collectCamerasBySerial(before);
6189
+ const afterMap = collectCamerasBySerial(after);
6190
+ const removed = [];
6191
+ const added = [];
6192
+ for (const [serial, props] of beforeMap) if (!afterMap.has(serial)) removed.push(props);
6193
+ for (const [serial, props] of afterMap) if (!beforeMap.has(serial)) added.push(props);
6194
+ emitCamerasChanged({
6195
+ added,
6196
+ removed
6197
+ });
6198
+ }
6159
6199
  function undo() {
6160
6200
  const prev = undoStack.pop();
6161
6201
  if (!prev) return;
@@ -6165,19 +6205,23 @@ function undo() {
6165
6205
  description: prev.description,
6166
6206
  timestamp: prev.timestamp
6167
6207
  });
6168
- currentProject.set(reviveDates(JSON.parse(prev.state)));
6208
+ const next = reviveDates(JSON.parse(prev.state));
6209
+ currentProject.set(next);
6210
+ emitCameraDiff(cur, next);
6169
6211
  syncHistoryStore();
6170
6212
  }
6171
6213
  function redo() {
6172
- const next = redoStack.pop();
6173
- if (!next) return;
6214
+ const nextEntry = redoStack.pop();
6215
+ if (!nextEntry) return;
6174
6216
  const cur = get$1(currentProject);
6175
6217
  if (cur) undoStack.push({
6176
6218
  state: JSON.stringify(cur),
6177
- description: next.description,
6178
- timestamp: next.timestamp
6219
+ description: nextEntry.description,
6220
+ timestamp: nextEntry.timestamp
6179
6221
  });
6180
- currentProject.set(reviveDates(JSON.parse(next.state)));
6222
+ const next = reviveDates(JSON.parse(nextEntry.state));
6223
+ currentProject.set(next);
6224
+ emitCameraDiff(cur, next);
6181
6225
  syncHistoryStore();
6182
6226
  }
6183
6227
  /** Jump to a specific undo history step by index (0 = oldest) */
@@ -6198,7 +6242,9 @@ function jumpToUndoStep(targetIndex) {
6198
6242
  redoStack.push(entry);
6199
6243
  }
6200
6244
  const target = undoStack.pop();
6201
- currentProject.set(reviveDates(JSON.parse(target.state)));
6245
+ const next = reviveDates(JSON.parse(target.state));
6246
+ currentProject.set(next);
6247
+ emitCameraDiff(cur, next);
6202
6248
  syncHistoryStore();
6203
6249
  }
6204
6250
  function mutate(fn, description) {
@@ -6372,10 +6418,13 @@ function removeFurniture(id) {
6372
6418
  mutate((f) => {
6373
6419
  f.furniture = f.furniture.filter((fi) => fi.id !== id);
6374
6420
  }, "Deleted furniture");
6375
- if ((removedCamera === null || removedCamera === void 0 ? void 0 : removedCamera.serial) && !isAssignedCamerasSyncing()) emitFloorCallback("cameraRemoved", {
6376
- serial: removedCamera.serial,
6377
- name: removedCamera.name
6378
- });
6421
+ if ((removedCamera === null || removedCamera === void 0 ? void 0 : removedCamera.serial) && !isAssignedCamerasSyncing()) {
6422
+ const props = cameraItemToCallbackProps(removedCamera);
6423
+ if (props) emitCamerasChanged({
6424
+ added: [],
6425
+ removed: [props]
6426
+ });
6427
+ }
6379
6428
  }
6380
6429
  function addStair(position) {
6381
6430
  const id = uid$1();
@@ -6489,10 +6538,13 @@ function removeElement(id) {
6489
6538
  if (f.columns) f.columns = f.columns.filter((c) => c.id !== id);
6490
6539
  if (f.textAnnotations) f.textAnnotations = f.textAnnotations.filter((t) => t.id !== id);
6491
6540
  }, "Deleted element");
6492
- if ((removedCamera === null || removedCamera === void 0 ? void 0 : removedCamera.serial) && !isAssignedCamerasSyncing()) emitFloorCallback("cameraRemoved", {
6493
- serial: removedCamera.serial,
6494
- name: removedCamera.name
6495
- });
6541
+ if ((removedCamera === null || removedCamera === void 0 ? void 0 : removedCamera.serial) && !isAssignedCamerasSyncing()) {
6542
+ const props = cameraItemToCallbackProps(removedCamera);
6543
+ if (props) emitCamerasChanged({
6544
+ added: [],
6545
+ removed: [props]
6546
+ });
6547
+ }
6496
6548
  }
6497
6549
  /** Move a wall endpoint without creating an undo snapshot (for dragging) */
6498
6550
  function moveWallEndpoint(id, endpoint, position) {
@@ -6526,10 +6578,30 @@ function updateWindow(id, updates) {
6526
6578
  });
6527
6579
  }
6528
6580
  function updateFurniture(id, updates) {
6581
+ const p = get$1(currentProject);
6582
+ const floor = p === null || p === void 0 ? void 0 : p.floors.find((f) => f.id === p.activeFloorId);
6583
+ const before = floor === null || floor === void 0 ? void 0 : floor.furniture.find((fi) => fi.id === id);
6584
+ const beforeSerial = (before === null || before === void 0 ? void 0 : before.catalogId) === "camera" ? before.serial || void 0 : void 0;
6585
+ const beforeProps = (before === null || before === void 0 ? void 0 : before.catalogId) === "camera" ? cameraItemToCallbackProps(before) : null;
6529
6586
  mutate((f) => {
6530
6587
  const fi = f.furniture.find((fi) => fi.id === id);
6531
6588
  if (fi) Object.assign(fi, updates);
6532
6589
  });
6590
+ if ((before === null || before === void 0 ? void 0 : before.catalogId) !== "camera" || isAssignedCamerasSyncing()) return;
6591
+ const afterProject = get$1(currentProject);
6592
+ const afterFloor = afterProject === null || afterProject === void 0 ? void 0 : afterProject.floors.find((f) => f.id === afterProject.activeFloorId);
6593
+ const after = afterFloor === null || afterFloor === void 0 ? void 0 : afterFloor.furniture.find((fi) => fi.id === id);
6594
+ const afterSerial = (after === null || after === void 0 ? void 0 : after.serial) || void 0;
6595
+ if (beforeSerial === afterSerial) return;
6596
+ const added = [];
6597
+ const removed = [];
6598
+ if (beforeSerial && beforeProps) removed.push(beforeProps);
6599
+ const afterProps = after ? cameraItemToCallbackProps(after) : null;
6600
+ if (afterSerial && afterProps) added.push(afterProps);
6601
+ emitCamerasChanged({
6602
+ added,
6603
+ removed
6604
+ });
6533
6605
  }
6534
6606
  function updateRoom(id, updates) {
6535
6607
  mutate((f) => {
@@ -7020,6 +7092,18 @@ var localStore = {
7020
7092
  };
7021
7093
  //#endregion
7022
7094
  //#region src/lib/packageDefaults.ts
7095
+ /** Flatten host camera object into string props for furniture + UI. */
7096
+ function assignedCameraToProps(cam) {
7097
+ const props = {};
7098
+ for (const [key, value] of Object.entries(cam)) {
7099
+ if (value == null) continue;
7100
+ props[key] = String(value);
7101
+ }
7102
+ return props;
7103
+ }
7104
+ function formatCameraPropLabel(key) {
7105
+ return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
7106
+ }
7023
7107
  var DEFAULT_CONFIG = {
7024
7108
  viewOnly: false,
7025
7109
  floorMaxWidth: 600,
@@ -7041,7 +7125,15 @@ var DEFAULT_CONFIG = {
7041
7125
  function normalizeConfig(value) {
7042
7126
  if (!value || typeof value !== "object") return { ...DEFAULT_CONFIG };
7043
7127
  const siteCameras = Array.isArray(value.siteCameras) ? value.siteCameras.filter((c) => !!c && typeof c === "object" && typeof c.serial === "string" && typeof c.name === "string") : DEFAULT_CONFIG.siteCameras;
7044
- const assignedCameras = Array.isArray(value.assignedCameras) ? value.assignedCameras.filter((c) => !!c && typeof c === "object" && typeof c.serial === "string" && c.serial.trim().length > 0 && typeof c.name === "string") : DEFAULT_CONFIG.assignedCameras;
7128
+ const assignedCameras = Array.isArray(value.assignedCameras) ? value.assignedCameras.filter((c) => !!c && typeof c === "object" && typeof c.serial === "string" && String(c.serial).trim().length > 0).map((c) => {
7129
+ const next = { serial: String(c.serial).trim() };
7130
+ for (const [key, val] of Object.entries(c)) {
7131
+ if (key === "serial") continue;
7132
+ if (val == null) continue;
7133
+ if (typeof val === "string" || typeof val === "number" || typeof val === "boolean") next[key] = val;
7134
+ }
7135
+ return next;
7136
+ }) : DEFAULT_CONFIG.assignedCameras;
7045
7137
  const image = typeof value.cameraThumbnail === "string" ? value.cameraThumbnail ? value.cameraThumbnail : DEFAULT_CONFIG.cameraThumbnail : DEFAULT_CONFIG.cameraThumbnail;
7046
7138
  const opacity = typeof value.cameraThumbnailOpacity === "number" && value.cameraThumbnailOpacity >= 0 && value.cameraThumbnailOpacity <= 1 ? value.cameraThumbnailOpacity : DEFAULT_CONFIG.cameraThumbnailOpacity;
7047
7139
  const canvasBackground = normalizeColor$1(value.canvasBackground, DEFAULT_CONFIG.canvasBackground);
@@ -56161,7 +56253,7 @@ var themePreference = createThemeStore();
56161
56253
  //#endregion
56162
56254
  //#region src/lib/components/toolbar/SettingsDialog.svelte
56163
56255
  init_client();
56164
- 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>`);
56256
+ 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>`);
56165
56257
  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>`);
56166
56258
  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>`);
56167
56259
  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>`);
@@ -56289,7 +56381,7 @@ function SettingsDialog($$anchor, $$props) {
56289
56381
  var button_1 = child(div_3);
56290
56382
  var node_1 = sibling(child(button_1));
56291
56383
  var consequent = ($$anchor) => {
56292
- append($$anchor, root_2$12());
56384
+ append($$anchor, root_2$13());
56293
56385
  };
56294
56386
  if_block(node_1, ($$render) => {
56295
56387
  if (get(activeTab) === "project") $$render(consequent);
@@ -56569,7 +56661,7 @@ delegate([
56569
56661
  //#endregion
56570
56662
  //#region src/lib/components/sidebar/AreaSummaryPanel.svelte
56571
56663
  init_client();
56572
- 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>`);
56664
+ 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>`);
56573
56665
  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>`);
56574
56666
  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>`);
56575
56667
  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>`);
@@ -56690,7 +56782,7 @@ function AreaSummaryPanel($$anchor, $$props) {
56690
56782
  var div_10 = root_1$12();
56691
56783
  var div_11 = sibling(child(div_10), 2);
56692
56784
  each(div_11, 21, () => get(categoryTotals), index$1, ($$anchor, cat) => {
56693
- var div_12 = root_2$11();
56785
+ var div_12 = root_2$12();
56694
56786
  var span = child(div_12);
56695
56787
  var text_4 = child(span);
56696
56788
  var span_1 = sibling(text_4);
@@ -56918,7 +57010,7 @@ async function autoSave(onDispatch) {
56918
57010
  //#endregion
56919
57011
  //#region src/lib/components/toolbar/VersionHistoryPanel.svelte
56920
57012
  init_client();
56921
- 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>`);
57013
+ 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>`);
56922
57014
  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>`);
56923
57015
  var root_3$10 = /* @__PURE__ */ from_html(`<div class="space-y-1"></div>`);
56924
57016
  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>`);
@@ -56968,7 +57060,7 @@ function VersionHistoryPanel($$anchor, $$props) {
56968
57060
  var div_3 = sibling(div_2, 2);
56969
57061
  var node_1 = child(div_3);
56970
57062
  var consequent = ($$anchor) => {
56971
- append($$anchor, root_2$10());
57063
+ append($$anchor, root_2$11());
56972
57064
  };
56973
57065
  var alternate = ($$anchor) => {
56974
57066
  var div_4 = root_3$10();
@@ -57034,14 +57126,14 @@ delegate(["click", "keydown"]);
57034
57126
  init_client();
57035
57127
  init_index_client();
57036
57128
  init_onboarding_svelte();
57037
- 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"/>`);
57129
+ 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"/>`);
57038
57130
  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>`);
57039
57131
  var root_4$8 = /* @__PURE__ */ from_html(`<button> </button>`);
57040
57132
  var root_5$5 = /* @__PURE__ */ from_html(`<div class="flex bg-white/15 rounded-full p-0.5"><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>`);
57041
57133
  var root_6$4 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1 bg-white/15 rounded-full p-0.5"><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>`);
57042
57134
  var root_8$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>`);
57043
57135
  var root_7$5 = /* @__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>`);
57044
- 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"><!> <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> <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> <!> <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> <div class="h-5 w-px bg-white/20"></div> <!> <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> <div class="h-5 w-px bg-white/20"></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>`);
57136
+ 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"><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> <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> <!> <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> <div class="h-5 w-px bg-white/20"></div> <!> <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> <div class="h-5 w-px bg-white/20"></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>`);
57045
57137
  var root_13$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"><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>`);
57046
57138
  var root_12$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>`);
57047
57139
  var root_14$2 = /* @__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>`);
@@ -57053,6 +57145,7 @@ function TopBar($$anchor, $$props) {
57053
57145
  const $canvasZoom = () => store_get(canvasZoom, "$canvasZoom", $$stores);
57054
57146
  const $saveState = () => store_get(saveState, "$saveState", $$stores);
57055
57147
  const [$$stores, $$cleanup] = setup_stores();
57148
+ let showBuildSidebar = prop($$props, "showBuildSidebar", 15, true);
57056
57149
  let settingsOpen = /* @__PURE__ */ state(false);
57057
57150
  let areaOpen = /* @__PURE__ */ state(false);
57058
57151
  let versionHistoryOpen = /* @__PURE__ */ state(false);
@@ -57235,9 +57328,10 @@ function TopBar($$anchor, $$props) {
57235
57328
  var node = first_child(fragment);
57236
57329
  var consequent_7 = ($$anchor) => {
57237
57330
  var div = root_1$10();
57238
- var node_1 = child(div);
57331
+ var button = child(div);
57332
+ var node_1 = sibling(button, 2);
57239
57333
  var consequent = ($$anchor) => {
57240
- var input_1 = root_2$9();
57334
+ var input_1 = root_2$10();
57241
57335
  remove_input_defaults(input_1);
57242
57336
  event("blur", input_1, onNameBlur);
57243
57337
  delegated("keydown", input_1, onNameKeydown);
@@ -57245,12 +57339,12 @@ function TopBar($$anchor, $$props) {
57245
57339
  append($$anchor, input_1);
57246
57340
  };
57247
57341
  var alternate = ($$anchor) => {
57248
- var button = root_3$9();
57249
- var text_1 = child(button, true);
57250
- reset(button);
57342
+ var button_1 = root_3$9();
57343
+ var text_1 = child(button_1, true);
57344
+ reset(button_1);
57251
57345
  template_effect(() => set_text(text_1, get(projectName)));
57252
- delegated("click", button, () => set(editingName, true));
57253
- append($$anchor, button);
57346
+ delegated("click", button_1, () => set(editingName, true));
57347
+ append($$anchor, button_1);
57254
57348
  };
57255
57349
  if_block(node_1, ($$render) => {
57256
57350
  if (get(editingName)) $$render(consequent);
@@ -57259,104 +57353,104 @@ function TopBar($$anchor, $$props) {
57259
57353
  var div_1 = sibling(node_1, 4);
57260
57354
  var node_2 = child(div_1);
57261
57355
  each(node_2, 17, () => get(floors), index$1, ($$anchor, fl) => {
57262
- var button_1 = root_4$8();
57263
- var text_2 = child(button_1, true);
57264
- reset(button_1);
57356
+ var button_2 = root_4$8();
57357
+ var text_2 = child(button_2, true);
57358
+ reset(button_2);
57265
57359
  template_effect(() => {
57266
- set_class(button_1, 1, `px-2 py-0.5 text-xs rounded transition-colors ${get(fl).id === get(activeFloorId) ? "bg-white text-slate-800 font-semibold" : "text-white/80 hover:bg-white/10"}`);
57267
- set_attribute(button_1, "title", get(fl).id === get(activeFloorId) ? "Active floor (dbl-click to remove)" : "Click to switch, dbl-click to remove");
57360
+ set_class(button_2, 1, `px-2 py-0.5 text-xs rounded transition-colors ${get(fl).id === get(activeFloorId) ? "bg-white text-slate-800 font-semibold" : "text-white/80 hover:bg-white/10"}`);
57361
+ set_attribute(button_2, "title", get(fl).id === get(activeFloorId) ? "Active floor (dbl-click to remove)" : "Click to switch, dbl-click to remove");
57268
57362
  set_text(text_2, get(fl).name);
57269
57363
  });
57270
- delegated("click", button_1, () => setActiveFloor(get(fl).id));
57271
- delegated("dblclick", button_1, () => onRemoveFloor(get(fl).id));
57272
- append($$anchor, button_1);
57364
+ delegated("click", button_2, () => setActiveFloor(get(fl).id));
57365
+ delegated("dblclick", button_2, () => onRemoveFloor(get(fl).id));
57366
+ append($$anchor, button_2);
57273
57367
  });
57274
- var button_2 = sibling(node_2, 2);
57275
- var span = sibling(button_2, 2);
57368
+ var button_3 = sibling(node_2, 2);
57369
+ var span = sibling(button_3, 2);
57276
57370
  var text_3 = child(span);
57277
57371
  reset(span);
57278
57372
  reset(div_1);
57279
- var button_3 = sibling(div_1, 4);
57280
- var button_4 = sibling(button_3, 2);
57281
- var button_5 = sibling(button_4, 4);
57282
- var node_3 = sibling(button_5, 2);
57373
+ var button_4 = sibling(div_1, 4);
57374
+ var button_5 = sibling(button_4, 2);
57375
+ var button_6 = sibling(button_5, 4);
57376
+ var node_3 = sibling(button_6, 2);
57283
57377
  var consequent_1 = ($$anchor) => {
57284
57378
  var div_2 = root_5$5();
57285
- var button_6 = child(div_2);
57286
- var button_7 = sibling(button_6, 2);
57379
+ var button_7 = child(div_2);
57380
+ var button_8 = sibling(button_7, 2);
57287
57381
  reset(div_2);
57288
57382
  template_effect(() => {
57289
- set_class(button_6, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${!$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
57290
- set_class(button_7, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
57383
+ set_class(button_7, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${!$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
57384
+ set_class(button_8, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
57291
57385
  });
57292
- delegated("click", button_6, () => panMode.set(false));
57293
- delegated("click", button_7, () => panMode.set(true));
57386
+ delegated("click", button_7, () => panMode.set(false));
57387
+ delegated("click", button_8, () => panMode.set(true));
57294
57388
  append($$anchor, div_2);
57295
57389
  };
57296
57390
  if_block(node_3, ($$render) => {
57297
57391
  if (get(mode) === "2d") $$render(consequent_1);
57298
57392
  });
57299
- var button_8 = sibling(node_3, 2);
57300
- var node_4 = sibling(button_8, 4);
57393
+ var button_9 = sibling(node_3, 2);
57394
+ var node_4 = sibling(button_9, 4);
57301
57395
  var consequent_2 = ($$anchor) => {
57302
57396
  var div_3 = root_6$4();
57303
- var button_9 = child(div_3);
57304
- var button_10 = sibling(button_9, 2);
57305
- var text_4 = child(button_10);
57306
- reset(button_10);
57397
+ var button_10 = child(div_3);
57307
57398
  var button_11 = sibling(button_10, 2);
57399
+ var text_4 = child(button_11);
57400
+ reset(button_11);
57401
+ var button_12 = sibling(button_11, 2);
57308
57402
  reset(div_3);
57309
57403
  template_effect(($0) => set_text(text_4, `${$0 !== null && $0 !== void 0 ? $0 : ""}%`), [() => Math.round($canvasZoom() * 100)]);
57310
- delegated("click", button_9, () => canvasZoom.update((z) => Math.max(.1, z / 1.25)));
57311
- delegated("click", button_10, () => canvasZoom.set(1));
57312
- delegated("click", button_11, () => canvasZoom.update((z) => Math.min(10, z * 1.25)));
57404
+ delegated("click", button_10, () => canvasZoom.update((z) => Math.max(.1, z / 1.25)));
57405
+ delegated("click", button_11, () => canvasZoom.set(1));
57406
+ delegated("click", button_12, () => canvasZoom.update((z) => Math.min(10, z * 1.25)));
57313
57407
  append($$anchor, div_3);
57314
57408
  };
57315
57409
  if_block(node_4, ($$render) => {
57316
57410
  if (get(mode) === "2d") $$render(consequent_2);
57317
57411
  });
57318
- var button_12 = sibling(node_4, 2);
57319
- var button_13 = sibling(button_12, 2);
57412
+ var button_13 = sibling(node_4, 2);
57320
57413
  var button_14 = sibling(button_13, 2);
57321
- var div_4 = sibling(button_14, 4);
57322
- var button_15 = child(div_4);
57323
- var node_5 = sibling(button_15, 2);
57414
+ var button_15 = sibling(button_14, 2);
57415
+ var div_4 = sibling(button_15, 4);
57416
+ var button_16 = child(div_4);
57417
+ var node_5 = sibling(button_16, 2);
57324
57418
  var consequent_4 = ($$anchor) => {
57325
57419
  var div_5 = root_7$5();
57326
- var button_16 = child(div_5);
57327
- var button_17 = sibling(button_16, 4);
57328
- var button_18 = sibling(button_17, 2);
57420
+ var button_17 = child(div_5);
57421
+ var button_18 = sibling(button_17, 4);
57329
57422
  var button_19 = sibling(button_18, 2);
57330
57423
  var button_20 = sibling(button_19, 2);
57331
57424
  var button_21 = sibling(button_20, 2);
57332
57425
  var button_22 = sibling(button_21, 2);
57333
57426
  var button_23 = sibling(button_22, 2);
57334
- var node_6 = sibling(button_23, 4);
57427
+ var button_24 = sibling(button_23, 2);
57428
+ var node_6 = sibling(button_24, 4);
57335
57429
  var consequent_3 = ($$anchor) => {
57336
- var button_24 = root_8$2();
57337
- delegated("click", button_24, onImportJSON);
57338
- append($$anchor, button_24);
57430
+ var button_25 = root_8$2();
57431
+ delegated("click", button_25, onImportJSON);
57432
+ append($$anchor, button_25);
57339
57433
  };
57340
57434
  if_block(node_6, ($$render) => {
57341
57435
  if (!$$props.viewOnly) $$render(consequent_3);
57342
57436
  });
57343
- var button_25 = sibling(node_6, 2);
57437
+ var button_26 = sibling(node_6, 2);
57344
57438
  reset(div_5);
57345
- delegated("click", button_16, () => {
57439
+ delegated("click", button_17, () => {
57346
57440
  set(exportOpen, false);
57347
57441
  window.dispatchEvent(new KeyboardEvent("keydown", {
57348
57442
  key: "p",
57349
57443
  ctrlKey: true
57350
57444
  }));
57351
57445
  });
57352
- delegated("click", button_17, onExport2DPNG);
57353
- delegated("click", button_18, onExport3DPNG);
57354
- delegated("click", button_19, onExportSVG);
57355
- delegated("click", button_20, onExportDXF);
57356
- delegated("click", button_21, onExportDWG);
57357
- delegated("click", button_22, onExportPDF);
57358
- delegated("click", button_23, onExportJSON);
57359
- delegated("click", button_25, newProject);
57446
+ delegated("click", button_18, onExport2DPNG);
57447
+ delegated("click", button_19, onExport3DPNG);
57448
+ delegated("click", button_20, onExportSVG);
57449
+ delegated("click", button_21, onExportDXF);
57450
+ delegated("click", button_22, onExportDWG);
57451
+ delegated("click", button_23, onExportPDF);
57452
+ delegated("click", button_24, onExportJSON);
57453
+ delegated("click", button_26, newProject);
57360
57454
  append($$anchor, div_5);
57361
57455
  };
57362
57456
  if_block(node_5, ($$render) => {
@@ -57381,41 +57475,46 @@ function TopBar($$anchor, $$props) {
57381
57475
  else $$render(alternate_1, -1);
57382
57476
  });
57383
57477
  reset(span_1);
57384
- var button_26 = sibling(span_1, 2);
57478
+ var button_27 = sibling(span_1, 2);
57385
57479
  reset(div);
57386
57480
  template_effect(() => {
57387
57481
  var _$$get$length;
57482
+ set_class(button, 1, `shrink-0 w-8 h-8 rounded-md flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 transition-colors ${showBuildSidebar() ? "bg-white/15 text-white" : ""}`);
57483
+ set_attribute(button, "title", showBuildSidebar() ? "Hide sidebar" : "Show sidebar");
57484
+ set_attribute(button, "aria-label", showBuildSidebar() ? "Hide sidebar" : "Show sidebar");
57485
+ set_attribute(button, "aria-pressed", showBuildSidebar());
57388
57486
  set_text(text_3, `${(_$$get$length = get(floors).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""}F`);
57389
- set_class(button_5, 1, `p-1.5 rounded transition-colors ${get(snapOn) ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
57390
- set_attribute(button_5, "title", `Snap to Grid (${get(snapOn) ? "On" : "Off"})`);
57391
- set_class(button_8, 1, `p-1.5 rounded transition-colors ${$showFurnitureStore() ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
57392
- set_attribute(button_8, "title", `Toggle Furniture (${$showFurnitureStore() ? "Visible" : "Hidden"})`);
57487
+ set_class(button_6, 1, `p-1.5 rounded transition-colors ${get(snapOn) ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
57488
+ set_attribute(button_6, "title", `Snap to Grid (${get(snapOn) ? "On" : "Off"})`);
57489
+ set_class(button_9, 1, `p-1.5 rounded transition-colors ${$showFurnitureStore() ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
57490
+ set_attribute(button_9, "title", `Toggle Furniture (${$showFurnitureStore() ? "Visible" : "Hidden"})`);
57393
57491
  set_class(span_1, 1, `text-[11px] font-medium transition-all duration-300 ${$saveState() === "saved" ? "text-emerald-400" : $saveState() === "saving" ? "text-amber-300 animate-pulse" : "text-white/50"}`);
57394
57492
  set_attribute(span_1, "title", get(lastSavedText) || "Not saved yet");
57395
57493
  });
57396
- delegated("click", button_2, onAddFloor);
57397
- delegated("click", button_3, function(...$$args) {
57494
+ delegated("click", button, () => showBuildSidebar(!showBuildSidebar()));
57495
+ delegated("click", button_3, onAddFloor);
57496
+ delegated("click", button_4, function(...$$args) {
57398
57497
  undo === null || undo === void 0 || undo.apply(this, $$args);
57399
57498
  });
57400
- delegated("click", button_4, function(...$$args) {
57499
+ delegated("click", button_5, function(...$$args) {
57401
57500
  redo === null || redo === void 0 || redo.apply(this, $$args);
57402
57501
  });
57403
- delegated("click", button_5, () => {
57502
+ delegated("click", button_6, () => {
57404
57503
  snapEnabled.update((v) => !v);
57405
57504
  set(snapOn, !get(snapOn));
57406
57505
  });
57407
- delegated("click", button_8, () => layerVisibility.update((v) => ({
57506
+ delegated("click", button_9, () => layerVisibility.update((v) => ({
57408
57507
  ...v,
57409
57508
  furniture: !v.furniture
57410
57509
  })));
57411
- delegated("click", button_12, () => set(versionHistoryOpen, true));
57412
- delegated("click", button_13, () => set(areaOpen, true));
57413
- delegated("click", button_14, () => set(settingsOpen, true));
57414
- delegated("click", button_15, () => {
57510
+ delegated("click", button_13, () => set(versionHistoryOpen, true));
57511
+ delegated("click", button_14, () => set(areaOpen, true));
57512
+ delegated("click", button_15, () => set(settingsOpen, true));
57513
+ delegated("click", button_16, () => {
57415
57514
  set(exportOpen, !get(exportOpen));
57416
57515
  if (get(exportOpen)) triggerTip("first-export", 300, 60);
57417
57516
  });
57418
- delegated("click", button_26, save);
57517
+ delegated("click", button_27, save);
57419
57518
  append($$anchor, div);
57420
57519
  };
57421
57520
  var alternate_2 = ($$anchor) => {
@@ -57424,35 +57523,35 @@ function TopBar($$anchor, $$props) {
57424
57523
  var text_8 = child(span_2, true);
57425
57524
  reset(span_2);
57426
57525
  var div_7 = sibling(span_2, 2);
57427
- var button_27 = child(div_7);
57428
- var node_8 = sibling(button_27, 2);
57526
+ var button_28 = child(div_7);
57527
+ var node_8 = sibling(button_28, 2);
57429
57528
  var consequent_8 = ($$anchor) => {
57430
57529
  var div_8 = root_13$2();
57431
- var button_28 = child(div_8);
57432
- var button_29 = sibling(button_28, 4);
57433
- var button_30 = sibling(button_29, 2);
57530
+ var button_29 = child(div_8);
57531
+ var button_30 = sibling(button_29, 4);
57434
57532
  var button_31 = sibling(button_30, 2);
57435
57533
  var button_32 = sibling(button_31, 2);
57436
57534
  var button_33 = sibling(button_32, 2);
57437
57535
  var button_34 = sibling(button_33, 2);
57438
57536
  var button_35 = sibling(button_34, 2);
57439
- var button_36 = sibling(button_35, 4);
57537
+ var button_36 = sibling(button_35, 2);
57538
+ var button_37 = sibling(button_36, 4);
57440
57539
  reset(div_8);
57441
- delegated("click", button_28, () => {
57540
+ delegated("click", button_29, () => {
57442
57541
  set(exportOpen, false);
57443
57542
  window.dispatchEvent(new KeyboardEvent("keydown", {
57444
57543
  key: "p",
57445
57544
  ctrlKey: true
57446
57545
  }));
57447
57546
  });
57448
- delegated("click", button_29, onExport2DPNG);
57449
- delegated("click", button_30, onExport3DPNG);
57450
- delegated("click", button_31, onExportSVG);
57451
- delegated("click", button_32, onExportDXF);
57452
- delegated("click", button_33, onExportDWG);
57453
- delegated("click", button_34, onExportPDF);
57454
- delegated("click", button_35, onExportJSON);
57455
- delegated("click", button_36, onImportJSON);
57547
+ delegated("click", button_30, onExport2DPNG);
57548
+ delegated("click", button_31, onExport3DPNG);
57549
+ delegated("click", button_32, onExportSVG);
57550
+ delegated("click", button_33, onExportDXF);
57551
+ delegated("click", button_34, onExportDWG);
57552
+ delegated("click", button_35, onExportPDF);
57553
+ delegated("click", button_36, onExportJSON);
57554
+ delegated("click", button_37, onImportJSON);
57456
57555
  append($$anchor, div_8);
57457
57556
  };
57458
57557
  if_block(node_8, ($$render) => {
@@ -57462,7 +57561,7 @@ function TopBar($$anchor, $$props) {
57462
57561
  bind_this(div_7, ($$value) => exportRef = $$value, () => exportRef);
57463
57562
  reset(div_6);
57464
57563
  template_effect(() => set_text(text_8, get(projectName)));
57465
- delegated("click", button_27, () => {
57564
+ delegated("click", button_28, () => {
57466
57565
  set(exportOpen, !get(exportOpen));
57467
57566
  if (get(exportOpen)) triggerTip("first-export", 300, 60);
57468
57567
  });
@@ -57495,7 +57594,7 @@ function TopBar($$anchor, $$props) {
57495
57594
  var div_9 = root_14$2();
57496
57595
  var div_10 = child(div_9);
57497
57596
  var div_11 = child(div_10);
57498
- var button_37 = sibling(child(div_11), 2);
57597
+ var button_38 = sibling(child(div_11), 2);
57499
57598
  reset(div_11);
57500
57599
  var div_12 = sibling(div_11, 2);
57501
57600
  AreaSummaryPanel(child(div_12), {});
@@ -57507,7 +57606,7 @@ function TopBar($$anchor, $$props) {
57507
57606
  if (e.key === "Escape") set(areaOpen, false);
57508
57607
  });
57509
57608
  delegated("click", div_10, (e) => e.stopPropagation());
57510
- delegated("click", button_37, () => set(areaOpen, false));
57609
+ delegated("click", button_38, () => set(areaOpen, false));
57511
57610
  append($$anchor, div_9);
57512
57611
  };
57513
57612
  if_block(node_11, ($$render) => {
@@ -57518,8 +57617,8 @@ function TopBar($$anchor, $$props) {
57518
57617
  $$cleanup();
57519
57618
  }
57520
57619
  delegate([
57521
- "keydown",
57522
57620
  "click",
57621
+ "keydown",
57523
57622
  "dblclick"
57524
57623
  ]);
57525
57624
  //#endregion
@@ -58053,7 +58152,7 @@ function placeRoomTemplate(preset, origin, template, w = 400, h = 300) {
58053
58152
  //#endregion
58054
58153
  //#region src/lib/components/editor/UndoHistoryPanel.svelte
58055
58154
  init_client();
58056
- var root_2$8 = /* @__PURE__ */ from_html(`<div class="px-3 py-6 text-center text-xs text-gray-400">No history yet</div>`);
58155
+ var root_2$9 = /* @__PURE__ */ from_html(`<div class="px-3 py-6 text-center text-xs text-gray-400">No history yet</div>`);
58057
58156
  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>`);
58058
58157
  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>`);
58059
58158
  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>`);
@@ -58092,7 +58191,7 @@ function UndoHistoryPanel($$anchor, $$props) {
58092
58191
  var div_3 = sibling(div_1, 2);
58093
58192
  var node_1 = child(div_3);
58094
58193
  var consequent = ($$anchor) => {
58095
- append($$anchor, root_2$8());
58194
+ append($$anchor, root_2$9());
58096
58195
  };
58097
58196
  var alternate = ($$anchor) => {
58098
58197
  var div_5 = root_3$8();
@@ -58158,7 +58257,7 @@ init_client();
58158
58257
  init_index_client();
58159
58258
  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>`);
58160
58259
  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>`);
58161
- var root_2$7 = /* @__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);
58260
+ 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);
58162
58261
  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>`);
58163
58262
  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>`);
58164
58263
  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>`);
@@ -58538,7 +58637,7 @@ function BuildPanel($$anchor, $$props) {
58538
58637
  reset(button_13);
58539
58638
  var node_1 = sibling(button_13, 2);
58540
58639
  var consequent = ($$anchor) => {
58541
- var fragment_1 = root_2$7();
58640
+ var fragment_1 = root_2$8();
58542
58641
  var div_13 = first_child(fragment_1);
58543
58642
  each(div_13, 21, () => doorCatalog, index$1, ($$anchor, dc) => {
58544
58643
  var button_14 = root_3$7();
@@ -59408,7 +59507,7 @@ function handleGlobalShortcut(e, ctx = {}) {
59408
59507
  init_client();
59409
59508
  var root_3$6 = /* @__PURE__ */ from_html(`<button></button>`);
59410
59509
  var root_4$5 = /* @__PURE__ */ from_html(`<button><span class="bg-white/80 backdrop-blur-sm rounded px-1 py-0.5 mb-0.5 text-gray-700"> </span></button>`);
59411
- var root_2$6 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
59510
+ var root_2$7 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
59412
59511
  var root_6$2 = /* @__PURE__ */ from_html(`<button></button>`);
59413
59512
  var root_7$3 = /* @__PURE__ */ from_html(`<button><span class="bg-white/80 backdrop-blur-sm rounded px-1 py-0.5 mb-0.5 text-gray-700"> </span></button>`);
59414
59513
  var root_5$3 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
@@ -59417,8 +59516,8 @@ var root_8$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-
59417
59516
  var root_9$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-cyan-100 rounded flex items-center justify-center text-xs">🪟</span> Window 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>Standard</option><option>Fixed</option><option>Casement</option><option>Sliding</option><option>Bay</option></select></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" 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"> </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></div>`, 1);
59418
59517
  var root_13$1 = /* @__PURE__ */ from_html(`<option> </option>`);
59419
59518
  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>`);
59420
- var root_14$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Camera Serial</span> <input type="text" disabled="" readonly="" placeholder="Assigned by host" class="w-full px-2 py-1 border border-gray-200 rounded text-sm bg-gray-50 text-gray-600 font-mono"/></label>`);
59421
- var root_11$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Camera Name</span> <input type="text" placeholder="Display name" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <!>`, 1);
59519
+ var root_14$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500"> </span> <input type="text"/></label>`);
59520
+ var root_11$1 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
59422
59521
  var root_15$1 = /* @__PURE__ */ from_html(`<button></button>`);
59423
59522
  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);
59424
59523
  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>`);
@@ -59433,7 +59532,7 @@ var root_26 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-
59433
59532
  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);
59434
59533
  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>`);
59435
59534
  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>`);
59436
- var root$3 = /* @__PURE__ */ from_html(`<div data-properties-panel="" style="top: 48px; bottom: 36px;"><!> <!></div>`);
59535
+ var root$3 = /* @__PURE__ */ from_html(`<div data-properties-panel="" style="top: 0; bottom: 0;"><!> <!></div>`);
59437
59536
  function PropertiesPanel($$anchor, $$props) {
59438
59537
  push($$props, true);
59439
59538
  const $projectSettings = () => store_get(projectSettings, "$projectSettings", $$stores);
@@ -59609,15 +59708,45 @@ function PropertiesPanel($$anchor, $$props) {
59609
59708
  if (!get(selectedFurniture)) return;
59610
59709
  updateFurniture(get(selectedFurniture).id, { rotation: Number(e.target.value) });
59611
59710
  }
59612
- function onFurnitureName(e) {
59613
- if (!get(selectedFurniture)) return;
59614
- updateFurniture(get(selectedFurniture).id, { name: e.target.value });
59615
- }
59711
+ const cameraPropEntries = /* @__PURE__ */ user_derived(() => {
59712
+ var _$$get$name, _$$get$serial;
59713
+ if (!get(selectedFurniture) || get(selectedFurniture).catalogId !== "camera") return [];
59714
+ const props = get(selectedFurniture).props;
59715
+ if (props && Object.keys(props).length > 0) {
59716
+ const keys = Object.keys(props);
59717
+ keys.sort((a, b) => {
59718
+ if (a === "serial") return -1;
59719
+ if (b === "serial") return 1;
59720
+ if (a === "name") return -1;
59721
+ if (b === "name") return 1;
59722
+ return a.localeCompare(b);
59723
+ });
59724
+ return keys.map((key) => {
59725
+ var _props$key;
59726
+ return {
59727
+ key,
59728
+ value: (_props$key = props[key]) !== null && _props$key !== void 0 ? _props$key : ""
59729
+ };
59730
+ });
59731
+ }
59732
+ return [{
59733
+ key: "name",
59734
+ value: (_$$get$name = get(selectedFurniture).name) !== null && _$$get$name !== void 0 ? _$$get$name : ""
59735
+ }, {
59736
+ key: "serial",
59737
+ value: (_$$get$serial = get(selectedFurniture).serial) !== null && _$$get$serial !== void 0 ? _$$get$serial : ""
59738
+ }];
59739
+ });
59740
+ /** Host-assigned camera fields are read-only; package fields (color/size/…) stay editable. */
59741
+ const cameraPropsLocked = /* @__PURE__ */ user_derived(() => {
59742
+ var _$$get13;
59743
+ return !!(((_$$get13 = get(selectedFurniture)) === null || _$$get13 === void 0 ? void 0 : _$$get13.catalogId) === "camera" && get(selectedFurniture).props && Object.keys(get(selectedFurniture).props).length > 0);
59744
+ });
59616
59745
  const useSiteCameraSelect = /* @__PURE__ */ user_derived(() => siteCameras().length > 0);
59617
59746
  const usedCameraSerials = /* @__PURE__ */ user_derived(() => {
59618
- var _$$get13;
59747
+ var _$$get14;
59619
59748
  const used = /* @__PURE__ */ new Set();
59620
- if (!((_$$get13 = get(floor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.furniture) || !get(selectedFurniture)) return used;
59749
+ if (!((_$$get14 = get(floor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.furniture) || !get(selectedFurniture)) return used;
59621
59750
  for (const item of get(floor).furniture) {
59622
59751
  if (item.catalogId !== "camera" || item.id === get(selectedFurniture).id) continue;
59623
59752
  if (item.serial) used.add(item.serial);
@@ -59625,20 +59754,21 @@ function PropertiesPanel($$anchor, $$props) {
59625
59754
  return used;
59626
59755
  });
59627
59756
  const selectableSiteCameras = /* @__PURE__ */ user_derived(() => {
59628
- var _$$get$serial;
59757
+ var _$$get$serial2;
59629
59758
  if (!get(selectedFurniture) || !get(useSiteCameraSelect)) return [];
59630
- const currentSerial = (_$$get$serial = get(selectedFurniture).serial) !== null && _$$get$serial !== void 0 ? _$$get$serial : "";
59759
+ const currentSerial = (_$$get$serial2 = get(selectedFurniture).serial) !== null && _$$get$serial2 !== void 0 ? _$$get$serial2 : "";
59631
59760
  const fromSite = siteCameras().filter((c) => !get(usedCameraSerials).has(c.serial) || c.serial === currentSerial);
59632
59761
  if (currentSerial && !fromSite.some((c) => c.serial === currentSerial)) {
59633
- var _$$get$name;
59762
+ var _$$get$name2;
59634
59763
  return [{
59635
59764
  serial: currentSerial,
59636
- name: (_$$get$name = get(selectedFurniture).name) !== null && _$$get$name !== void 0 ? _$$get$name : currentSerial
59765
+ name: (_$$get$name2 = get(selectedFurniture).name) !== null && _$$get$name2 !== void 0 ? _$$get$name2 : currentSerial
59637
59766
  }, ...fromSite];
59638
59767
  }
59639
59768
  return fromSite;
59640
59769
  });
59641
59770
  function onSiteCameraSelect(e) {
59771
+ var _$$get$props;
59642
59772
  if (!get(selectedFurniture)) return;
59643
59773
  const serial = e.target.value;
59644
59774
  if (!serial) {
@@ -59652,7 +59782,12 @@ function PropertiesPanel($$anchor, $$props) {
59652
59782
  if (!camera) return;
59653
59783
  updateFurniture(get(selectedFurniture).id, {
59654
59784
  serial: camera.serial,
59655
- name: camera.name
59785
+ name: camera.name,
59786
+ props: {
59787
+ ...(_$$get$props = get(selectedFurniture).props) !== null && _$$get$props !== void 0 ? _$$get$props : {},
59788
+ serial: camera.serial,
59789
+ name: camera.name
59790
+ }
59656
59791
  });
59657
59792
  }
59658
59793
  function resetFurnitureDefaults() {
@@ -59961,7 +60096,7 @@ function PropertiesPanel($$anchor, $$props) {
59961
60096
  var consequent = ($$anchor) => {
59962
60097
  const sideColor = /* @__PURE__ */ user_derived(() => get(selectedWall).interiorColor || get(selectedWall).color);
59963
60098
  const sideTex = /* @__PURE__ */ user_derived(() => get(selectedWall).interiorTexture === "none" ? void 0 : get(selectedWall).interiorTexture || get(selectedWall).texture);
59964
- var div_5 = root_2$6();
60099
+ var div_5 = root_2$7();
59965
60100
  var div_6 = sibling(child(div_5), 2);
59966
60101
  each(div_6, 21, () => wallColors, index$1, ($$anchor, wc) => {
59967
60102
  var button_3 = root_3$6();
@@ -60204,7 +60339,7 @@ function PropertiesPanel($$anchor, $$props) {
60204
60339
  reset(label_11);
60205
60340
  reset(div_11);
60206
60341
  template_effect(($0, $1, $2, $3, $4, $5, $6, $7) => {
60207
- var _$$get14, _$$get15, _$$get16, _$$get17;
60342
+ var _$$get15, _$$get16, _$$get17, _$$get18;
60208
60343
  set_text(text_6, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60209
60344
  set_value(input_5, $1);
60210
60345
  set_text(text_7, `Distance from A (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
@@ -60217,10 +60352,10 @@ function PropertiesPanel($$anchor, $$props) {
60217
60352
  var _select$__value;
60218
60353
  select.value = (_select$__value = select.__value = get(selectedDoor).type) !== null && _select$__value !== void 0 ? _select$__value : "", select_option(select, get(selectedDoor).type);
60219
60354
  }
60220
- set_class(button_9, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get14 = get(selectedDoor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.swingDirection) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60221
- set_class(button_10, 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) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60222
- set_class(button_11, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${!((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60223
- set_class(button_12, 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"}`);
60355
+ 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"}`);
60356
+ 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"}`);
60357
+ 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"}`);
60358
+ 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"}`);
60224
60359
  }, [
60225
60360
  () => unitLabel(),
60226
60361
  () => displayValue(get(selectedDoor).width),
@@ -60359,14 +60494,10 @@ function PropertiesPanel($$anchor, $$props) {
60359
60494
  var node_4 = child(div_15);
60360
60495
  var consequent_5 = ($$anchor) => {
60361
60496
  var fragment_4 = root_11$1();
60362
- var label_18 = first_child(fragment_4);
60363
- var input_14 = sibling(child(label_18), 2);
60364
- remove_input_defaults(input_14);
60365
- reset(label_18);
60366
- var node_5 = sibling(label_18, 2);
60497
+ var node_5 = first_child(fragment_4);
60367
60498
  var consequent_4 = ($$anchor) => {
60368
- var label_19 = root_12$1();
60369
- var select_2 = sibling(child(label_19), 2);
60499
+ var label_18 = root_12$1();
60500
+ var select_2 = sibling(child(label_18), 2);
60370
60501
  var option_11 = child(select_2);
60371
60502
  option_11.value = option_11.__value = "";
60372
60503
  each(sibling(option_11), 17, () => get(selectableSiteCameras), (cam) => cam.serial, ($$anchor, cam) => {
@@ -60375,8 +60506,8 @@ function PropertiesPanel($$anchor, $$props) {
60375
60506
  reset(option_12);
60376
60507
  var option_12_value = {};
60377
60508
  template_effect(() => {
60378
- var _$$get$name2, _$$get$serial2;
60379
- set_text(text_18, `${(_$$get$name2 = get(cam).name) !== null && _$$get$name2 !== void 0 ? _$$get$name2 : ""} (${(_$$get$serial2 = get(cam).serial) !== null && _$$get$serial2 !== void 0 ? _$$get$serial2 : ""})`);
60509
+ var _$$get$name3, _$$get$serial3;
60510
+ set_text(text_18, `${(_$$get$name3 = get(cam).name) !== null && _$$get$name3 !== void 0 ? _$$get$name3 : ""} (${(_$$get$serial3 = get(cam).serial) !== null && _$$get$serial3 !== void 0 ? _$$get$serial3 : ""})`);
60380
60511
  if (option_12_value !== (option_12_value = get(cam).serial)) {
60381
60512
  var _option_12$__value;
60382
60513
  option_12.value = (_option_12$__value = option_12.__value = get(cam).serial) !== null && _option_12$__value !== void 0 ? _option_12$__value : "";
@@ -60386,30 +60517,30 @@ function PropertiesPanel($$anchor, $$props) {
60386
60517
  });
60387
60518
  reset(select_2);
60388
60519
  select_2.value = select_2.__value = "";
60389
- reset(label_19);
60520
+ reset(label_18);
60390
60521
  delegated("change", select_2, onSiteCameraSelect);
60391
- append($$anchor, label_19);
60392
- };
60393
- var alternate_1 = ($$anchor) => {
60394
- var label_20 = root_14$1();
60395
- var input_15 = sibling(child(label_20), 2);
60396
- remove_input_defaults(input_15);
60397
- reset(label_20);
60398
- template_effect(() => {
60399
- var _$$get$serial3;
60400
- return set_value(input_15, (_$$get$serial3 = get(selectedFurniture).serial) !== null && _$$get$serial3 !== void 0 ? _$$get$serial3 : "");
60401
- });
60402
- append($$anchor, label_20);
60522
+ append($$anchor, label_18);
60403
60523
  };
60404
60524
  if_block(node_5, ($$render) => {
60405
60525
  if (get(useSiteCameraSelect) && !get(selectedFurniture).serial) $$render(consequent_4);
60406
- else $$render(alternate_1, -1);
60407
60526
  });
60408
- template_effect(() => {
60409
- var _$$get$name3;
60410
- return set_value(input_14, (_$$get$name3 = get(selectedFurniture).name) !== null && _$$get$name3 !== void 0 ? _$$get$name3 : "");
60527
+ each(sibling(node_5, 2), 17, () => get(cameraPropEntries), (field) => field.key, ($$anchor, field) => {
60528
+ var label_19 = root_14$1();
60529
+ var span_15 = child(label_19);
60530
+ var text_19 = child(span_15, true);
60531
+ reset(span_15);
60532
+ var input_14 = sibling(span_15, 2);
60533
+ remove_input_defaults(input_14);
60534
+ reset(label_19);
60535
+ template_effect(($0) => {
60536
+ set_text(text_19, $0);
60537
+ set_value(input_14, get(field).value);
60538
+ input_14.disabled = get(cameraPropsLocked) || get(field).key === "serial";
60539
+ input_14.readOnly = get(cameraPropsLocked) || get(field).key === "serial";
60540
+ set_class(input_14, 1, `w-full px-2 py-1 border border-gray-200 rounded text-sm bg-gray-50 text-gray-600 ${get(field).key === "serial" ? "font-mono" : ""}`);
60541
+ }, [() => formatCameraPropLabel(get(field).key)]);
60542
+ append($$anchor, label_19);
60411
60543
  });
60412
- delegated("input", input_14, onFurnitureName);
60413
60544
  append($$anchor, fragment_4);
60414
60545
  };
60415
60546
  if_block(node_4, ($$render) => {
@@ -60443,33 +60574,33 @@ function PropertiesPanel($$anchor, $$props) {
60443
60574
  });
60444
60575
  reset(div_17);
60445
60576
  var div_18 = sibling(div_17, 2);
60446
- var input_16 = sibling(child(div_18), 2);
60447
- remove_input_defaults(input_16);
60577
+ var input_15 = sibling(child(div_18), 2);
60578
+ remove_input_defaults(input_15);
60448
60579
  reset(div_18);
60449
60580
  reset(div_16);
60450
- var label_21 = sibling(div_16, 2);
60451
- var span_15 = child(label_21);
60452
- var text_19 = child(span_15);
60453
- reset(span_15);
60454
- var input_17 = sibling(span_15, 2);
60581
+ var label_20 = sibling(div_16, 2);
60582
+ var span_16 = child(label_20);
60583
+ var text_20 = child(span_16);
60584
+ reset(span_16);
60585
+ var input_16 = sibling(span_16, 2);
60586
+ remove_input_defaults(input_16);
60587
+ reset(label_20);
60588
+ var label_21 = sibling(label_20, 2);
60589
+ var span_17 = child(label_21);
60590
+ var text_21 = child(span_17);
60591
+ reset(span_17);
60592
+ var input_17 = sibling(span_17, 2);
60455
60593
  remove_input_defaults(input_17);
60456
60594
  reset(label_21);
60457
60595
  var label_22 = sibling(label_21, 2);
60458
- var span_16 = child(label_22);
60459
- var text_20 = child(span_16);
60460
- reset(span_16);
60461
- var input_18 = sibling(span_16, 2);
60596
+ var span_18 = child(label_22);
60597
+ var text_22 = child(span_18);
60598
+ reset(span_18);
60599
+ var input_18 = sibling(span_18, 2);
60462
60600
  remove_input_defaults(input_18);
60463
60601
  reset(label_22);
60464
60602
  var label_23 = sibling(label_22, 2);
60465
- var span_17 = child(label_23);
60466
- var text_21 = child(span_17);
60467
- reset(span_17);
60468
- var input_19 = sibling(span_17, 2);
60469
- remove_input_defaults(input_19);
60470
- reset(label_23);
60471
- var label_24 = sibling(label_23, 2);
60472
- var select_3 = sibling(child(label_24), 2);
60603
+ var select_3 = sibling(child(label_23), 2);
60473
60604
  var option_13 = child(select_3);
60474
60605
  option_13.value = option_13.__value = "Wood";
60475
60606
  var option_14 = sibling(option_13);
@@ -60489,12 +60620,12 @@ function PropertiesPanel($$anchor, $$props) {
60489
60620
  reset(select_3);
60490
60621
  var select_3_value;
60491
60622
  init_select(select_3);
60623
+ reset(label_23);
60624
+ var label_24 = sibling(label_23, 2);
60625
+ var input_19 = sibling(child(label_24), 2);
60626
+ remove_input_defaults(input_19);
60492
60627
  reset(label_24);
60493
- var label_25 = sibling(label_24, 2);
60494
- var input_20 = sibling(child(label_25), 2);
60495
- remove_input_defaults(input_20);
60496
- reset(label_25);
60497
- var div_19 = sibling(label_25, 2);
60628
+ var div_19 = sibling(label_24, 2);
60498
60629
  var button_15 = child(div_19);
60499
60630
  var button_16 = sibling(button_15, 2);
60500
60631
  reset(div_19);
@@ -60511,18 +60642,18 @@ function PropertiesPanel($$anchor, $$props) {
60511
60642
  set_class(button_13, 1, `ml-auto px-1.5 py-0.5 rounded text-xs border transition-colors ${get(selectedFurniture).locked ? "bg-amber-100 border-amber-400 text-amber-700" : "border-gray-200 hover:bg-gray-50 text-gray-500"}`);
60512
60643
  set_attribute(button_13, "title", get(selectedFurniture).locked ? "Unlock (Ctrl+L)" : "Lock (Ctrl+L)");
60513
60644
  set_text(text_17, get(selectedFurniture).locked ? "🔒 Locked" : "🔓");
60514
- set_value(input_16, $2);
60515
- set_text(text_19, `Width (${$3 !== null && $3 !== void 0 ? $3 : ""})`);
60516
- set_value(input_17, $4);
60517
- set_text(text_20, `Depth (${$5 !== null && $5 !== void 0 ? $5 : ""})`);
60518
- set_value(input_18, $6);
60519
- set_text(text_21, `Height (${$7 !== null && $7 !== void 0 ? $7 : ""})`);
60520
- set_value(input_19, $8);
60645
+ set_value(input_15, $2);
60646
+ set_text(text_20, `Width (${$3 !== null && $3 !== void 0 ? $3 : ""})`);
60647
+ set_value(input_16, $4);
60648
+ set_text(text_21, `Depth (${$5 !== null && $5 !== void 0 ? $5 : ""})`);
60649
+ set_value(input_17, $6);
60650
+ set_text(text_22, `Height (${$7 !== null && $7 !== void 0 ? $7 : ""})`);
60651
+ set_value(input_18, $8);
60521
60652
  if (select_3_value !== (select_3_value = (_$$get$material = get(selectedFurniture).material) !== null && _$$get$material !== void 0 ? _$$get$material : "Wood")) {
60522
60653
  var _select_3$__value, _$$get$material2, _$$get$material3;
60523
60654
  select_3.value = (_select_3$__value = select_3.__value = (_$$get$material2 = get(selectedFurniture).material) !== null && _$$get$material2 !== void 0 ? _$$get$material2 : "Wood") !== null && _select_3$__value !== void 0 ? _select_3$__value : "", select_option(select_3, (_$$get$material3 = get(selectedFurniture).material) !== null && _$$get$material3 !== void 0 ? _$$get$material3 : "Wood");
60524
60655
  }
60525
- set_value(input_20, $9);
60656
+ set_value(input_19, $9);
60526
60657
  }, [
60527
60658
  () => {
60528
60659
  var _getCatalogItem$icon, _getCatalogItem2;
@@ -60556,12 +60687,12 @@ function PropertiesPanel($$anchor, $$props) {
60556
60687
  delegated("click", button_13, () => {
60557
60688
  if (get(selectedFurniture)) toggleFurnitureLock(get(selectedFurniture).id);
60558
60689
  });
60559
- delegated("input", input_16, (e) => onFurnitureColor(e.target.value));
60560
- delegated("input", input_17, onFurnitureWidth);
60561
- delegated("input", input_18, onFurnitureDepth);
60562
- delegated("input", input_19, onFurnitureHeight);
60690
+ delegated("input", input_15, (e) => onFurnitureColor(e.target.value));
60691
+ delegated("input", input_16, onFurnitureWidth);
60692
+ delegated("input", input_17, onFurnitureDepth);
60693
+ delegated("input", input_18, onFurnitureHeight);
60563
60694
  delegated("change", select_3, onFurnitureMaterial);
60564
- delegated("input", input_20, onFurnitureRotation);
60695
+ delegated("input", input_19, onFurnitureRotation);
60565
60696
  delegated("click", button_15, () => {
60566
60697
  if (get(selectedFurniture)) updateFurniture(get(selectedFurniture).id, { rotation: get(selectedFurniture).rotation - 90 });
60567
60698
  });
@@ -60594,35 +60725,35 @@ function PropertiesPanel($$anchor, $$props) {
60594
60725
  var consequent_9 = ($$anchor) => {
60595
60726
  var fragment_5 = root_16();
60596
60727
  var div_21 = sibling(first_child(fragment_5), 2);
60597
- var node_7 = child(div_21);
60728
+ var node_8 = child(div_21);
60598
60729
  var consequent_7 = ($$anchor) => {
60599
- var label_26 = root_17$1();
60600
- var span_18 = child(label_26);
60601
- var text_22 = child(span_18);
60602
- reset(span_18);
60603
- var input_21 = sibling(span_18, 2);
60604
- remove_input_defaults(input_21);
60605
- reset(label_26);
60730
+ var label_25 = root_17$1();
60731
+ var span_19 = child(label_25);
60732
+ var text_23 = child(span_19);
60733
+ reset(span_19);
60734
+ var input_20 = sibling(span_19, 2);
60735
+ remove_input_defaults(input_20);
60736
+ reset(label_25);
60606
60737
  template_effect(($0) => {
60607
- set_text(text_22, `Camera Thumbnail Opacity (${$0 !== null && $0 !== void 0 ? $0 : ""}%)`);
60608
- set_value(input_21, get(thumbOpacity));
60738
+ set_text(text_23, `Camera Thumbnail Opacity (${$0 !== null && $0 !== void 0 ? $0 : ""}%)`);
60739
+ set_value(input_20, get(thumbOpacity));
60609
60740
  }, [() => Math.round(get(thumbOpacity) * 100)]);
60610
- delegated("input", input_21, (e) => updateCameraThumbnailOpacity(Number(e.target.value)));
60611
- append($$anchor, label_26);
60741
+ delegated("input", input_20, (e) => updateCameraThumbnailOpacity(Number(e.target.value)));
60742
+ append($$anchor, label_25);
60612
60743
  };
60613
- if_block(node_7, ($$render) => {
60744
+ if_block(node_8, ($$render) => {
60614
60745
  if (get(hasCameraThumbnailOverlay)) $$render(consequent_7);
60615
60746
  });
60616
- var label_27 = sibling(node_7, 2);
60617
- var select_4 = sibling(child(label_27), 2);
60747
+ var label_26 = sibling(node_8, 2);
60748
+ var select_4 = sibling(child(label_26), 2);
60618
60749
  each(select_4, 21, () => roomTypes, index$1, ($$anchor, rt) => {
60619
60750
  var option_21 = root_18$1();
60620
- var text_23 = child(option_21);
60751
+ var text_24 = child(option_21);
60621
60752
  reset(option_21);
60622
60753
  var option_21_value = {};
60623
60754
  template_effect(() => {
60624
60755
  var _$$get$icon, _$$get$label;
60625
- set_text(text_23, `${(_$$get$icon = get(rt).icon) !== null && _$$get$icon !== void 0 ? _$$get$icon : ""} ${(_$$get$label = get(rt).label) !== null && _$$get$label !== void 0 ? _$$get$label : ""}`);
60756
+ set_text(text_24, `${(_$$get$icon = get(rt).icon) !== null && _$$get$icon !== void 0 ? _$$get$icon : ""} ${(_$$get$label = get(rt).label) !== null && _$$get$label !== void 0 ? _$$get$label : ""}`);
60626
60757
  if (option_21_value !== (option_21_value = get(rt).id)) {
60627
60758
  var _option_21$__value;
60628
60759
  option_21.value = (_option_21$__value = option_21.__value = get(rt).id) !== null && _option_21$__value !== void 0 ? _option_21$__value : "";
@@ -60633,13 +60764,13 @@ function PropertiesPanel($$anchor, $$props) {
60633
60764
  reset(select_4);
60634
60765
  var select_4_value;
60635
60766
  init_select(select_4);
60767
+ reset(label_26);
60768
+ var label_27 = sibling(label_26, 2);
60769
+ var input_21 = sibling(child(label_27), 2);
60770
+ remove_input_defaults(input_21);
60636
60771
  reset(label_27);
60637
60772
  var label_28 = sibling(label_27, 2);
60638
- var input_22 = sibling(child(label_28), 2);
60639
- remove_input_defaults(input_22);
60640
- reset(label_28);
60641
- var label_29 = sibling(label_28, 2);
60642
- var select_5 = sibling(child(label_29), 2);
60773
+ var select_5 = sibling(child(label_28), 2);
60643
60774
  var option_22 = child(select_5);
60644
60775
  option_22.value = option_22.__value = "indoor";
60645
60776
  var option_23 = sibling(option_22);
@@ -60651,10 +60782,10 @@ function PropertiesPanel($$anchor, $$props) {
60651
60782
  reset(select_5);
60652
60783
  var select_5_value;
60653
60784
  init_select(select_5);
60654
- reset(label_29);
60655
- var div_22 = sibling(label_29, 2);
60785
+ reset(label_28);
60786
+ var div_22 = sibling(label_28, 2);
60656
60787
  var p = sibling(child(div_22), 2);
60657
- var text_24 = child(p, true);
60788
+ var text_25 = child(p, true);
60658
60789
  reset(p);
60659
60790
  reset(div_22);
60660
60791
  var div_23 = sibling(div_22, 2);
@@ -60672,22 +60803,22 @@ function PropertiesPanel($$anchor, $$props) {
60672
60803
  });
60673
60804
  reset(div_24);
60674
60805
  var div_25 = sibling(div_24, 2);
60675
- var input_23 = sibling(child(div_25), 2);
60676
- remove_input_defaults(input_23);
60806
+ var input_22 = sibling(child(div_25), 2);
60807
+ remove_input_defaults(input_22);
60677
60808
  reset(div_25);
60678
60809
  reset(div_23);
60679
60810
  var div_26 = sibling(div_23, 2);
60680
60811
  var div_27 = sibling(child(div_26), 2);
60681
60812
  each(div_27, 21, () => textureGroups, index$1, ($$anchor, group) => {
60682
60813
  var div_28 = root_20$1();
60683
- var span_19 = child(div_28);
60684
- var text_25 = child(span_19, true);
60685
- reset(span_19);
60686
- var div_29 = sibling(span_19, 2);
60814
+ var span_20 = child(div_28);
60815
+ var text_26 = child(span_20, true);
60816
+ reset(span_20);
60817
+ var div_29 = sibling(span_20, 2);
60687
60818
  each(div_29, 21, () => get(group).ids, index$1, ($$anchor, matId) => {
60688
60819
  const mat = /* @__PURE__ */ user_derived(() => floorMaterials.find((m) => m.id === get(matId)));
60689
60820
  var fragment_6 = comment();
60690
- var node_8 = first_child(fragment_6);
60821
+ var node_9 = first_child(fragment_6);
60691
60822
  var consequent_8 = ($$anchor) => {
60692
60823
  const texPath = /* @__PURE__ */ user_derived(() => {
60693
60824
  var _floorTexPaths$$$get$;
@@ -60696,26 +60827,26 @@ function PropertiesPanel($$anchor, $$props) {
60696
60827
  var button_21 = root_22$1();
60697
60828
  var div_30 = child(button_21);
60698
60829
  var div_31 = sibling(div_30, 2);
60699
- var text_26 = child(div_31, true);
60830
+ var text_27 = child(div_31, true);
60700
60831
  reset(div_31);
60701
60832
  reset(button_21);
60702
60833
  template_effect(() => {
60703
60834
  set_class(button_21, 1, `p-1 rounded-lg border-2 hover:border-gray-300 transition-all text-xs ${get(selectedRoom).floorTexture === get(mat).id ? "border-blue-500 ring-2 ring-blue-200 shadow-sm" : "border-gray-200"}`);
60704
60835
  set_attribute(button_21, "title", get(mat).name);
60705
60836
  set_style(div_30, get(texPath) ? `background-image: url(${get(texPath)}); background-size: cover; background-position: center;` : `background-color: ${get(mat).color}`);
60706
- set_text(text_26, get(mat).name);
60837
+ set_text(text_27, get(mat).name);
60707
60838
  });
60708
60839
  delegated("click", button_21, () => onRoomFloor(get(mat).id));
60709
60840
  append($$anchor, button_21);
60710
60841
  };
60711
- if_block(node_8, ($$render) => {
60842
+ if_block(node_9, ($$render) => {
60712
60843
  if (get(mat)) $$render(consequent_8);
60713
60844
  });
60714
60845
  append($$anchor, fragment_6);
60715
60846
  });
60716
60847
  reset(div_29);
60717
60848
  reset(div_28);
60718
- template_effect(() => set_text(text_25, get(group).label));
60849
+ template_effect(() => set_text(text_26, get(group).label));
60719
60850
  append($$anchor, div_28);
60720
60851
  });
60721
60852
  reset(div_27);
@@ -60727,16 +60858,16 @@ function PropertiesPanel($$anchor, $$props) {
60727
60858
  var _select_4$__value;
60728
60859
  select_4.value = (_select_4$__value = select_4.__value = get(selectedRoomType)) !== null && _select_4$__value !== void 0 ? _select_4$__value : "", select_option(select_4, get(selectedRoomType));
60729
60860
  }
60730
- set_value(input_22, get(selectedRoom).name);
60861
+ set_value(input_21, get(selectedRoom).name);
60731
60862
  if (select_5_value !== (select_5_value = (_$$get$roomType = get(selectedRoom).roomType) !== null && _$$get$roomType !== void 0 ? _$$get$roomType : "indoor")) {
60732
60863
  var _select_5$__value, _$$get$roomType2, _$$get$roomType3;
60733
60864
  select_5.value = (_select_5$__value = select_5.__value = (_$$get$roomType2 = get(selectedRoom).roomType) !== null && _$$get$roomType2 !== void 0 ? _$$get$roomType2 : "indoor") !== null && _select_5$__value !== void 0 ? _select_5$__value : "", select_option(select_5, (_$$get$roomType3 = get(selectedRoom).roomType) !== null && _$$get$roomType3 !== void 0 ? _$$get$roomType3 : "indoor");
60734
60865
  }
60735
- set_text(text_24, $0);
60736
- set_value(input_23, (_$$get$color6 = get(selectedRoom).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : "#ffffff");
60866
+ set_text(text_25, $0);
60867
+ set_value(input_22, (_$$get$color6 = get(selectedRoom).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : "#ffffff");
60737
60868
  }, [() => formatArea(get(selectedRoom).area, get(settings).units)]);
60738
60869
  delegated("change", select_4, onRoomType);
60739
- delegated("input", input_22, onRoomName);
60870
+ delegated("input", input_21, onRoomName);
60740
60871
  delegated("change", select_5, (e) => {
60741
60872
  if (get(selectedRoom)) {
60742
60873
  const v = e.target.value;
@@ -60744,14 +60875,14 @@ function PropertiesPanel($$anchor, $$props) {
60744
60875
  updateDetectedRoom(get(selectedRoom).id, { roomType: v });
60745
60876
  }
60746
60877
  });
60747
- delegated("input", input_23, (e) => onRoomColor(e.target.value));
60878
+ delegated("input", input_22, (e) => onRoomColor(e.target.value));
60748
60879
  append($$anchor, fragment_5);
60749
60880
  };
60750
60881
  var consequent_10 = ($$anchor) => {
60751
60882
  var fragment_7 = root_23$1();
60752
60883
  var div_32 = sibling(first_child(fragment_7), 2);
60753
- var label_30 = child(div_32);
60754
- var select_6 = sibling(child(label_30), 2);
60884
+ var label_29 = child(div_32);
60885
+ var select_6 = sibling(child(label_29), 2);
60755
60886
  var option_26 = child(select_6);
60756
60887
  option_26.value = option_26.__value = "straight";
60757
60888
  var option_27 = sibling(option_26);
@@ -60763,49 +60894,49 @@ function PropertiesPanel($$anchor, $$props) {
60763
60894
  reset(select_6);
60764
60895
  var select_6_value;
60765
60896
  init_select(select_6);
60897
+ reset(label_29);
60898
+ var label_30 = sibling(label_29, 2);
60899
+ var span_21 = child(label_30);
60900
+ var text_28 = child(span_21);
60901
+ reset(span_21);
60902
+ var input_23 = sibling(span_21, 2);
60903
+ remove_input_defaults(input_23);
60766
60904
  reset(label_30);
60767
60905
  var label_31 = sibling(label_30, 2);
60768
- var span_20 = child(label_31);
60769
- var text_27 = child(span_20);
60770
- reset(span_20);
60771
- var input_24 = sibling(span_20, 2);
60906
+ var span_22 = child(label_31);
60907
+ var text_29 = child(span_22);
60908
+ reset(span_22);
60909
+ var input_24 = sibling(span_22, 2);
60772
60910
  remove_input_defaults(input_24);
60773
60911
  reset(label_31);
60774
60912
  var label_32 = sibling(label_31, 2);
60775
- var span_21 = child(label_32);
60776
- var text_28 = child(span_21);
60777
- reset(span_21);
60778
- var input_25 = sibling(span_21, 2);
60913
+ var input_25 = sibling(child(label_32), 2);
60779
60914
  remove_input_defaults(input_25);
60780
60915
  reset(label_32);
60781
60916
  var label_33 = sibling(label_32, 2);
60782
- var input_26 = sibling(child(label_33), 2);
60783
- remove_input_defaults(input_26);
60784
- reset(label_33);
60785
- var label_34 = sibling(label_33, 2);
60786
- var div_33 = sibling(child(label_34), 2);
60917
+ var div_33 = sibling(child(label_33), 2);
60787
60918
  var button_22 = child(div_33);
60788
60919
  var button_23 = sibling(button_22, 2);
60789
60920
  reset(div_33);
60921
+ reset(label_33);
60922
+ var label_34 = sibling(label_33, 2);
60923
+ var input_26 = sibling(child(label_34), 2);
60924
+ remove_input_defaults(input_26);
60790
60925
  reset(label_34);
60791
- var label_35 = sibling(label_34, 2);
60792
- var input_27 = sibling(child(label_35), 2);
60793
- remove_input_defaults(input_27);
60794
- reset(label_35);
60795
60926
  reset(div_32);
60796
60927
  template_effect(($0, $1, $2, $3) => {
60797
60928
  if (select_6_value !== (select_6_value = get(selectedStair).stairType || "straight")) {
60798
60929
  var _select_6$__value;
60799
60930
  select_6.value = (_select_6$__value = select_6.__value = get(selectedStair).stairType || "straight") !== null && _select_6$__value !== void 0 ? _select_6$__value : "", select_option(select_6, get(selectedStair).stairType || "straight");
60800
60931
  }
60801
- set_text(text_27, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60802
- set_value(input_24, $1);
60803
- set_text(text_28, `Depth (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60804
- set_value(input_25, $3);
60805
- set_value(input_26, get(selectedStair).riserCount);
60932
+ set_text(text_28, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60933
+ set_value(input_23, $1);
60934
+ set_text(text_29, `Depth (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60935
+ set_value(input_24, $3);
60936
+ set_value(input_25, get(selectedStair).riserCount);
60806
60937
  set_class(button_22, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedStair).direction === "up" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60807
60938
  set_class(button_23, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedStair).direction === "down" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60808
- set_value(input_27, get(selectedStair).rotation);
60939
+ set_value(input_26, get(selectedStair).rotation);
60809
60940
  }, [
60810
60941
  () => unitLabel(),
60811
60942
  () => displayValue(get(selectedStair).width),
@@ -60813,38 +60944,38 @@ function PropertiesPanel($$anchor, $$props) {
60813
60944
  () => displayValue(get(selectedStair).depth)
60814
60945
  ]);
60815
60946
  delegated("change", select_6, (e) => updateStair(get(selectedStair).id, { stairType: e.target.value }));
60816
- delegated("input", input_24, (e) => updateStair(get(selectedStair).id, { width: inputToCm(Number(e.target.value)) }));
60817
- delegated("input", input_25, (e) => updateStair(get(selectedStair).id, { depth: inputToCm(Number(e.target.value)) }));
60818
- delegated("input", input_26, (e) => updateStair(get(selectedStair).id, { riserCount: Number(e.target.value) }));
60947
+ delegated("input", input_23, (e) => updateStair(get(selectedStair).id, { width: inputToCm(Number(e.target.value)) }));
60948
+ delegated("input", input_24, (e) => updateStair(get(selectedStair).id, { depth: inputToCm(Number(e.target.value)) }));
60949
+ delegated("input", input_25, (e) => updateStair(get(selectedStair).id, { riserCount: Number(e.target.value) }));
60819
60950
  delegated("click", button_22, () => updateStair(get(selectedStair).id, { direction: "up" }));
60820
60951
  delegated("click", button_23, () => updateStair(get(selectedStair).id, { direction: "down" }));
60821
- delegated("input", input_27, (e) => updateStair(get(selectedStair).id, { rotation: Number(e.target.value) }));
60952
+ delegated("input", input_26, (e) => updateStair(get(selectedStair).id, { rotation: Number(e.target.value) }));
60822
60953
  append($$anchor, fragment_7);
60823
60954
  };
60824
60955
  var consequent_12 = ($$anchor) => {
60825
60956
  var fragment_8 = root_24$1();
60826
60957
  var div_34 = sibling(first_child(fragment_8), 2);
60827
- var label_36 = child(div_34);
60828
- var div_35 = sibling(child(label_36), 2);
60958
+ var label_35 = child(div_34);
60959
+ var div_35 = sibling(child(label_35), 2);
60829
60960
  var button_24 = child(div_35);
60830
60961
  var button_25 = sibling(button_24, 2);
60831
60962
  reset(div_35);
60963
+ reset(label_35);
60964
+ var label_36 = sibling(label_35, 2);
60965
+ var span_23 = child(label_36);
60966
+ var text_30 = child(span_23);
60967
+ reset(span_23);
60968
+ var input_27 = sibling(span_23, 2);
60969
+ remove_input_defaults(input_27);
60832
60970
  reset(label_36);
60833
60971
  var label_37 = sibling(label_36, 2);
60834
- var span_22 = child(label_37);
60835
- var text_29 = child(span_22);
60836
- reset(span_22);
60837
- var input_28 = sibling(span_22, 2);
60972
+ var span_24 = child(label_37);
60973
+ var text_31 = child(span_24);
60974
+ reset(span_24);
60975
+ var input_28 = sibling(span_24, 2);
60838
60976
  remove_input_defaults(input_28);
60839
60977
  reset(label_37);
60840
- var label_38 = sibling(label_37, 2);
60841
- var span_23 = child(label_38);
60842
- var text_30 = child(span_23);
60843
- reset(span_23);
60844
- var input_29 = sibling(span_23, 2);
60845
- remove_input_defaults(input_29);
60846
- reset(label_38);
60847
- var div_36 = sibling(label_38, 2);
60978
+ var div_36 = sibling(label_37, 2);
60848
60979
  var div_37 = sibling(child(div_36), 2);
60849
60980
  each(div_37, 21, () => columnColorPresets, index$1, ($$anchor, preset) => {
60850
60981
  var button_26 = root_25();
@@ -60859,32 +60990,32 @@ function PropertiesPanel($$anchor, $$props) {
60859
60990
  });
60860
60991
  reset(div_37);
60861
60992
  var div_38 = sibling(div_37, 2);
60862
- var input_30 = sibling(child(div_38), 2);
60863
- remove_input_defaults(input_30);
60993
+ var input_29 = sibling(child(div_38), 2);
60994
+ remove_input_defaults(input_29);
60864
60995
  reset(div_38);
60865
60996
  reset(div_36);
60866
- var node_9 = sibling(div_36, 2);
60997
+ var node_10 = sibling(div_36, 2);
60867
60998
  var consequent_11 = ($$anchor) => {
60868
- var label_39 = root_26();
60869
- var input_31 = sibling(child(label_39), 2);
60870
- remove_input_defaults(input_31);
60871
- reset(label_39);
60872
- template_effect(() => set_value(input_31, get(selectedColumn).rotation));
60873
- delegated("input", input_31, (e) => updateColumn(get(selectedColumn).id, { rotation: Number(e.target.value) }));
60874
- append($$anchor, label_39);
60999
+ var label_38 = root_26();
61000
+ var input_30 = sibling(child(label_38), 2);
61001
+ remove_input_defaults(input_30);
61002
+ reset(label_38);
61003
+ template_effect(() => set_value(input_30, get(selectedColumn).rotation));
61004
+ delegated("input", input_30, (e) => updateColumn(get(selectedColumn).id, { rotation: Number(e.target.value) }));
61005
+ append($$anchor, label_38);
60875
61006
  };
60876
- if_block(node_9, ($$render) => {
61007
+ if_block(node_10, ($$render) => {
60877
61008
  if (get(selectedColumn).shape === "square") $$render(consequent_11);
60878
61009
  });
60879
61010
  reset(div_34);
60880
61011
  template_effect(($0, $1, $2, $3) => {
60881
61012
  set_class(button_24, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedColumn).shape === "round" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60882
61013
  set_class(button_25, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedColumn).shape === "square" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60883
- set_text(text_29, `${get(selectedColumn).shape === "round" ? "Diameter" : "Side Length"} (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60884
- set_value(input_28, $1);
60885
- set_text(text_30, `Height (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60886
- set_value(input_29, $3);
60887
- set_value(input_30, get(selectedColumn).color);
61014
+ set_text(text_30, `${get(selectedColumn).shape === "round" ? "Diameter" : "Side Length"} (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
61015
+ set_value(input_27, $1);
61016
+ set_text(text_31, `Height (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
61017
+ set_value(input_28, $3);
61018
+ set_value(input_29, get(selectedColumn).color);
60888
61019
  }, [
60889
61020
  () => unitLabel(),
60890
61021
  () => displayValue(get(selectedColumn).diameter),
@@ -60893,29 +61024,33 @@ function PropertiesPanel($$anchor, $$props) {
60893
61024
  ]);
60894
61025
  delegated("click", button_24, () => updateColumn(get(selectedColumn).id, { shape: "round" }));
60895
61026
  delegated("click", button_25, () => updateColumn(get(selectedColumn).id, { shape: "square" }));
60896
- delegated("input", input_28, (e) => updateColumn(get(selectedColumn).id, { diameter: inputToCm(Number(e.target.value)) }));
60897
- delegated("input", input_29, (e) => updateColumn(get(selectedColumn).id, { height: inputToCm(Number(e.target.value)) }));
60898
- delegated("input", input_30, (e) => updateColumn(get(selectedColumn).id, { color: e.target.value }));
61027
+ delegated("input", input_27, (e) => updateColumn(get(selectedColumn).id, { diameter: inputToCm(Number(e.target.value)) }));
61028
+ delegated("input", input_28, (e) => updateColumn(get(selectedColumn).id, { height: inputToCm(Number(e.target.value)) }));
61029
+ delegated("input", input_29, (e) => updateColumn(get(selectedColumn).id, { color: e.target.value }));
60899
61030
  append($$anchor, fragment_8);
60900
61031
  };
60901
61032
  var consequent_13 = ($$anchor) => {
60902
61033
  var div_39 = root_27();
60903
- var label_40 = sibling(child(div_39), 2);
61034
+ var label_39 = sibling(child(div_39), 2);
61035
+ var input_31 = sibling(child(label_39), 2);
61036
+ remove_input_defaults(input_31);
61037
+ reset(label_39);
61038
+ var label_40 = sibling(label_39, 2);
60904
61039
  var input_32 = sibling(child(label_40), 2);
60905
61040
  remove_input_defaults(input_32);
60906
61041
  reset(label_40);
60907
61042
  var label_41 = sibling(label_40, 2);
60908
- var input_33 = sibling(child(label_41), 2);
61043
+ var div_40 = sibling(child(label_41), 2);
61044
+ var input_33 = child(div_40);
60909
61045
  remove_input_defaults(input_33);
61046
+ var span_25 = sibling(input_33, 2);
61047
+ var text_32 = child(span_25, true);
61048
+ reset(span_25);
61049
+ reset(div_40);
60910
61050
  reset(label_41);
60911
61051
  var label_42 = sibling(label_41, 2);
60912
- var div_40 = sibling(child(label_42), 2);
60913
- var input_34 = child(div_40);
61052
+ var input_34 = sibling(child(label_42), 2);
60914
61053
  remove_input_defaults(input_34);
60915
- var span_24 = sibling(input_34, 2);
60916
- var text_31 = child(span_24, true);
60917
- reset(span_24);
60918
- reset(div_40);
60919
61054
  reset(label_42);
60920
61055
  var label_43 = sibling(label_42, 2);
60921
61056
  var input_35 = sibling(child(label_43), 2);
@@ -60925,26 +61060,22 @@ function PropertiesPanel($$anchor, $$props) {
60925
61060
  var input_36 = sibling(child(label_44), 2);
60926
61061
  remove_input_defaults(input_36);
60927
61062
  reset(label_44);
60928
- var label_45 = sibling(label_44, 2);
60929
- var input_37 = sibling(child(label_45), 2);
60930
- remove_input_defaults(input_37);
60931
- reset(label_45);
60932
61063
  reset(div_39);
60933
61064
  template_effect(($0, $1) => {
60934
- set_value(input_32, get(selectedTextAnnotation).text);
60935
- set_value(input_33, get(selectedTextAnnotation).fontSize);
60936
- set_value(input_34, get(selectedTextAnnotation).color);
60937
- set_text(text_31, get(selectedTextAnnotation).color);
60938
- set_value(input_35, get(selectedTextAnnotation).rotation);
60939
- set_value(input_36, $0);
60940
- set_value(input_37, $1);
61065
+ set_value(input_31, get(selectedTextAnnotation).text);
61066
+ set_value(input_32, get(selectedTextAnnotation).fontSize);
61067
+ set_value(input_33, get(selectedTextAnnotation).color);
61068
+ set_text(text_32, get(selectedTextAnnotation).color);
61069
+ set_value(input_34, get(selectedTextAnnotation).rotation);
61070
+ set_value(input_35, $0);
61071
+ set_value(input_36, $1);
60941
61072
  }, [() => Math.round(get(selectedTextAnnotation).x), () => Math.round(get(selectedTextAnnotation).y)]);
60942
- delegated("input", input_32, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { text: e.target.value }));
60943
- delegated("input", input_33, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { fontSize: Number(e.target.value) }));
60944
- delegated("input", input_34, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { color: e.target.value }));
60945
- delegated("input", input_35, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
60946
- delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
60947
- delegated("input", input_37, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
61073
+ delegated("input", input_31, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { text: e.target.value }));
61074
+ delegated("input", input_32, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { fontSize: Number(e.target.value) }));
61075
+ delegated("input", input_33, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { color: e.target.value }));
61076
+ delegated("input", input_34, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
61077
+ delegated("input", input_35, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
61078
+ delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
60948
61079
  append($$anchor, div_39);
60949
61080
  };
60950
61081
  if_block(node, ($$render) => {
@@ -60957,11 +61088,15 @@ function PropertiesPanel($$anchor, $$props) {
60957
61088
  else if (get(selectedColumn)) $$render(consequent_12, 6);
60958
61089
  else if (get(selectedTextAnnotation)) $$render(consequent_13, 7);
60959
61090
  });
60960
- var node_10 = sibling(node, 2);
61091
+ var node_11 = sibling(node, 2);
60961
61092
  var consequent_14 = ($$anchor) => {
60962
61093
  var div_41 = root_28();
60963
61094
  var div_42 = sibling(child(div_41), 2);
60964
- var label_46 = child(div_42);
61095
+ var label_45 = child(div_42);
61096
+ var input_37 = sibling(child(label_45), 2);
61097
+ remove_input_defaults(input_37);
61098
+ reset(label_45);
61099
+ var label_46 = sibling(label_45, 2);
60965
61100
  var input_38 = sibling(child(label_46), 2);
60966
61101
  remove_input_defaults(input_38);
60967
61102
  reset(label_46);
@@ -60969,13 +61104,9 @@ function PropertiesPanel($$anchor, $$props) {
60969
61104
  var input_39 = sibling(child(label_47), 2);
60970
61105
  remove_input_defaults(input_39);
60971
61106
  reset(label_47);
60972
- var label_48 = sibling(label_47, 2);
60973
- var input_40 = sibling(child(label_48), 2);
60974
- remove_input_defaults(input_40);
60975
- reset(label_48);
60976
- var div_43 = sibling(label_48, 2);
61107
+ var div_43 = sibling(label_47, 2);
60977
61108
  var button_27 = child(div_43);
60978
- var text_32 = child(button_27, true);
61109
+ var text_33 = child(button_27, true);
60979
61110
  reset(button_27);
60980
61111
  var button_28 = sibling(button_27, 2);
60981
61112
  reset(div_43);
@@ -60983,15 +61114,15 @@ function PropertiesPanel($$anchor, $$props) {
60983
61114
  reset(div_42);
60984
61115
  reset(div_41);
60985
61116
  template_effect(() => {
60986
- set_value(input_38, get(floor).backgroundImage.opacity);
60987
- set_value(input_39, get(floor).backgroundImage.scale);
60988
- set_value(input_40, get(floor).backgroundImage.rotation);
61117
+ set_value(input_37, get(floor).backgroundImage.opacity);
61118
+ set_value(input_38, get(floor).backgroundImage.scale);
61119
+ set_value(input_39, get(floor).backgroundImage.rotation);
60989
61120
  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"}`);
60990
- set_text(text_32, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
61121
+ set_text(text_33, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
60991
61122
  });
60992
- delegated("input", input_38, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
60993
- delegated("input", input_39, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
60994
- delegated("input", input_40, (e) => updateBackgroundImage({ rotation: Number(e.target.value) }));
61123
+ delegated("input", input_37, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
61124
+ delegated("input", input_38, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
61125
+ delegated("input", input_39, (e) => updateBackgroundImage({ rotation: Number(e.target.value) }));
60995
61126
  delegated("click", button_27, () => updateBackgroundImage({ locked: !get(floor).backgroundImage.locked }));
60996
61127
  delegated("click", button_28, () => {
60997
61128
  calibrationPoints.set([]);
@@ -61000,12 +61131,12 @@ function PropertiesPanel($$anchor, $$props) {
61000
61131
  delegated("click", button_29, () => setBackgroundImage(void 0));
61001
61132
  append($$anchor, div_41);
61002
61133
  };
61003
- if_block(node_10, ($$render) => {
61004
- var _$$get18;
61005
- if (get(hasBgImage) && ((_$$get18 = get(floor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.backgroundImage)) $$render(consequent_14);
61134
+ if_block(node_11, ($$render) => {
61135
+ var _$$get19;
61136
+ if (get(hasBgImage) && ((_$$get19 = get(floor)) === null || _$$get19 === void 0 ? void 0 : _$$get19.backgroundImage)) $$render(consequent_14);
61006
61137
  });
61007
61138
  reset(div);
61008
- 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 fixed right-0 z-40 shadow-lg`, null, classes, { hidden: !get(hasSelection) }));
61139
+ 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) }));
61009
61140
  delegated("keydown", div, stopShortcutBubble);
61010
61141
  event("keydown", div, stopShortcutBubble, true);
61011
61142
  append($$anchor, div);
@@ -61023,7 +61154,7 @@ delegate([
61023
61154
  init_client();
61024
61155
  var root_3$5 = /* @__PURE__ */ from_html(`<button><span class="text-[10px]"> </span> <span class="truncate flex-1"> </span></button>`);
61025
61156
  var root_4$4 = /* @__PURE__ */ from_html(`<div class="pl-7 pr-2 py-1 text-gray-300 italic">Empty</div>`);
61026
- var root_2$5 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
61157
+ var root_2$6 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
61027
61158
  var root_1$6 = /* @__PURE__ */ from_html(`<div class="border-b border-gray-50 relative"><button class="w-full flex items-center gap-1.5 px-2 py-1.5 hover:bg-gray-50 text-left"><span class="text-[10px] text-gray-400 w-3"> </span> <span> </span> <span class="font-medium text-gray-700 flex-1"> </span> <span class="text-gray-400 mr-1"> </span></button> <span role="button" tabindex="0">👁</span> <!></div>`);
61028
61159
  var root_5$2 = /* @__PURE__ */ from_html(`<div class="p-4 text-gray-400 text-center">No elements</div>`);
61029
61160
  var root$2 = /* @__PURE__ */ from_html(`<div class="w-56 bg-white border-l border-gray-200 flex flex-col overflow-hidden text-xs select-none"><div class="px-3 py-2 border-b border-gray-100 font-semibold text-gray-700 text-sm flex items-center gap-1.5">🗂 Layers</div> <div class="flex-1 overflow-y-auto"><!> <!></div></div>`);
@@ -61194,7 +61325,7 @@ function LayersPanel($$anchor, $$props) {
61194
61325
  let classes;
61195
61326
  var node_1 = sibling(span_4, 2);
61196
61327
  var consequent_1 = ($$anchor) => {
61197
- var fragment = root_2$5();
61328
+ var fragment = root_2$6();
61198
61329
  var node_2 = first_child(fragment);
61199
61330
  each(node_2, 17, () => get(cat).items, index$1, ($$anchor, item) => {
61200
61331
  var button_1 = root_3$5();
@@ -62232,7 +62363,7 @@ function drawFurnitureIcon(ctx, catalogId, w, d, color, strokeColor, heatmapMatr
62232
62363
  //#region src/lib/components/editor/ContextMenu.svelte
62233
62364
  init_client();
62234
62365
  init_index_client();
62235
- var root_2$4 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">📋</span> Duplicate</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🔄</span> Rotate 90°</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">↔️</span> Flip Horizontal</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⬆️</span> Bring to Front</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⬇️</span> Send to Back</button> <div class="ctx-sep svelte-wxo1tu"></div> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu"> </span> </button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⚙️</span> Properties</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item ctx-danger svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🗑️</span> Delete</button>`, 1);
62366
+ var root_2$5 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">📋</span> Duplicate</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🔄</span> Rotate 90°</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">↔️</span> Flip Horizontal</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⬆️</span> Bring to Front</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⬇️</span> Send to Back</button> <div class="ctx-sep svelte-wxo1tu"></div> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu"> </span> </button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⚙️</span> Properties</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item ctx-danger svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🗑️</span> Delete</button>`, 1);
62236
62367
  var root_3$4 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">✂️</span> Split Wall</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">〰️</span> </button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⚙️</span> Properties</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item ctx-danger svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🗑️</span> Delete Wall</button>`, 1);
62237
62368
  var root_4$3 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⚙️</span> Properties</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item ctx-danger svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🗑️</span> Delete</button>`, 1);
62238
62369
  var root_5$1 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">✏️</span> Rename Room</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🎨</span> Change Floor Texture</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item ctx-danger svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🗑️</span> Delete Room</button>`, 1);
@@ -62280,7 +62411,7 @@ function ContextMenu($$anchor, $$props) {
62280
62411
  var div = root_1$5();
62281
62412
  var node_1 = child(div);
62282
62413
  var consequent = ($$anchor) => {
62283
- var fragment_1 = root_2$4();
62414
+ var fragment_1 = root_2$5();
62284
62415
  var button = first_child(fragment_1);
62285
62416
  var button_1 = sibling(button, 2);
62286
62417
  var button_2 = sibling(button_1, 2);
@@ -63618,30 +63749,65 @@ function drawFurnitureItem(cs, item, selected, options) {
63618
63749
  ctx.fillRect(hx - ehs, hy - ehs, ehs * 2, ehs * 2);
63619
63750
  ctx.strokeRect(hx - ehs, hy - ehs, ehs * 2, ehs * 2);
63620
63751
  }
63621
- const rotY = -d / 2 - 18;
63622
- ctx.strokeStyle = "#3b82f6";
63623
- ctx.lineWidth = 1;
63624
- ctx.beginPath();
63625
- ctx.moveTo(0, -d / 2 - 2);
63626
- ctx.lineTo(0, rotY + 5);
63627
- ctx.stroke();
63628
- ctx.fillStyle = "#3b82f6";
63629
- ctx.beginPath();
63630
- ctx.arc(0, rotY, 5, 0, Math.PI * 2);
63631
- ctx.fill();
63632
- ctx.strokeStyle = "#ffffff";
63633
- ctx.lineWidth = 1.2;
63634
- ctx.beginPath();
63635
- ctx.arc(0, rotY, 3, -Math.PI * .8, Math.PI * .4);
63636
- ctx.stroke();
63637
- const arrowAngle2 = Math.PI * .4;
63638
- const ax = Math.cos(arrowAngle2) * 3;
63639
- const ay = Math.sin(arrowAngle2) * 3;
63640
- ctx.beginPath();
63641
- ctx.moveTo(ax + 1.5, rotY + ay - 1);
63642
- ctx.lineTo(ax, rotY + ay);
63643
- ctx.lineTo(ax - 1, rotY + ay - 2);
63644
- ctx.stroke();
63752
+ const rotOffset = isCamera ? 26 : 18;
63753
+ const rotRadius = isCamera ? 8 : 5;
63754
+ const rotIconR = isCamera ? 4.5 : 3;
63755
+ const rotHandles = isCamera ? [
63756
+ {
63757
+ edgeX: 0,
63758
+ edgeY: -d / 2,
63759
+ hx: 0,
63760
+ hy: -d / 2 - rotOffset
63761
+ },
63762
+ {
63763
+ edgeX: 0,
63764
+ edgeY: d / 2,
63765
+ hx: 0,
63766
+ hy: d / 2 + rotOffset
63767
+ },
63768
+ {
63769
+ edgeX: -w / 2,
63770
+ edgeY: 0,
63771
+ hx: -w / 2 - rotOffset,
63772
+ hy: 0
63773
+ },
63774
+ {
63775
+ edgeX: w / 2,
63776
+ edgeY: 0,
63777
+ hx: w / 2 + rotOffset,
63778
+ hy: 0
63779
+ }
63780
+ ] : [{
63781
+ edgeX: 0,
63782
+ edgeY: -d / 2,
63783
+ hx: 0,
63784
+ hy: -d / 2 - rotOffset
63785
+ }];
63786
+ for (const h of rotHandles) {
63787
+ ctx.strokeStyle = "#3b82f6";
63788
+ ctx.lineWidth = 1;
63789
+ ctx.beginPath();
63790
+ ctx.moveTo(h.edgeX, h.edgeY);
63791
+ ctx.lineTo(h.hx, h.hy);
63792
+ ctx.stroke();
63793
+ ctx.fillStyle = "#3b82f6";
63794
+ ctx.beginPath();
63795
+ ctx.arc(h.hx, h.hy, rotRadius, 0, Math.PI * 2);
63796
+ ctx.fill();
63797
+ ctx.strokeStyle = "#ffffff";
63798
+ ctx.lineWidth = isCamera ? 1.6 : 1.2;
63799
+ ctx.beginPath();
63800
+ ctx.arc(h.hx, h.hy, rotIconR, -Math.PI * .8, Math.PI * .4);
63801
+ ctx.stroke();
63802
+ const arrowAngle2 = Math.PI * .4;
63803
+ const ax = Math.cos(arrowAngle2) * rotIconR;
63804
+ const ay = Math.sin(arrowAngle2) * rotIconR;
63805
+ ctx.beginPath();
63806
+ ctx.moveTo(h.hx + ax + 1.5, h.hy + ay - 1);
63807
+ ctx.lineTo(h.hx + ax, h.hy + ay);
63808
+ ctx.lineTo(h.hx + ax - 1, h.hy + ay - 2);
63809
+ ctx.stroke();
63810
+ }
63645
63811
  }
63646
63812
  ctx.restore();
63647
63813
  }
@@ -64579,7 +64745,7 @@ function findWallAt(p, walls, zoom) {
64579
64745
  return null;
64580
64746
  }
64581
64747
  function findHandleAt(p, selectedId, furniture, zoom) {
64582
- var _fi$scale$x, _fi$scale, _fi$scale$y, _fi$scale2;
64748
+ var _fi$width, _fi$scale$x, _fi$scale, _fi$depth, _fi$scale$y, _fi$scale2;
64583
64749
  if (!selectedId) return null;
64584
64750
  const fi = furniture.find((f) => f.id === selectedId);
64585
64751
  if (!fi) return null;
@@ -64590,11 +64756,34 @@ function findHandleAt(p, selectedId, furniture, zoom) {
64590
64756
  const angle = -(fi.rotation * Math.PI) / 180;
64591
64757
  const rx = dx * Math.cos(angle) - dy * Math.sin(angle);
64592
64758
  const ry = dx * Math.sin(angle) + dy * Math.cos(angle);
64593
- const hw = cat.width * Math.abs((_fi$scale$x = (_fi$scale = fi.scale) === null || _fi$scale === void 0 ? void 0 : _fi$scale.x) !== null && _fi$scale$x !== void 0 ? _fi$scale$x : 1) / 2;
64594
- const hd = cat.depth * Math.abs((_fi$scale$y = (_fi$scale2 = fi.scale) === null || _fi$scale2 === void 0 ? void 0 : _fi$scale2.y) !== null && _fi$scale$y !== void 0 ? _fi$scale$y : 1) / 2;
64759
+ const hw = ((_fi$width = fi.width) !== null && _fi$width !== void 0 ? _fi$width : cat.width) * Math.abs((_fi$scale$x = (_fi$scale = fi.scale) === null || _fi$scale === void 0 ? void 0 : _fi$scale.x) !== null && _fi$scale$x !== void 0 ? _fi$scale$x : 1) / 2;
64760
+ const hd = ((_fi$depth = fi.depth) !== null && _fi$depth !== void 0 ? _fi$depth : cat.depth) * Math.abs((_fi$scale$y = (_fi$scale2 = fi.scale) === null || _fi$scale2 === void 0 ? void 0 : _fi$scale2.y) !== null && _fi$scale$y !== void 0 ? _fi$scale$y : 1) / 2;
64595
64761
  const ht = 8 / zoom;
64596
- const rotHandleDist = 18 / zoom;
64597
- if (Math.abs(rx) < ht && Math.abs(ry - (-hd - rotHandleDist)) < ht) return "rotate";
64762
+ const isCamera = fi.catalogId === "camera";
64763
+ const rotHandleDist = (isCamera ? 26 : 18) / zoom;
64764
+ const rotHt = (isCamera ? 12 : 8) / zoom;
64765
+ const rotateHits = isCamera ? [
64766
+ {
64767
+ x: 0,
64768
+ y: -hd - rotHandleDist
64769
+ },
64770
+ {
64771
+ x: 0,
64772
+ y: hd + rotHandleDist
64773
+ },
64774
+ {
64775
+ x: -hw - rotHandleDist,
64776
+ y: 0
64777
+ },
64778
+ {
64779
+ x: hw + rotHandleDist,
64780
+ y: 0
64781
+ }
64782
+ ] : [{
64783
+ x: 0,
64784
+ y: -hd - rotHandleDist
64785
+ }];
64786
+ for (const h of rotateHits) if (Math.abs(rx - h.x) < rotHt && Math.abs(ry - h.y) < rotHt) return "rotate";
64598
64787
  if (Math.abs(rx - -hw) < ht && Math.abs(ry - -hd) < ht) return "resize-tl";
64599
64788
  if (Math.abs(rx - hw) < ht && Math.abs(ry - -hd) < ht) return "resize-tr";
64600
64789
  if (Math.abs(rx - -hw) < ht && Math.abs(ry - hd) < ht) return "resize-bl";
@@ -64780,7 +64969,7 @@ var root_21 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -tr
64780
64969
  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>`);
64781
64970
  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>`);
64782
64971
  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>`);
64783
- var root_2$3 = /* @__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);
64972
+ 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);
64784
64973
  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>`);
64785
64974
  function FloorPlanCanvas($$anchor, $$props) {
64786
64975
  push($$props, true);
@@ -65254,21 +65443,31 @@ function FloorPlanCanvas($$anchor, $$props) {
65254
65443
  };
65255
65444
  return end;
65256
65445
  }
65446
+ let resizeRaf = 0;
65257
65447
  function resize() {
65448
+ if (resizeRaf) return;
65449
+ resizeRaf = requestAnimationFrame(() => {
65450
+ resizeRaf = 0;
65451
+ applyCanvasResize();
65452
+ });
65453
+ }
65454
+ function applyCanvasResize() {
65258
65455
  if ($$props.viewOnly) {
65259
65456
  layoutViewOnlyViewport();
65260
65457
  return;
65261
65458
  }
65262
65459
  const parent = canvas === null || canvas === void 0 ? void 0 : canvas.parentElement;
65263
- if (!parent) return;
65264
- set(width, parent.clientWidth, true);
65265
- set(height, parent.clientHeight, true);
65266
- if (canvas) {
65267
- canvas.width = get(width);
65268
- canvas.height = get(height);
65269
- }
65270
- markDirty();
65271
- needsFitToCanvas = true;
65460
+ if (!parent || !canvas) return;
65461
+ const nextW = parent.clientWidth;
65462
+ const nextH = parent.clientHeight;
65463
+ if (nextW <= 0 || nextH <= 0) return;
65464
+ if (nextW === get(width) && nextH === get(height) && canvas.width === nextW) return;
65465
+ set(width, nextW, true);
65466
+ set(height, nextH, true);
65467
+ canvas.width = get(width);
65468
+ canvas.height = get(height);
65469
+ canvasDirty = true;
65470
+ draw();
65272
65471
  }
65273
65472
  /** viewOnly: canvas fills parent 100%, floor zoomed to fit edge-to-edge */
65274
65473
  function layoutViewOnlyViewport() {
@@ -68263,7 +68462,7 @@ function FloorPlanCanvas($$anchor, $$props) {
68263
68462
  });
68264
68463
  var node_1 = sibling(node, 2);
68265
68464
  var consequent_22 = ($$anchor) => {
68266
- var fragment = root_2$3();
68465
+ var fragment = root_2$4();
68267
68466
  var node_2 = first_child(fragment);
68268
68467
  var consequent_1 = ($$anchor) => {
68269
68468
  var input = root_3$3();
@@ -68780,7 +68979,7 @@ function FloorPlanCanvas($$anchor, $$props) {
68780
68979
  set_style(div_1, $0);
68781
68980
  classes = set_class(canvas_1, 1, "block w-full h-full", null, classes, { "pointer-events-none": $$props.viewOnly });
68782
68981
  set_attribute(canvas_1, "tabindex", $$props.viewOnly ? -1 : 0);
68783
- set_style(canvas_1, `cursor: ${get(cursorStyle)};`);
68982
+ set_style(canvas_1, `cursor: ${get(cursorStyle)}; background-color: ${canvasBackground()};`);
68784
68983
  }, [() => getCanvasFrameStyle()]);
68785
68984
  delegated("mousedown", canvas_1, onMouseDown);
68786
68985
  delegated("mousemove", canvas_1, onMouseMove);
@@ -68929,7 +69128,7 @@ function alignElements(ids, op) {
68929
69128
  //#region src/lib/components/editor/AlignmentToolbar.svelte
68930
69129
  init_client();
68931
69130
  var root_3$2 = /* @__PURE__ */ from_html(`<div class="w-px h-5 bg-gray-200 mx-0.5"></div>`);
68932
- var root_2$2 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-blue-50 text-gray-500 hover:text-blue-600 transition-colors"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path></path></svg></button> <!>`, 1);
69131
+ var root_2$3 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-blue-50 text-gray-500 hover:text-blue-600 transition-colors"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path></path></svg></button> <!>`, 1);
68933
69132
  var root_1$3 = /* @__PURE__ */ from_html(`<div class="fixed top-16 left-1/2 -translate-x-1/2 z-50 flex items-center gap-0.5 bg-white rounded-lg shadow-lg border border-gray-200 px-1.5 py-1"><span class="text-xs text-gray-400 px-1 select-none"> </span> <div class="w-px h-5 bg-gray-200 mx-0.5"></div> <!></div>`);
68934
69133
  function AlignmentToolbar($$anchor, $$props) {
68935
69134
  push($$props, true);
@@ -68994,7 +69193,7 @@ function AlignmentToolbar($$anchor, $$props) {
68994
69193
  var text = child(span);
68995
69194
  reset(span);
68996
69195
  each(sibling(span, 4), 17, () => buttons, index$1, ($$anchor, btn) => {
68997
- var fragment_1 = root_2$2();
69196
+ var fragment_1 = root_2$3();
68998
69197
  var button = first_child(fragment_1);
68999
69198
  var svg = child(button);
69000
69199
  var path = child(svg);
@@ -69032,7 +69231,7 @@ delegate(["click"]);
69032
69231
  //#endregion
69033
69232
  //#region src/lib/components/editor/CommandPalette.svelte
69034
69233
  init_client();
69035
- var root_2$1 = /* @__PURE__ */ from_html(`<div class="px-4 py-6 text-center text-sm text-gray-400">No results found</div>`);
69234
+ var root_2$2 = /* @__PURE__ */ from_html(`<div class="px-4 py-6 text-center text-sm text-gray-400">No results found</div>`);
69036
69235
  var root_4$1 = /* @__PURE__ */ from_html(`<div role="option"><span class="text-base w-6 text-center flex-shrink-0"> </span> <span class="flex-1 truncate"> </span> <span class="text-xs text-gray-400 flex-shrink-0"> </span></div>`);
69037
69236
  var root_1$2 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/40 z-[100] flex justify-center" role="dialog" aria-label="Command Palette"><div class="mt-[15vh] w-full max-w-lg h-fit bg-white rounded-xl shadow-2xl overflow-hidden" role="listbox"><div class="flex items-center gap-2 px-4 py-3 border-b border-gray-200"><span class="text-gray-400 text-lg">🔍</span> <input class="flex-1 bg-transparent outline-none text-sm text-gray-800 placeholder-gray-400" placeholder="Search furniture, tools, actions…" type="text" spellcheck="false"/> <kbd class="text-[10px] px-1.5 py-0.5 bg-gray-100 rounded border border-gray-200 text-gray-400">ESC</kbd></div> <div class="max-h-[50vh] overflow-y-auto"><!></div> <div class="px-4 py-2 border-t border-gray-100 flex items-center gap-3 text-[10px] text-gray-400"><span><kbd class="px-1 py-0.5 bg-gray-100 rounded border border-gray-200">↑↓</kbd> navigate</span> <span><kbd class="px-1 py-0.5 bg-gray-100 rounded border border-gray-200">↵</kbd> select</span> <span><kbd class="px-1 py-0.5 bg-gray-100 rounded border border-gray-200">esc</kbd> close</span></div></div></div>`);
69038
69237
  function CommandPalette($$anchor, $$props) {
@@ -69289,7 +69488,7 @@ function CommandPalette($$anchor, $$props) {
69289
69488
  var div_3 = sibling(div_2, 2);
69290
69489
  var node_1 = child(div_3);
69291
69490
  var consequent = ($$anchor) => {
69292
- append($$anchor, root_2$1());
69491
+ append($$anchor, root_2$2());
69293
69492
  };
69294
69493
  var alternate = ($$anchor) => {
69295
69494
  var fragment_1 = comment();
@@ -69353,7 +69552,7 @@ delegate(["click", "keydown"]);
69353
69552
  //#region src/lib/components/editor/PrintLayout.svelte
69354
69553
  init_client();
69355
69554
  init_index_client();
69356
- var root_2 = /* @__PURE__ */ from_html(`<option> </option>`);
69555
+ var root_2$1 = /* @__PURE__ */ from_html(`<option> </option>`);
69357
69556
  var root_4 = /* @__PURE__ */ from_html(`<div class="flex justify-between"><span class="text-slate-600"> </span> <span class="text-slate-800 font-medium ml-2"> </span></div>`);
69358
69557
  var root_3$1 = /* @__PURE__ */ from_html(`<div class="border-t border-slate-300 pt-3 mt-2 print-legend"><h3 class="text-xs font-bold text-slate-700 uppercase tracking-wide mb-2">Room Schedule</h3> <div class="grid grid-cols-3 gap-x-6 gap-y-1 text-xs"></div></div>`);
69359
69558
  var root_1$1 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/60 z-[100] flex items-start justify-center overflow-auto print-overlay-backdrop"><div class="fixed top-0 left-0 right-0 bg-slate-800 text-white px-6 py-3 flex items-center gap-4 z-[101] print-hide"><h3 class="font-semibold text-sm">Print Preview</h3> <div class="h-4 w-px bg-white/20"></div> <label class="text-xs text-white/70">Page: <select class="ml-1 bg-slate-700 text-white text-xs rounded px-2 py-1 border border-slate-600"><option>Letter</option><option>A4</option></select></label> <label class="text-xs text-white/70">Orientation: <select class="ml-1 bg-slate-700 text-white text-xs rounded px-2 py-1 border border-slate-600"><option>Landscape</option><option>Portrait</option></select></label> <label class="text-xs text-white/70">Scale: <select class="ml-1 bg-slate-700 text-white text-xs rounded px-2 py-1 border border-slate-600"></select></label> <div class="flex-1"></div> <button class="px-4 py-1.5 bg-blue-500 hover:bg-blue-600 text-white text-sm font-semibold rounded-lg transition-colors 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</button> <button class="px-3 py-1.5 text-white/70 hover:text-white text-sm transition-colors">✕ Close</button></div> <div><div class="border-b-2 border-slate-800 pb-3 mb-4 flex items-end justify-between print-title-block"><div><h1 class="text-xl font-bold text-slate-800"> </h1> <p class="text-sm text-slate-500"> </p></div> <div class="text-right text-xs text-slate-500"><p class="font-semibold text-slate-700"> </p> <p> </p></div></div> <div class="flex-1 relative print-canvas-container svelte-67xe6d"><canvas class="w-full svelte-67xe6d" style="height: calc(100% - 20px);"></canvas> <div class="absolute top-2 right-2 print-north-arrow"><svg width="40" height="40" viewBox="0 0 40 40"><polygon points="20,2 24,16 20,12 16,16" fill="#1e293b"></polygon><polygon points="20,38 24,24 20,28 16,24" fill="#94a3b8"></polygon><text x="20" y="10" text-anchor="middle" fill="#1e293b" font-size="8" font-weight="bold">N</text></svg></div> <div class="absolute bottom-1 left-2 flex items-center gap-2 text-[10px] text-slate-600 print-scale-bar"><div class="flex items-end gap-0"><div class="w-12 h-1 bg-slate-800"></div> <div class="w-12 h-1 bg-slate-400"></div></div> <span> </span></div></div> <!> <div class="border-t border-slate-200 pt-2 mt-3 flex justify-between text-[9px] text-slate-400 print-footer"><span>Generated by Open3D Floorplan</span> <span>Page 1 of 1</span></div></div></div>`);
@@ -69580,7 +69779,7 @@ function PrintLayout($$anchor, $$props) {
69580
69779
  var label_2 = sibling(label_1, 2);
69581
69780
  var select_2 = sibling(child(label_2));
69582
69781
  each(select_2, 21, () => scaleOptions, index$1, ($$anchor, s) => {
69583
- var option_4 = root_2();
69782
+ var option_4 = root_2$1();
69584
69783
  var text = child(option_4, true);
69585
69784
  reset(option_4);
69586
69785
  var option_4_value = {};
@@ -69802,10 +70001,32 @@ function findOpenCameraPosition(floor, preferred) {
69802
70001
  y: preferred.y
69803
70002
  };
69804
70003
  }
70004
+ function propsEqual(a, b) {
70005
+ const left = a !== null && a !== void 0 ? a : {};
70006
+ const keys = new Set([...Object.keys(left), ...Object.keys(b)]);
70007
+ for (const key of keys) {
70008
+ var _left$key, _b$key;
70009
+ if (((_left$key = left[key]) !== null && _left$key !== void 0 ? _left$key : "") !== ((_b$key = b[key]) !== null && _b$key !== void 0 ? _b$key : "")) return false;
70010
+ }
70011
+ return true;
70012
+ }
70013
+ function applyCameraProps(id, cam) {
70014
+ var _props$serial, _ref, _props$name;
70015
+ const props = assignedCameraToProps(cam);
70016
+ const serial = ((_props$serial = props.serial) === null || _props$serial === void 0 ? void 0 : _props$serial.trim()) || String(cam.serial).trim();
70017
+ updateFurniture(id, {
70018
+ serial,
70019
+ name: (_ref = (_props$name = props.name) !== null && _props$name !== void 0 ? _props$name : props.serial) !== null && _ref !== void 0 ? _ref : serial,
70020
+ props: {
70021
+ ...props,
70022
+ serial
70023
+ }
70024
+ });
70025
+ }
69805
70026
  /**
69806
70027
  * Sync host `assignedCameras` onto the active floor.
69807
70028
  * - Adds missing serials at floor center (non-overlapping)
69808
- * - Updates names for existing serials
70029
+ * - Updates dynamic props for existing serials
69809
70030
  * - Removes cameras whose serial is no longer assigned
69810
70031
  * - If floor has no walls, rejects adds and emits camerasRejected
69811
70032
  */
@@ -69814,24 +70035,21 @@ function syncAssignedCameras(assigned) {
69814
70035
  const floor = get$1(activeFloor);
69815
70036
  const project = get$1(currentProject);
69816
70037
  if (!floor || !project) return;
69817
- const normalized = assigned.filter((c) => c && typeof c.serial === "string" && c.serial.trim());
69818
- const assignedBySerial = new Map(normalized.map((c) => [c.serial.trim(), c]));
70038
+ const normalized = assigned.filter((c) => c && typeof c.serial === "string" && String(c.serial).trim());
70039
+ const assignedBySerial = new Map(normalized.map((c) => [String(c.serial).trim(), c]));
69819
70040
  const existing = getCameraFurniture(floor);
69820
70041
  const existingBySerial = /* @__PURE__ */ new Map();
69821
70042
  for (const item of existing) if (item.serial) existingBySerial.set(item.serial, item);
69822
- const toAdd = normalized.filter((c) => !existingBySerial.has(c.serial.trim()));
70043
+ const toAdd = normalized.filter((c) => !existingBySerial.has(String(c.serial).trim()));
69823
70044
  const hasFloorLayout = ((_floor$walls$length = (_floor$walls = floor.walls) === null || _floor$walls === void 0 ? void 0 : _floor$walls.length) !== null && _floor$walls$length !== void 0 ? _floor$walls$length : 0) > 0;
69824
70045
  function rejectNoFloor(cameras) {
69825
70046
  if (cameras.length === 0) return;
69826
- const key = cameras.map((c) => c.serial.trim()).sort().join(",");
70047
+ const key = cameras.map((c) => String(c.serial).trim()).sort().join(",");
69827
70048
  if (key === lastRejectedKey) return;
69828
70049
  lastRejectedKey = key;
69829
70050
  emitFloorCallback("camerasRejected", {
69830
70051
  reason: "no-floor",
69831
- cameras: cameras.map((c) => ({
69832
- serial: c.serial,
69833
- name: c.name
69834
- }))
70052
+ cameras: cameras.map((c) => assignedCameraToProps(c))
69835
70053
  });
69836
70054
  }
69837
70055
  if (toAdd.length > 0 && !hasFloorLayout) rejectNoFloor(toAdd);
@@ -69846,7 +70064,10 @@ function syncAssignedCameras(assigned) {
69846
70064
  for (const item of getCameraFurniture(floorAfterRemove)) {
69847
70065
  if (!item.serial) continue;
69848
70066
  const assignedCam = assignedBySerial.get(item.serial);
69849
- if (assignedCam && assignedCam.name !== item.name) updateFurniture(item.id, { name: assignedCam.name });
70067
+ if (!assignedCam) continue;
70068
+ const nextProps = assignedCameraToProps(assignedCam);
70069
+ nextProps.serial = item.serial;
70070
+ if (!propsEqual(item.props, nextProps) || item.name !== nextProps.name) applyCameraProps(item.id, assignedCam);
69850
70071
  }
69851
70072
  if (!hasFloorLayout) return;
69852
70073
  const center = getFloorCenter(floorAfterRemove);
@@ -69857,12 +70078,9 @@ function syncAssignedCameras(assigned) {
69857
70078
  lastRejectedKey = "";
69858
70079
  let workingFloor = get$1(activeFloor);
69859
70080
  for (const cam of toAdd) {
69860
- const serial = cam.serial.trim();
70081
+ const serial = String(cam.serial).trim();
69861
70082
  if (getCameraFurniture(workingFloor).some((f) => f.serial === serial)) continue;
69862
- updateFurniture(addFurniture("camera", findOpenCameraPosition(workingFloor, center)), {
69863
- serial,
69864
- name: cam.name
69865
- });
70083
+ applyCameraProps(addFurniture("camera", findOpenCameraPosition(workingFloor, center)), cam);
69866
70084
  workingFloor = get$1(activeFloor);
69867
70085
  }
69868
70086
  } finally {
@@ -69873,13 +70091,15 @@ function syncAssignedCameras(assigned) {
69873
70091
  //#region src/App.svelte
69874
70092
  init_client();
69875
70093
  init_index_client();
70094
+ var root_2 = /* @__PURE__ */ from_html(`<div class="shrink-0 h-full overflow-hidden transition-[width] duration-300 ease-in-out"><div><!></div></div>`);
69876
70095
  var root_3 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
69877
70096
  var root_7 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 flex items-center justify-center z-50" role="dialog" tabindex="-1" aria-label="Keyboard Shortcuts"><div class="bg-white rounded-2xl shadow-2xl max-w-2xl w-full mx-4 max-h-[85vh] flex flex-col" role="document"><div class="flex items-center justify-between px-6 pt-5 pb-3 border-b border-gray-100"><div class="flex items-center gap-2"><svg class="w-5 h-5 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707"></path></svg> <h2 class="text-lg font-bold text-slate-800">Keyboard Shortcuts</h2></div> <div class="flex items-center gap-2"><button class="text-xs px-3 py-1.5 rounded-lg bg-slate-100 hover:bg-slate-200 text-slate-600 hover:text-slate-800 transition-colors flex items-center gap-1.5" aria-label="Copy all shortcuts"><svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path></svg> Copy All</button> <button class="text-gray-400 hover:text-gray-600 text-xl leading-none" aria-label="Close shortcuts">✕</button></div></div> <div class="overflow-y-auto px-6 py-4"><div class="grid grid-cols-2 gap-x-8 gap-y-0 text-sm"><div><div class="flex items-center gap-2 mb-2"><span class="text-xs font-bold uppercase tracking-wider text-indigo-500">Tools</span> <div class="flex-1 h-px bg-indigo-100"></div></div> <div class="space-y-1.5 mb-5"><div class="flex justify-between"><span class="text-gray-600">Select tool</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">V</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Wall tool</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">W</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Door tool</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">D</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Pan mode</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">H</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Measure tool</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">M</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Annotate tool</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">N</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Text tool</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">T</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Toggle snap</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">S</kbd></div></div> <div class="flex items-center gap-2 mb-2"><span class="text-xs font-bold uppercase tracking-wider text-amber-500">Edit</span> <div class="flex-1 h-px bg-amber-100"></div></div> <div class="space-y-1.5 mb-5"><div class="flex justify-between"><span class="text-gray-600">Undo</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+Z</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Redo</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+Y</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Copy</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+C</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Paste</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+V</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Select all</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+A</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Deselect all</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+D</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Save project</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+S</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Cancel / Deselect</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Esc</kbd></div></div></div> <div><div class="flex items-center gap-2 mb-2"><span class="text-xs font-bold uppercase tracking-wider text-emerald-500">Elements</span> <div class="flex-1 h-px bg-emerald-100"></div></div> <div class="space-y-1.5 mb-5"><div class="flex justify-between"><span class="text-gray-600">Rotate element</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">R</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Delete selected</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Del</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Lock / Unlock</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+L</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Group selection</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+G</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Ungroup</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Ctrl+⇧+G</kbd></div></div> <div class="flex items-center gap-2 mb-2"><span class="text-xs font-bold uppercase tracking-wider text-blue-500">View</span> <div class="flex-1 h-px bg-blue-100"></div></div> <div class="space-y-1.5 mb-5"><div class="flex justify-between"><span class="text-gray-600">Toggle 2D / 3D</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Tab</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Zoom to fit</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">F</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Toggle grid</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">G</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Toggle layers</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">L</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Show shortcuts</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">?</kbd></div></div> <div class="flex items-center gap-2 mb-2"><span class="text-xs font-bold uppercase tracking-wider text-purple-500">Canvas</span> <div class="flex-1 h-px bg-purple-100"></div></div> <div class="space-y-1.5 mb-5"><div class="flex justify-between"><span class="text-gray-600">Zoom in / out</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Scroll</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Zoom in / out</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">+ / −</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Pan canvas</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Space+Drag</kbd></div></div> <div class="flex items-center gap-2 mb-2"><span class="text-xs font-bold uppercase tracking-wider text-rose-500">Walls</span> <div class="flex-1 h-px bg-rose-100"></div></div> <div class="space-y-1.5"><div class="flex justify-between"><span class="text-gray-600">Finish wall chain</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">Dbl-click</kbd></div> <div class="flex justify-between"><span class="text-gray-600">Close wall loop</span><kbd class="px-1.5 py-0.5 bg-gray-100 rounded text-xs font-mono text-slate-700 border border-gray-200">C</kbd></div></div></div></div></div> <div class="px-6 py-3 border-t border-gray-100 text-center"><p class="text-xs text-gray-400">Press <kbd class="px-1 py-0.5 bg-gray-100 rounded text-xs font-mono border border-gray-200">?</kbd> or <kbd class="px-1 py-0.5 bg-gray-100 rounded text-xs font-mono border border-gray-200">Esc</kbd> to close</p></div></div></div>`);
69878
- var root = /* @__PURE__ */ from_html(`<div class="h-full flex flex-col overflow-hidden"><!> <div class="flex flex-1 overflow-hidden"><!> <div class="flex-1 min-w-0 relative"><!></div> <!> <!></div></div> <!> <!> <!> <!> <!>`, 1);
70097
+ var root = /* @__PURE__ */ from_html(`<div class="h-full flex flex-col overflow-hidden"><!> <div class="flex flex-1 overflow-hidden relative"><!> <div class="flex-1 min-w-0 relative"><!></div> <!> <!></div></div> <!> <!> <!> <!> <!>`, 1);
69879
70098
  function App($$anchor, $$props) {
69880
70099
  var _$$props$stores, _$$props$stores2;
69881
70100
  push($$props, true);
69882
70101
  let showLayers = /* @__PURE__ */ state(false);
70102
+ let showBuildSidebar = /* @__PURE__ */ state(true);
69883
70103
  let floorData = /* @__PURE__ */ state(null);
69884
70104
  let config = /* @__PURE__ */ state(proxy({ ...DEFAULT_CONFIG }));
69885
70105
  let activeFloorId = /* @__PURE__ */ state(null);
@@ -69962,6 +70182,12 @@ function App($$anchor, $$props) {
69962
70182
  },
69963
70183
  get onDispatch() {
69964
70184
  return $$props.onDispatch;
70185
+ },
70186
+ get showBuildSidebar() {
70187
+ return get(showBuildSidebar);
70188
+ },
70189
+ set showBuildSidebar($$value) {
70190
+ set(showBuildSidebar, $$value, true);
69965
70191
  }
69966
70192
  });
69967
70193
  };
@@ -69971,7 +70197,9 @@ function App($$anchor, $$props) {
69971
70197
  var div_1 = sibling(node, 2);
69972
70198
  var node_1 = child(div_1);
69973
70199
  var consequent_1 = ($$anchor) => {
69974
- BuildPanel($$anchor, {
70200
+ var div_2 = root_2();
70201
+ var div_3 = child(div_2);
70202
+ BuildPanel(child(div_3), {
69975
70203
  get showHelp() {
69976
70204
  return get(showHelp);
69977
70205
  },
@@ -69991,16 +70219,24 @@ function App($$anchor, $$props) {
69991
70219
  set(showUndoHistory, $$value, true);
69992
70220
  }
69993
70221
  });
70222
+ reset(div_3);
70223
+ reset(div_2);
70224
+ template_effect(() => {
70225
+ set_style(div_2, `width: ${get(showBuildSidebar) ? "16rem" : "0"};`);
70226
+ set_attribute(div_2, "aria-hidden", !get(showBuildSidebar));
70227
+ set_class(div_3, 1, `w-64 h-full ${get(showBuildSidebar) ? "" : "pointer-events-none"}`);
70228
+ });
70229
+ append($$anchor, div_2);
69994
70230
  };
69995
70231
  if_block(node_1, ($$render) => {
69996
70232
  var _$$get;
69997
70233
  if (get(mode) === "2d" && !((_$$get = get(config)) === null || _$$get === void 0 ? void 0 : _$$get.viewOnly)) $$render(consequent_1);
69998
70234
  });
69999
- var div_2 = sibling(node_1, 2);
70000
- var node_2 = child(div_2);
70235
+ var div_4 = sibling(node_1, 2);
70236
+ var node_3 = child(div_4);
70001
70237
  var consequent_3 = ($$anchor) => {
70002
- var fragment_3 = root_3();
70003
- var node_3 = first_child(fragment_3);
70238
+ var fragment_2 = root_3();
70239
+ var node_4 = first_child(fragment_2);
70004
70240
  {
70005
70241
  let $0 = /* @__PURE__ */ user_derived(() => {
70006
70242
  var _$$get2;
@@ -70054,7 +70290,7 @@ function App($$anchor, $$props) {
70054
70290
  var _$$get14;
70055
70291
  return (_$$get14 = get(config)) === null || _$$get14 === void 0 ? void 0 : _$$get14.floorPlateBackground;
70056
70292
  });
70057
- FloorPlanCanvas(node_3, {
70293
+ FloorPlanCanvas(node_4, {
70058
70294
  get viewOnly() {
70059
70295
  return get($0);
70060
70296
  },
@@ -70096,27 +70332,27 @@ function App($$anchor, $$props) {
70096
70332
  }
70097
70333
  });
70098
70334
  }
70099
- var node_4 = sibling(node_3, 2);
70335
+ var node_5 = sibling(node_4, 2);
70100
70336
  var consequent_2 = ($$anchor) => {
70101
70337
  AlignmentToolbar($$anchor, {});
70102
70338
  };
70103
- if_block(node_4, ($$render) => {
70339
+ if_block(node_5, ($$render) => {
70104
70340
  if (!get(config).viewOnly) $$render(consequent_2);
70105
70341
  });
70106
- append($$anchor, fragment_3);
70342
+ append($$anchor, fragment_2);
70107
70343
  };
70108
- if_block(node_2, ($$render) => {
70344
+ if_block(node_3, ($$render) => {
70109
70345
  if (get(mode) === "2d") $$render(consequent_3);
70110
70346
  });
70111
- reset(div_2);
70112
- var node_5 = sibling(div_2, 2);
70347
+ reset(div_4);
70348
+ var node_6 = sibling(div_4, 2);
70113
70349
  var consequent_4 = ($$anchor) => {
70114
70350
  LayersPanel($$anchor, {});
70115
70351
  };
70116
- if_block(node_5, ($$render) => {
70352
+ if_block(node_6, ($$render) => {
70117
70353
  if (get(showLayers) && get(mode) === "2d" && !get(config).viewOnly) $$render(consequent_4);
70118
70354
  });
70119
- var node_6 = sibling(node_5, 2);
70355
+ var node_7 = sibling(node_6, 2);
70120
70356
  var consequent_5 = ($$anchor) => {
70121
70357
  {
70122
70358
  let $0 = /* @__PURE__ */ user_derived(() => get(mode) === "3d");
@@ -70141,13 +70377,13 @@ function App($$anchor, $$props) {
70141
70377
  });
70142
70378
  }
70143
70379
  };
70144
- if_block(node_6, ($$render) => {
70380
+ if_block(node_7, ($$render) => {
70145
70381
  if (!get(config).viewOnly) $$render(consequent_5);
70146
70382
  });
70147
70383
  reset(div_1);
70148
70384
  reset(div);
70149
- var node_7 = sibling(div, 2);
70150
- UndoHistoryPanel(node_7, {
70385
+ var node_8 = sibling(div, 2);
70386
+ UndoHistoryPanel(node_8, {
70151
70387
  get visible() {
70152
70388
  return get(showUndoHistory);
70153
70389
  },
@@ -70155,25 +70391,25 @@ function App($$anchor, $$props) {
70155
70391
  set(showUndoHistory, $$value, true);
70156
70392
  }
70157
70393
  });
70158
- var node_8 = sibling(node_7, 2);
70394
+ var node_9 = sibling(node_8, 2);
70159
70395
  var consequent_6 = ($$anchor) => {
70160
- var div_3 = root_7();
70161
- var div_4 = child(div_3);
70162
- var div_5 = child(div_4);
70163
- var div_6 = sibling(child(div_5), 2);
70164
- var button = child(div_6);
70396
+ var div_5 = root_7();
70397
+ var div_6 = child(div_5);
70398
+ var div_7 = child(div_6);
70399
+ var div_8 = sibling(child(div_7), 2);
70400
+ var button = child(div_8);
70165
70401
  var button_1 = sibling(button, 2);
70402
+ reset(div_8);
70403
+ reset(div_7);
70404
+ next(4);
70166
70405
  reset(div_6);
70167
70406
  reset(div_5);
70168
- next(4);
70169
- reset(div_4);
70170
- reset(div_3);
70171
- delegated("click", div_3, () => set(showHelp, false));
70172
- delegated("keydown", div_3, (e) => {
70407
+ delegated("click", div_5, () => set(showHelp, false));
70408
+ delegated("keydown", div_5, (e) => {
70173
70409
  if (e.key === "Escape") set(showHelp, false);
70174
70410
  });
70175
- delegated("click", div_4, (e) => e.stopPropagation());
70176
- delegated("keydown", div_4, (e) => e.stopPropagation());
70411
+ delegated("click", div_6, (e) => e.stopPropagation());
70412
+ delegated("keydown", div_6, (e) => e.stopPropagation());
70177
70413
  delegated("click", button, () => {
70178
70414
  const text = [
70179
70415
  "KEYBOARD SHORTCUTS — Open3D Floorplan",
@@ -70224,13 +70460,13 @@ function App($$anchor, $$props) {
70224
70460
  navigator.clipboard.writeText(text);
70225
70461
  });
70226
70462
  delegated("click", button_1, () => set(showHelp, false));
70227
- append($$anchor, div_3);
70463
+ append($$anchor, div_5);
70228
70464
  };
70229
- if_block(node_8, ($$render) => {
70465
+ if_block(node_9, ($$render) => {
70230
70466
  if (get(showHelp)) $$render(consequent_6);
70231
70467
  });
70232
- var node_9 = sibling(node_8, 2);
70233
- CommandPalette(node_9, {
70468
+ var node_10 = sibling(node_9, 2);
70469
+ CommandPalette(node_10, {
70234
70470
  get open() {
70235
70471
  return get(commandPaletteOpen);
70236
70472
  },
@@ -70238,8 +70474,8 @@ function App($$anchor, $$props) {
70238
70474
  set(commandPaletteOpen, $$value, true);
70239
70475
  }
70240
70476
  });
70241
- var node_10 = sibling(node_9, 2);
70242
- PrintLayout(node_10, {
70477
+ var node_11 = sibling(node_10, 2);
70478
+ PrintLayout(node_11, {
70243
70479
  get open() {
70244
70480
  return get(printOpen);
70245
70481
  },
@@ -70247,7 +70483,7 @@ function App($$anchor, $$props) {
70247
70483
  set(printOpen, $$value, true);
70248
70484
  }
70249
70485
  });
70250
- OnboardingTooltip(sibling(node_10, 2), {});
70486
+ OnboardingTooltip(sibling(node_11, 2), {});
70251
70487
  append($$anchor, fragment);
70252
70488
  pop();
70253
70489
  }