function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * PisellFloorMapLayout - 空间布局视图
 * 支持两种用法：1) 仅传入 items + renderItem（原有用法）；2) 传入 floorMapConfig + dataSources + mode 使用平面图视图（含多画布/编辑态）
 */
import React, { useMemo, useRef, useImperativeHandle, useCallback, useState, useEffect } from 'react';
import classNames from 'classnames';
import { theme } from 'antd';
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
import MapLayer from "./components/MapLayer";
import ItemLayer from "./components/ItemLayer";
import { EditableItemLayer } from "./components/EditableItemLayer";
import { FloorMapToolbar } from "./components/FloorMapToolbar";
import { FloorMapEditTopBar } from "./components/FloorMapEditTopBar";
import { CanvasTabs } from "./components/CanvasTabs";
import { FloorMapEditPanel } from "./components/FloorMapEditPanel";
import { ViewControlsWithZoom } from "./components/ViewControlsWithZoom";
import { useFloorMapEditState } from "./hooks/useFloorMapEditState";
import { useFloorMapTransformMetrics } from "./hooks/useFloorMapTransformMetrics";
import { DEFAULT_CELL_SIZE, gapToPx } from "./utils/layoutMeasurements";
import { renderFloorMapFallbackPlaceholder, renderFloorMapRenderError } from "./utils/floorMapFallbackRender";
import { getElementKindConfig, getSceneElementRenderIssue } from "./utils/floorMapElementKindUtils";
import { isFloorMapPaletteDrag, parsePaletteDragPayload, sceneXYFromContentDropOffset } from "./utils/floorMapDropUtils";
import { useFloorMapPaletteTouchDrag } from "./hooks/useFloorMapPaletteTouchDrag";
import { mergeCanvasesForTabs } from "./utils/mergeCanvasesForTabs";
import { useFloorMapLayoutContext } from "./context/FloorMapLayoutContext";
import { mergeFloorMapLayoutPropsFromContext } from "./context/mergeFloorMapLayoutContext";
import useEngineContext from "../../hooks/useEngineContext";
import { locales } from '@pisell/utils';
import { initFloorMapLayoutLocales } from "./utils/floorMapCanvasDisplay";
import "./PisellFloorMapLayout.less";
var PREFIX = 'pisell-floor-map-layout';
function PisellFloorMapLayoutInner(props, ref) {
  var _engineCtx$engine, _config$sceneElements;
  var layoutCtx = useFloorMapLayoutContext();
  var p = mergeFloorMapLayoutPropsFromContext(props, layoutCtx);
  var className = p.className,
    style = p.style,
    itemsProp = p.items,
    renderItem = p.renderItem,
    rowKey = p.rowKey,
    renderItemByKind = p.renderItemByKind,
    getMergedItemWrapperStyle = p.getMergedItemWrapperStyle,
    mapLayer = p.mapLayer,
    cellSizeProp = p.cellSize,
    _p$itemUnit = p.itemUnit,
    itemUnit = _p$itemUnit === void 0 ? 'cell' : _p$itemUnit,
    _p$zoom = p.zoom,
    zoom = _p$zoom === void 0 ? {} : _p$zoom,
    _p$pan = p.pan,
    pan = _p$pan === void 0 ? {} : _p$pan,
    _p$controls = p.controls,
    controls = _p$controls === void 0 ? {} : _p$controls,
    _p$enableHover = p.enableHover,
    enableHover = _p$enableHover === void 0 ? true : _p$enableHover,
    onItemClick = p.onItemClick,
    onItemHover = p.onItemHover,
    onItemLeave = p.onItemLeave,
    _p$mode = p.mode,
    mode = _p$mode === void 0 ? 'read' : _p$mode,
    floorMapConfigProp = p.floorMapConfig,
    dataSources = p.dataSources,
    onSave = p.onSave,
    onDataSourceRecordSave = p.onDataSourceRecordSave,
    dataSourceLabels = p.dataSourceLabels,
    dataSourceFormColumns = p.dataSourceFormColumns,
    dataSourceRecordForm = p.dataSourceRecordForm,
    loading = p.loading,
    saveError = p.saveError,
    onElementRenderError = p.onElementRenderError,
    _p$toolbarShowSave = p.toolbarShowSave,
    toolbarShowSave = _p$toolbarShowSave === void 0 ? true : _p$toolbarShowSave,
    floorMapFullscreenMode = p.floorMapFullscreenMode,
    showDataSourceRecordFormBlock = p.showDataSourceRecordFormBlock,
    floorMapViewportOverlay = p.floorMapViewportOverlay,
    canvasTabsBarTrailing = p.canvasTabsBarTrailing,
    viewportDockTrailing = p.viewportDockTrailing;
  var _theme$useToken = theme.useToken(),
    token = _theme$useToken.token;
  var isFloorMapView = Boolean(floorMapConfigProp);
  var contentOffsetRef = useRef({
    x: 0,
    y: 0
  });
  var mapDropLayerRef = useRef(null);
  var transformRef = useRef(null);
  var edit = useFloorMapEditState({
    floorMapConfigProp: floorMapConfigProp,
    isFloorMapView: isFloorMapView,
    itemsProp: itemsProp,
    cellSizeProp: cellSizeProp,
    dataSources: dataSources,
    onSave: onSave,
    onDataSourceRecordSave: onDataSourceRecordSave,
    dataSourceFormColumns: dataSourceFormColumns,
    dataSourceRecordForm: dataSourceRecordForm,
    dataSourceLabels: dataSourceLabels,
    layoutPrefix: PREFIX,
    contentOffsetRef: contentOffsetRef,
    showDataSourceRecordFormBlock: showDataSourceRecordFormBlock
  });
  var config = edit.config,
    currentCanvasId = edit.currentCanvasId,
    setCurrentCanvasId = edit.setCurrentCanvasId,
    selectedId = edit.selectedId,
    setSelectedId = edit.setSelectedId,
    placeMode = edit.placeMode,
    setPlaceMode = edit.setPlaceMode,
    items = edit.items,
    saving = edit.saving,
    savingRecord = edit.savingRecord,
    handleAddCanvas = edit.handleAddCanvas,
    handleRemoveCanvas = edit.handleRemoveCanvas,
    handleRenameCanvas = edit.handleRenameCanvas,
    handleUpdateItem = edit.handleUpdateItem,
    handleCanvasPlaceClick = edit.handleCanvasPlaceClick,
    handleSave = edit.handleSave,
    placeSceneElementFromPaletteDrop = edit.placeSceneElementFromPaletteDrop,
    editPanelParams = edit.editPanelParams,
    placeOverlayClass = edit.placeOverlayClass,
    isLayoutDirty = edit.isLayoutDirty,
    toggleDraftCanvasShowGrid = edit.toggleDraftCanvasShowGrid,
    toggleSelectedLayoutLock = edit.toggleSelectedLayoutLock,
    duplicateSelectedElement = edit.duplicateSelectedElement,
    deleteSelectedElement = edit.deleteSelectedElement;
  var effectiveMapLayer = useMemo(function () {
    var _canvas$mapLayer;
    if (!isFloorMapView || !config || !currentCanvasId) {
      return mapLayer;
    }
    var canvas = config.canvases.find(function (c) {
      return c.id === currentCanvasId;
    });
    return _objectSpread(_objectSpread({}, mapLayer !== null && mapLayer !== void 0 ? mapLayer : {}), (_canvas$mapLayer = canvas === null || canvas === void 0 ? void 0 : canvas.mapLayer) !== null && _canvas$mapLayer !== void 0 ? _canvas$mapLayer : {});
  }, [isFloorMapView, config, currentCanvasId, mapLayer]);

  /**
   * 必须与下方 TransformWrapper 的 `key` 完全一致。
   * 远程/合并配置落地后 boundingPadding 等会变 → Wrapper 重挂载 → 若 autoFit 仍按旧「仅 canvasId」帧认为已 done，首屏会停在初始 transform；切换画布才因 id 变化再次 fit。
   */
  var transformWrapperKey = useMemo(function () {
    var _effectiveMapLayer$bo, _zoom$defaultScale;
    if (!isFloorMapView) return 'fmap-layout';
    var bp = (_effectiveMapLayer$bo = effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.boundingPadding) !== null && _effectiveMapLayer$bo !== void 0 ? _effectiveMapLayer$bo : 'd';
    var z = (_zoom$defaultScale = zoom.defaultScale) !== null && _zoom$defaultScale !== void 0 ? _zoom$defaultScale : 1;
    return "fmap-".concat(currentCanvasId !== null && currentCanvasId !== void 0 ? currentCanvasId : 'na', "-bp").concat(bp, "-z").concat(z);
  }, [isFloorMapView, currentCanvasId, effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.boundingPadding, zoom.defaultScale]);
  var canvasesForTabs = useMemo(function () {
    return config ? mergeCanvasesForTabs(config) : [];
  }, [config]);
  var engineCtx = useEngineContext();
  var engineLocale = (engineCtx === null || engineCtx === void 0 || (_engineCtx$engine = engineCtx.engine) === null || _engineCtx$engine === void 0 || (_engineCtx$engine = _engineCtx$engine.props) === null || _engineCtx$engine === void 0 ? void 0 : _engineCtx$engine.locale) || 'zh-CN';
  var hasCanvasTabsBarTrailing = canvasTabsBarTrailing != null && canvasTabsBarTrailing !== false;
  var enabledCanvasCount = useMemo(function () {
    return canvasesForTabs.filter(function (c) {
      return c.enabled;
    }).length;
  }, [canvasesForTabs]);
  var showReadModeCanvasTabsBar = useMemo(function () {
    if (!isFloorMapView || mode !== 'read' || !config) return false;
    if (hasCanvasTabsBarTrailing) return true;
    return enabledCanvasCount > 1;
  }, [isFloorMapView, mode, config, hasCanvasTabsBarTrailing, enabledCanvasCount]);
  var readCanvasTabsAriaLabel = useMemo(function () {
    initFloorMapLayoutLocales(engineLocale);
    return locales.getText('pisell-floor-map-layout.read-canvas-tabs.aria');
  }, [engineLocale]);

  /** 编辑态始终保留顶栏 Tab（单画布也要能「添加画布」）；仅阅读态在单画布时可隐藏 Tab 行 */
  var showEditCompactTopBar = isFloorMapView && mode === 'edit' && Boolean(config) && !useFullTopChrome;
  var loadingLabel = useMemo(function () {
    initFloorMapLayoutLocales(engineLocale);
    return locales.getText('pisell-floor-map-layout.loading');
  }, [engineLocale]);

  /** 选中图元旁：锁定（与侧栏同字段）/ 复制 / 删除；锁定时不展开右侧属性面板 */
  var editQuickBar = useMemo(function () {
    if (!isFloorMapView || mode !== 'edit' || !(config !== null && config !== void 0 && config.canvasUi.canEdit) || !selectedId) {
      return null;
    }
    initFloorMapLayoutLocales(engineLocale);
    var row = items.find(function (i) {
      return i.id === selectedId;
    });
    if (!(row !== null && row !== void 0 && row._sceneElement)) return null;
    return {
      labels: {
        lock: locales.getText('pisell-floor-map-layout.edit-quick.lock'),
        unlock: locales.getText('pisell-floor-map-layout.edit-quick.unlock'),
        duplicate: locales.getText('pisell-floor-map-layout.edit-quick.duplicate'),
        delete: locales.getText('pisell-floor-map-layout.edit-quick.delete'),
        popTitle: locales.getText('pisell-floor-map-layout.edit-panel.pop-title'),
        popDesc: locales.getText('pisell-floor-map-layout.edit-panel.pop-desc'),
        cancel: locales.getText('pisell-floor-map-layout.edit-panel.btn-cancel'),
        okDelete: locales.getText('pisell-floor-map-layout.edit-panel.btn-ok-delete'),
        ariaToolbar: locales.getText('pisell-floor-map-layout.edit-quick.aria-toolbar')
      },
      isLocked: Boolean(row._sceneElement.layoutTransformLocked),
      onToggleLock: toggleSelectedLayoutLock,
      onDuplicate: duplicateSelectedElement,
      onDelete: deleteSelectedElement
    };
  }, [isFloorMapView, mode, config === null || config === void 0 ? void 0 : config.canvasUi.canEdit, selectedId, items, engineLocale, toggleSelectedLayoutLock, duplicateSelectedElement, deleteSelectedElement]);
  var cellSize = cellSizeProp !== null && cellSizeProp !== void 0 ? cellSizeProp : DEFAULT_CELL_SIZE;
  var itemGap = useMemo(function () {
    return gapToPx(effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.gap);
  }, [effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.gap]);
  var effectiveItemUnit = isFloorMapView ? 'pixel' : itemUnit;
  var metrics = useFloorMapTransformMetrics({
    items: items,
    cellSize: cellSize,
    itemGap: itemGap,
    effectiveItemUnit: effectiveItemUnit,
    isFloorMapView: isFloorMapView,
    mode: mode,
    zoom: zoom,
    transformRef: transformRef,
    contentOffsetRef: contentOffsetRef,
    boundingPadding: effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.boundingPadding,
    frameResetKey: isFloorMapView ? transformWrapperKey : undefined
  });
  var containerRef = metrics.containerRef,
    mapAreaRef = metrics.mapAreaRef,
    mapAreaSize = metrics.mapAreaSize,
    contentWidth = metrics.contentWidth,
    contentHeight = metrics.contentHeight,
    contentOffsetX = metrics.contentOffsetX,
    contentOffsetY = metrics.contentOffsetY,
    initialPositionX = metrics.initialPositionX,
    initialPositionY = metrics.initialPositionY,
    zoomConfig = metrics.zoomConfig,
    scale = metrics.scale,
    setScale = metrics.setScale,
    isFullscreen = metrics.isFullscreen,
    toggleFullscreen = metrics.toggleFullscreen,
    fitBounds = metrics.fitBounds,
    lastTransformRef = metrics.lastTransformRef,
    isInteractingWithElement = metrics.isInteractingWithElement,
    setIsInteractingWithElement = metrics.setIsInteractingWithElement;

  /** 编辑态全屏策略：toggle 可切换；locked 始终全屏顶栏且不可在组件内退出；disabled 无全屏按钮 */
  var fsMode = floorMapFullscreenMode !== null && floorMapFullscreenMode !== void 0 ? floorMapFullscreenMode : 'toggle';
  var useFullTopChrome = isFloorMapView && mode === 'edit' && (fsMode === 'locked' || fsMode === 'toggle' && isFullscreen);
  /** toggle 时左下 Dock 展示全屏；locked/disabled 不传 API */
  var dockToggleFullscreen = isFloorMapView && fsMode === 'toggle' ? toggleFullscreen : undefined;
  var viewControlsConfig = useMemo(function () {
    var _controls$showFullscr;
    if (!isFloorMapView) return controls;
    return _objectSpread(_objectSpread({}, controls), {}, {
      showFullscreen: (_controls$showFullscr = controls.showFullscreen) !== null && _controls$showFullscr !== void 0 ? _controls$showFullscr : Boolean(dockToggleFullscreen)
    });
  }, [isFloorMapView, controls, dockToggleFullscreen]);
  var topBarExtraActions = null;
  var _useState = useState(false),
    _useState2 = _slicedToArray(_useState, 2),
    mapPaletteDragActive = _useState2[0],
    setMapPaletteDragActive = _useState2[1];
  useEffect(function () {
    var clear = function clear() {
      return setMapPaletteDragActive(false);
    };
    window.addEventListener('dragend', clear);
    return function () {
      return window.removeEventListener('dragend', clear);
    };
  }, []);
  var handlePaletteDropOnCanvas = useCallback(function (e) {
    e.preventDefault();
    e.stopPropagation();
    setMapPaletteDragActive(false);
    if (!isFloorMapView || mode !== 'edit') return;
    var payload = parsePaletteDragPayload(e.dataTransfer);
    if (!payload) return;
    var _sceneXYFromContentDr = sceneXYFromContentDropOffset(e.nativeEvent.offsetX, e.nativeEvent.offsetY, contentOffsetRef.current),
      cx = _sceneXYFromContentDr.x,
      cy = _sceneXYFromContentDr.y;
    placeSceneElementFromPaletteDrop(cx, cy, {
      type: 'scene',
      elementKind: payload.elementKind,
      dataSourceKey: payload.dataSourceKey,
      recordId: payload.recordId,
      recordIds: payload.recordIds
    });
  }, [isFloorMapView, mode, placeSceneElementFromPaletteDrop]);
  var applyPaletteTouchDropInScene = useCallback(function (payload, cx, cy) {
    if (!isFloorMapView || mode !== 'edit') return;
    placeSceneElementFromPaletteDrop(cx, cy, {
      type: 'scene',
      elementKind: payload.elementKind,
      dataSourceKey: payload.dataSourceKey,
      recordId: payload.recordId,
      recordIds: payload.recordIds
    });
  }, [isFloorMapView, mode, placeSceneElementFromPaletteDrop]);
  var paletteTouchDrag = useFloorMapPaletteTouchDrag({
    enabled: Boolean(isFloorMapView && mode === 'edit' && (config === null || config === void 0 ? void 0 : config.canvasUi.canCreate)),
    mapDropLayerRef: mapDropLayerRef,
    contentWidth: contentWidth,
    contentHeight: contentHeight,
    contentOffsetRef: contentOffsetRef,
    setMapPaletteDragActive: setMapPaletteDragActive,
    onDropInScene: applyPaletteTouchDropInScene
  });
  var fallbackPlaceholderRender = useCallback(function (item) {
    return renderFloorMapFallbackPlaceholder(item);
  }, []);
  var effectiveRenderItem = useCallback(function (item, index, options) {
    var merged = item;
    var kind = merged === null || merged === void 0 ? void 0 : merged.elementKind;
    if (isFloorMapView && floorMapConfigProp && merged._sceneElement) {
      var kc = getElementKindConfig(floorMapConfigProp, kind);
      var issue = getSceneElementRenderIssue(merged._sceneElement, kc, dataSources);
      if (issue) {
        return renderFloorMapRenderError(issue);
      }
    }
    if (isFloorMapView && kind && renderItemByKind !== null && renderItemByKind !== void 0 && renderItemByKind[kind]) {
      try {
        return renderItemByKind[kind](item, index, options);
      } catch (err) {
        if (merged._sceneElement) {
          onElementRenderError === null || onElementRenderError === void 0 || onElementRenderError(merged._sceneElement, err);
        }
        return renderFloorMapRenderError(err instanceof Error ? err.message : String(err));
      }
    }
    if (isFloorMapView && kind) {
      return fallbackPlaceholderRender(merged);
    }
    return renderItem(item, index, options);
  }, [isFloorMapView, floorMapConfigProp, dataSources, renderItemByKind, renderItem, fallbackPlaceholderRender, onElementRenderError]);
  var handleItemClick = useCallback(function (item, index, e) {
    if (isFloorMapView && mode === 'edit') setSelectedId(item.id);
    onItemClick === null || onItemClick === void 0 || onItemClick(item, index, e);
  }, [isFloorMapView, mode, onItemClick, setSelectedId]);
  useImperativeHandle(ref, function () {
    return {
      zoomIn: function zoomIn() {
        var _transformRef$current;
        return (_transformRef$current = transformRef.current) === null || _transformRef$current === void 0 ? void 0 : _transformRef$current.zoomIn();
      },
      zoomOut: function zoomOut() {
        var _transformRef$current2;
        return (_transformRef$current2 = transformRef.current) === null || _transformRef$current2 === void 0 ? void 0 : _transformRef$current2.zoomOut();
      },
      reset: function reset() {
        var _transformRef$current3;
        return (_transformRef$current3 = transformRef.current) === null || _transformRef$current3 === void 0 ? void 0 : _transformRef$current3.resetTransform();
      },
      fitBounds: fitBounds,
      saveLayout: function saveLayout() {
        return handleSave();
      }
    };
  }, [fitBounds, handleSave]);
  var showSidebar = isFloorMapView && mode === 'edit' && config && dataSources;

  /** 右侧属性面板打开时给画布区留空，避免落点被挡在面板下 */
  var editPanelVisible = isFloorMapView && mode === 'edit' && Boolean(editPanelParams) && Boolean(config) && Boolean(dataSources);

  /**
   * 在 map-area 上统一处理「点空白取消选中」：空白点击常落在 Transform 的 wrapper/content 上，
   * 不会冒泡到 EditableItemLayer 根节点；图元内点击由 EditableItemLayer stopPropagation，避免误清。
   */
  var handleMapAreaBackgroundClick = useCallback(function (e) {
    if (!isFloorMapView || mode !== 'edit') return;
    var t = e.target;
    if (t.closest(".".concat(PREFIX, "-editable-item"))) return;
    if (t.closest(".".concat(PREFIX, "-edit-panel-wrap"))) return;
    if (t.closest(".".concat(PREFIX, "-view-controls"))) return;
    if (t.closest(".".concat(PREFIX, "-viewport-overlay"))) return;
    if (t.closest(".".concat(PREFIX, "-place-overlay"))) return;
    if (t.closest(".".concat(PREFIX, "-map-drop-layer"))) return;
    setSelectedId(null);
  }, [isFloorMapView, mode, setSelectedId]);
  return /*#__PURE__*/React.createElement("div", {
    ref: containerRef,
    className: classNames(PREFIX, className, _defineProperty(_defineProperty({}, "".concat(PREFIX, "-floor-map-view"), isFloorMapView), "".concat(PREFIX, "-mode-edit"), isFloorMapView && mode === 'edit')),
    style: _objectSpread(_objectSpread(_objectSpread({
      display: 'flex',
      flexDirection: 'column'
    }, isFloorMapView ? {
      minHeight: 0
    } : {}), isFloorMapView ? _defineProperty({}, '--fmap-primary', token.colorPrimary) : {}), style)
  }, showEditCompactTopBar && !useFullTopChrome && /*#__PURE__*/React.createElement(FloorMapEditTopBar, {
    mode: "compact",
    config: config,
    canvases: canvasesForTabs,
    currentCanvasId: currentCanvasId,
    onTabChange: function onTabChange(id) {
      setCurrentCanvasId(id);
      setSelectedId(null);
    },
    canEditTabs: config.canvasUi.canEdit,
    onAddCanvas: handleAddCanvas,
    onRemoveCanvas: handleRemoveCanvas,
    onRenameCanvas: handleRenameCanvas,
    controls: controls,
    canvasTabsBarTrailing: canvasTabsBarTrailing
  }), isFloorMapView && mode === 'edit' && config && useFullTopChrome && /*#__PURE__*/React.createElement(FloorMapEditTopBar, {
    mode: "full",
    config: config,
    canvases: canvasesForTabs,
    currentCanvasId: currentCanvasId,
    onTabChange: function onTabChange(id) {
      setCurrentCanvasId(id);
      setSelectedId(null);
    },
    canEditTabs: config.canvasUi.canEdit,
    onAddCanvas: handleAddCanvas,
    onRemoveCanvas: handleRemoveCanvas,
    onRenameCanvas: handleRenameCanvas,
    onSave: onSave ? handleSave : undefined,
    saving: saving,
    saveError: saveError,
    layoutDirty: isLayoutDirty,
    isFullscreen: isFullscreen,
    controls: controls,
    extraActions: topBarExtraActions,
    canvasTabsBarTrailing: canvasTabsBarTrailing
  }), showReadModeCanvasTabsBar && /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-edit-top-bar ").concat(PREFIX, "-read-canvas-tabs-bar"),
    role: "toolbar",
    "aria-label": readCanvasTabsAriaLabel
  }, /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-edit-top-bar-tabs")
  }, /*#__PURE__*/React.createElement(CanvasTabs, {
    canvases: canvasesForTabs,
    currentCanvasId: currentCanvasId,
    onTabChange: function onTabChange(id) {
      setCurrentCanvasId(id);
      setSelectedId(null);
    },
    canEdit: false,
    className: "".concat(PREFIX, "-edit-top-bar-canvas-tabs")
  })), hasCanvasTabsBarTrailing ? /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-edit-top-bar-actions")
  }, canvasTabsBarTrailing) : null), loading && /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-loading")
  }, /*#__PURE__*/React.createElement("span", null, loadingLabel)), saveError && !(isFloorMapView && mode === 'edit' && config) && /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-save-error")
  }, typeof saveError === 'string' ? saveError : saveError === null || saveError === void 0 ? void 0 : saveError.message), /*#__PURE__*/React.createElement("div", {
    className: showSidebar ? "".concat(PREFIX, "-edit-layout") : undefined,
    style: {
      flex: 1,
      display: 'flex',
      minHeight: 0
    }
  }, showSidebar && /*#__PURE__*/React.createElement(FloorMapToolbar, {
    config: config,
    dataSources: dataSources,
    dataSourceLabels: dataSourceLabels,
    canCreate: config.canvasUi.canCreate,
    placeMode: placeMode,
    onPlaceModeChange: setPlaceMode,
    sceneElements: (_config$sceneElements = config.sceneElements) !== null && _config$sceneElements !== void 0 ? _config$sceneElements : [],
    renderPreviewItem: function renderPreviewItem(item) {
      return effectiveRenderItem(item, 0);
    },
    placementPreviewSize: {
      width: 180,
      height: 120
    },
    decorationPreviewSize: 48,
    onSave: onSave && config.canvasUi.canEdit && !useFullTopChrome && toolbarShowSave !== false ? handleSave : undefined,
    saving: saving,
    saveError: saveError,
    layoutDirty: isLayoutDirty,
    onPaletteCardPointerDown: paletteTouchDrag.handlePaletteCardPointerDown,
    consumeToolbarClickIfTouchDrag: paletteTouchDrag.consumeToolbarClickIfTouchDrag
  }), /*#__PURE__*/React.createElement("div", {
    ref: mapAreaRef,
    className: classNames(showSidebar && "".concat(PREFIX, "-map-area"), editPanelVisible && "".concat(PREFIX, "-map-area--edit-panel-inset")),
    style: {
      flex: 1,
      position: 'relative',
      minWidth: 0,
      overflow: 'hidden'
    },
    onClick: handleMapAreaBackgroundClick,
    onDragEnter: function onDragEnter(e) {
      if (!isFloorMapView || mode !== 'edit') return;
      if (!isFloorMapPaletteDrag(e.dataTransfer)) return;
      e.preventDefault();
      e.stopPropagation();
      setMapPaletteDragActive(true);
    },
    onDragOver: function onDragOver(e) {
      if (!isFloorMapView || mode !== 'edit' || !mapPaletteDragActive) return;
      e.preventDefault();
      e.stopPropagation();
    },
    onDragLeave: function onDragLeave(e) {
      var _mapAreaRef$current;
      if (!mapPaletteDragActive) return;
      var related = e.relatedTarget;
      if (!((_mapAreaRef$current = mapAreaRef.current) !== null && _mapAreaRef$current !== void 0 && _mapAreaRef$current.contains(related))) {
        setMapPaletteDragActive(false);
      }
    }
  }, /*#__PURE__*/React.createElement(TransformWrapper, {
    key: transformWrapperKey,
    centerOnInit: false,
    initialScale: zoomConfig.initialScale,
    initialPositionX: initialPositionX,
    initialPositionY: initialPositionY,
    minScale: zoomConfig.minScale,
    maxScale: zoomConfig.maxScale
    /**
     * 库默认 limitToBounds=true，平移会被限制在内容包盒内。
     * pan.boundary === 'none' 时关闭限制，可一直拖动画布（视觉上类似无限大底图）。
     * 'clamp' / 'bounce' / 未传：保持限制（与历史行为一致）。
     */,
    limitToBounds: pan.boundary !== 'none'
    // v3 类型定义未包含 step，库仍支持缩放步进时使用
    ,
    step: zoomConfig.step,
    panning: {
      disabled: pan.enabled === false || isInteractingWithElement,
      velocityDisabled: true
    },
    doubleClick: {
      disabled: true
    },
    onTransformed: function onTransformed(_, state) {
      setScale(state.scale);
      lastTransformRef.current = {
        x: state.positionX,
        y: state.positionY,
        scale: state.scale
      };
    }
  }, function (ctx) {
    var _effectiveMapLayer$sn;
    transformRef.current = ctx;
    return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TransformComponent, {
      wrapperStyle: {
        width: '100%',
        height: '100%',
        backgroundColor: '#F2F4F7',
        overflow: 'visible'
      },
      contentStyle: {
        width: contentWidth,
        height: contentHeight,
        minWidth: contentWidth,
        minHeight: contentHeight,
        position: 'relative',
        overflow: 'visible',
        backgroundColor: '#F2F4F7'
      }
    }, /*#__PURE__*/React.createElement(MapLayer, {
      config: effectiveMapLayer,
      contentWidth: contentWidth,
      contentHeight: contentHeight,
      cellSize: cellSize,
      preferCanvasGrid: true,
      pointerEventsNone: isFloorMapView && mode === 'edit'
    }), isFloorMapView && mode === 'edit' ? /*#__PURE__*/React.createElement(EditableItemLayer, {
      items: items,
      renderItem: effectiveRenderItem,
      rowKey: rowKey,
      cellSize: cellSize,
      itemUnit: effectiveItemUnit,
      itemGap: itemGap,
      contentWidth: contentWidth,
      contentHeight: contentHeight,
      contentOffsetX: contentOffsetX,
      contentOffsetY: contentOffsetY,
      selectedId: selectedId,
      onSelect: setSelectedId,
      onUpdateItem: handleUpdateItem,
      snapStep: (_effectiveMapLayer$sn = effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.snapStep) !== null && _effectiveMapLayer$sn !== void 0 ? _effectiveMapLayer$sn : 0,
      scale: scale,
      onInteractionChange: setIsInteractingWithElement,
      getMergedItemWrapperStyle: getMergedItemWrapperStyle,
      editQuickBar: editQuickBar
    }) : /*#__PURE__*/React.createElement(ItemLayer, {
      items: items,
      renderItem: effectiveRenderItem,
      rowKey: rowKey,
      cellSize: cellSize,
      itemUnit: effectiveItemUnit,
      itemGap: itemGap,
      contentWidth: contentWidth,
      contentHeight: contentHeight,
      contentOffsetX: contentOffsetX,
      contentOffsetY: contentOffsetY,
      enableHover: enableHover,
      itemHoverOutline: true,
      onItemClick: handleItemClick,
      onItemHover: onItemHover,
      onItemLeave: onItemLeave,
      getMergedItemWrapperStyle: getMergedItemWrapperStyle,
      onInteractionChange: setIsInteractingWithElement
    }), isFloorMapView && mode === 'edit' && (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' && /*#__PURE__*/React.createElement("div", {
      className: placeOverlayClass,
      style: {
        width: contentWidth,
        height: contentHeight
      },
      onClick: handleCanvasPlaceClick
    }), isFloorMapView && mode === 'edit' && /*#__PURE__*/React.createElement("div", {
      ref: mapDropLayerRef,
      className: classNames("".concat(PREFIX, "-map-drop-layer"), _defineProperty({}, "".concat(PREFIX, "-map-drop-layer-active"), mapPaletteDragActive)),
      style: {
        width: contentWidth,
        height: contentHeight
      },
      onDragOver: function onDragOver(ev) {
        ev.preventDefault();
        ev.stopPropagation();
      },
      onDrop: handlePaletteDropOnCanvas
    })), /*#__PURE__*/React.createElement(ViewControlsWithZoom, {
      config: viewControlsConfig,
      scale: scale,
      isFullscreen: isFullscreen,
      fitBounds: fitBounds,
      toggleFullscreen: dockToggleFullscreen,
      mapGridVisible: Boolean(effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.showGrid),
      onToggleMapGrid: isFloorMapView ? toggleDraftCanvasShowGrid : undefined,
      dockChrome: isFloorMapView,
      dockExpandedTrailing: viewportDockTrailing,
      autoCollapseDockMs: 10000
    }), isFloorMapView && floorMapViewportOverlay != null ? /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-viewport-overlay")
    }, typeof floorMapViewportOverlay === 'function' ? floorMapViewportOverlay({
      items: items,
      dataSources: dataSources,
      currentCanvasId: currentCanvasId,
      mode: mode
    }) : floorMapViewportOverlay) : null, isFloorMapView && mode === 'edit' && editPanelParams && config && dataSources && /*#__PURE__*/React.createElement("div", {
      className: classNames("".concat(PREFIX, "-edit-panel-wrap"), mapAreaSize.height > 0 && "".concat(PREFIX, "-edit-panel-wrap-constrained")),
      style: mapAreaSize.height > 0 ? {
        height: mapAreaSize.height - 32,
        maxHeight: mapAreaSize.height - 32,
        overflow: 'hidden',
        top: 16,
        transform: 'none'
      } : undefined
    }, /*#__PURE__*/React.createElement(FloorMapEditPanel, _extends({}, editPanelParams, {
      config: config,
      dataSources: dataSources,
      savingRecord: savingRecord
    }))));
  }))));
}
var PisellFloorMapLayout = /*#__PURE__*/React.forwardRef(PisellFloorMapLayoutInner);
export { PisellFloorMapLayout };
export default PisellFloorMapLayout;